feat: add is_anagram to dsa

This commit is contained in:
rzmk 2024-03-05 15:55:21 -05:00
parent 1f32820941
commit b46a066dfc
No known key found for this signature in database
4 changed files with 127 additions and 4 deletions

View file

@ -6,7 +6,7 @@ The `ladderz` project is a collection of math and tech concepts implemented in c
- **[`lz` CLI](https://rzmk.github.io/ladderz/lz/index.html)** - A command line tool for running ladderz functions - **[`lz` CLI](https://rzmk.github.io/ladderz/lz/index.html)** - A command line tool for running ladderz functions
- **[notebooks](notebooks)** - Rust & Python Jupyter notebooks with concept exercises and solutions - **[notebooks](notebooks)** - Rust & Python Jupyter notebooks with concept exercises and solutions
> If you're looking for a more efficient implementation of a concept (e.g., for use in your programs), other resources may be more useful. > Note: If you're looking for a more efficient implementation of a concept (e.g., for use in your programs), other resources may be more useful.
## Demos ## Demos

View file

@ -1,4 +1,4 @@
use std::collections::HashSet; use std::collections::{HashMap, HashSet};
pub fn contains_duplicate(nums: Vec<i32>) -> bool { pub fn contains_duplicate(nums: Vec<i32>) -> bool {
let mut seen = HashSet::<i32>::new(); let mut seen = HashSet::<i32>::new();
@ -11,6 +11,49 @@ pub fn contains_duplicate(nums: Vec<i32>) -> bool {
false false
} }
pub fn is_anagram(a: String, b: String) -> bool {
let mut letters = HashMap::new();
for c in a.chars() {
if let Some(&value) = letters.get(&c) {
letters.insert(c, value + 1);
} else {
letters.insert(c, 1);
}
}
for c in b.chars() {
if let Some(&value) = letters.get(&c) {
if value - 1 < 0 {
return false;
}
letters.insert(c, value - 1);
} else {
return false;
}
}
for (_, &count) in letters.iter() {
if count > 0 {
return false;
}
}
true
}
pub fn is_anagram2(a: String, b: String) -> bool {
if a.len() != b.len() {
return false;
}
let mut letters = HashMap::new();
for c in a.chars() {
*letters.entry(c).or_default() += 1;
}
for c in b.chars() {
*letters.entry(c).or_default() -= 1;
}
letters.into_values().all(|c: i32| c == 0)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -21,4 +64,11 @@ mod tests {
let expected = true; let expected = true;
assert_eq!(result, expected); assert_eq!(result, expected);
} }
#[test]
fn test_is_anagram() {
let result = is_anagram("marc".to_owned(), "cram".to_owned());
let expected = true;
assert_eq!(result, expected);
}
} }

View file

@ -34,6 +34,36 @@ pub enum Dsa {
#[arg(short = 'r', long)] #[arg(short = 'r', long)]
raw: bool, raw: bool,
}, },
/// Returns true or false based on whether string a is an anagram of string b.
///
/// ## Example
///
/// ### Input
///
/// ```bash
/// lz dsa is-anagram marc cram
/// ```
///
/// ### Output
///
/// ```bash
/// "marc" is an anagram of "cram".
/// ```
///
/// ## Raw Output (use `-r` or `--raw`)
///
/// ```bash
/// true
/// ```
IsAnagram {
/// The first string to compare against.
a: String,
/// The second string to compare against.
b: String,
/// Whether or not to return the raw output.
#[arg(short = 'r', long)]
raw: bool,
},
} }
pub fn match_dsa(function: Option<Dsa>) { pub fn match_dsa(function: Option<Dsa>) {
@ -50,6 +80,18 @@ pub fn match_dsa(function: Option<Dsa>) {
) )
} }
}, },
Some(Dsa::IsAnagram { a, b, raw }) => match raw {
true => println!("{:?}", is_anagram(a, b)),
false => {
let result = is_anagram(a.clone(), b.clone());
println!(
"{:?} {} an anagram of {:?}.",
a,
if result { "is" } else { "is not" },
b,
)
}
},
None => { None => {
println!("Please provide a function to use."); println!("Please provide a function to use.");
} }

View file

@ -37,7 +37,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 3,
"metadata": { "metadata": {
"vscode": { "vscode": {
"languageId": "rust" "languageId": "rust"
@ -50,7 +50,7 @@
"true" "true"
] ]
}, },
"execution_count": 6, "execution_count": 3,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -58,6 +58,37 @@
"source": [ "source": [
"dsa::contains_duplicate(vec![1, 3, 4, 2, 4])" "dsa::contains_duplicate(vec![1, 3, 4, 2, 4])"
] ]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 242. Valid Anagram"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"vscode": {
"languageId": "rust"
}
},
"outputs": [
{
"data": {
"text/plain": [
"true"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dsa::is_anagram(\"marc\".to_owned(), \"cram\".to_owned())"
]
} }
], ],
"metadata": { "metadata": {