From 0b910bf74da75ae4478c8d73b3eebf2c7484ba89 Mon Sep 17 00:00:00 2001 From: Reality Enjoyer Date: Thu, 15 Jan 2026 09:10:06 +0000 Subject: [PATCH] second exercise! - create exercise string manipulator (shout out claude) - finish hacky solution (it almost works) --- exercises/string-manipulator/Cargo.toml | 6 ++ exercises/string-manipulator/src/main.rs | 87 +++++++++++++++++++ .../string-manipulator-exercise.md | 30 +++++++ 3 files changed, 123 insertions(+) create mode 100644 exercises/string-manipulator/Cargo.toml create mode 100644 exercises/string-manipulator/src/main.rs create mode 100644 exercises/string-manipulator/string-manipulator-exercise.md diff --git a/exercises/string-manipulator/Cargo.toml b/exercises/string-manipulator/Cargo.toml new file mode 100644 index 0000000..7f5afca --- /dev/null +++ b/exercises/string-manipulator/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "string-manipulator" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/exercises/string-manipulator/src/main.rs b/exercises/string-manipulator/src/main.rs new file mode 100644 index 0000000..ca37b2d --- /dev/null +++ b/exercises/string-manipulator/src/main.rs @@ -0,0 +1,87 @@ +use std::collections::HashMap; + +fn main() { + let mut test = StringTool::new(); + + test.add_string("hello".to_string()); + test.add_string("world".to_string()); + test.add_string("rust programming".to_string()); + println!("\nDEBUG: current values\n\t{:?}", test); + + let word = "o".to_string(); + let strings_with_word = test.contains_word(&word); + println!( + "DEBUG: string(s) with {word} are:\n\t{:?}", + strings_with_word + ); + + let longest = test.longest().unwrap_or("collection is empty!"); + println!("{longest}"); + + test.to_uppercase_all(); + println!("{:?}", test); +} + +#[derive(Debug)] +struct StringTool { + collection: Vec, +} + +impl StringTool { + fn new() -> StringTool { + StringTool { + collection: Vec::new(), + } + } + + fn add_string(&mut self, s: String) { + self.collection.push(s); + } + + fn longest(&self) -> Option<&str> { + if self.collection.len() < 1 { + return None; + } else { + let mut longest_string = &self.collection[0]; + let mut length = longest_string.len(); + let mut count = 0; + + for v in &self.collection { + if v.len() > length { + longest_string = v; + length = longest_string.len(); + } + count += 1; + } + Some(longest_string.as_str()) + } + } + fn to_uppercase_all(&mut self) { + for v in &mut self.collection { + *v = v.to_uppercase(); + } + } + //TODO improve search + fn contains_word(&self, word: &str) -> Vec<&str> { + let collection = &self.collection; + let mut return_val: Vec<&str> = Vec::new(); + + //for strings in collection + for v in collection { + let words: Vec<_> = v.split_ascii_whitespace().collect(); + //for words in string + for w in words { + // for characters in word + + if w == word { + return_val.push(v); + } + } + } + return_val + } +} +// +// fn word_count(&self) -> HashMap { +// // counts total occurences of each word +// } diff --git a/exercises/string-manipulator/string-manipulator-exercise.md b/exercises/string-manipulator/string-manipulator-exercise.md new file mode 100644 index 0000000..ed510d7 --- /dev/null +++ b/exercises/string-manipulator/string-manipulator-exercise.md @@ -0,0 +1,30 @@ +# Exercise: String Manipulator Tool + +**Concepts practiced:** String vs &str, ownership/borrowing, Vec operations, pattern matching +**Objective:** Build a CLI tool that performs various string operations + +## Requirements: +- Create a `StringTool` struct that holds a collection of strings +- Implement methods: + - `new()` - creates empty tool + - `add_string(&mut self, s: String)` - adds string to collection + - `longest(&self) -> Option<&str>` - returns longest string (or None if empty) + - `contains_word(&self, word: &str) -> Vec<&str>` - returns strings containing the word + - `to_uppercase_all(&mut self)` - converts all strings to uppercase in-place + +## Success criteria: +- Code compiles without warnings +- Test with: adding "hello", "world", "rust programming" +- `longest()` should return "rust programming" +- `contains_word("o")` should return vec!["hello", "world", "rust programming"] +- After `to_uppercase_all()`, all strings should be uppercase + +## Stretch goal: +Add a method `word_count(&self) -> HashMap` that counts total occurrences of each word across all strings + +## Getting Started: +1. `cd exercises && cargo new string-manipulator` +2. Focus on ownership: when do you need `String` vs `&str`? +3. Think about borrowing: methods that read vs modify + +Expected time: 45-60 minutes \ No newline at end of file