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
- **[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

View file

@ -1,4 +1,4 @@
use std::collections::HashSet;
use std::collections::{HashMap, HashSet};
pub fn contains_duplicate(nums: Vec<i32>) -> bool {
let mut seen = HashSet::<i32>::new();
@ -11,6 +11,49 @@ pub fn contains_duplicate(nums: Vec<i32>) -> bool {
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)]
mod tests {
use super::*;
@ -21,4 +64,11 @@ mod tests {
let expected = true;
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)]
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>) {
@ -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 => {
println!("Please provide a function to use.");
}

View file

@ -37,7 +37,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 3,
"metadata": {
"vscode": {
"languageId": "rust"
@ -50,7 +50,7 @@
"true"
]
},
"execution_count": 6,
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
@ -58,6 +58,37 @@
"source": [
"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": {