diff --git a/src/assignments/assignment10/labyrinth.rs b/src/assignments/assignment10/labyrinth.rs index 5829748..c0ebcd4 100644 --- a/src/assignments/assignment10/labyrinth.rs +++ b/src/assignments/assignment10/labyrinth.rs @@ -18,7 +18,12 @@ pub struct Husband { impl Husband { /// What might a husband, who is looking for his wife's ID my_wife, be thinking? pub fn seeking(my_wife: usize) -> Self { - todo!() + let mut brain = [usize::MAX; 100]; + brain[0] = my_wife; + + Self { + brain: RefCell::new(brain), + } } #[allow(missing_docs)] @@ -29,7 +34,12 @@ impl Husband { /// Based on the information about currently visited room number and someone's wife ID trapped /// inside, what the husband should do next? pub fn carefully_checks_whos_inside(&self, room: usize, wife: usize) { - todo!() + *self + .brain + .borrow_mut() + .iter_mut() + .find(|brain| **brain == usize::MAX) + .unwrap() = wife; } } @@ -43,6 +53,12 @@ impl Iterator for Strategy<'_> { type Item = usize; fn next(&mut self) -> Option { - todo!() + self.husband + .brain + .borrow() + .iter() + .rev() + .find(|brain| **brain != usize::MAX) + .copied() } } diff --git a/src/assignments/assignment10/small_exercises.rs b/src/assignments/assignment10/small_exercises.rs index 9ce49c1..2eca4cb 100644 --- a/src/assignments/assignment10/small_exercises.rs +++ b/src/assignments/assignment10/small_exercises.rs @@ -1,6 +1,6 @@ //! Small exercises. -use std::collections::HashSet; +use std::{collections::HashSet, f64::consts::SQRT_2}; use itertools::*; @@ -17,7 +17,17 @@ use itertools::*; /// /// Consult for more details of inversion. pub fn inversion(inner: Vec) -> Vec<(usize, usize)> { - todo!() + let mut result = vec![]; + + for i in 0..inner.len() { + for j in i..inner.len() { + if inner[i] > inner[j] { + result.push((i, j)); + } + } + } + + result } /// Represents a node of tree data structure. @@ -68,7 +78,22 @@ pub enum Node { /// /// is `1 -> 2 -> 5 -> 6 -> 3 -> 4 -> 7 -> 8 -> 9`. pub fn traverse_preorder(root: Node) -> Vec { - todo!() + let mut result = vec![]; + + fn helper(result: &mut Vec, node: Node) { + match node { + Node::Leaf(v) => result.push(v), + Node::NonLeaf((v, nodes)) => { + result.push(v); + for node in nodes { + helper(result, node); + } + } + } + } + + helper(&mut result, root); + result } /// File @@ -114,7 +139,31 @@ pub enum File { /// Output: `[("a1", 1), ("a2", 3), ("b1", 3), ("a", 4), ("c", 8), ("b2", 15), ("b", 18), ("root", /// 30)]` pub fn du_sort(root: &File) -> Vec<(&str, usize)> { - todo!() + let mut result: Vec<(&str, usize)> = vec![]; + + fn helper<'a>(result: &mut Vec<(&'a str, usize)>, file: &'a File) -> usize { + match file { + File::Data(name, size) => { + result.push((name, *size)); + *size + } + File::Directory(name, files) => { + let mut total_size = 0; + for file in files { + total_size += helper(result, file); + } + result.push((name, total_size)); + total_size + } + } + } + let _ = helper(&mut result, root); + + result.sort_by(|(n1, s1), (n2, s2)| match s1.cmp(s2) { + std::cmp::Ordering::Equal => n1.cmp(n2), + r => r, + }); + result } /// Remove all even numbers inside a vector using the given mutable reference. @@ -129,7 +178,17 @@ pub fn du_sort(root: &File) -> Vec<(&str, usize)> { /// ``` #[allow(clippy::ptr_arg)] pub fn remove_even(inner: &mut Vec) { - todo!() + let mut indices = vec![]; + + for (i, v) in inner.iter().enumerate() { + if v % 2 == 0 { + indices.push(i); + } + } + + for &i in indices.iter().rev() { + let _ = inner.remove(i); + } } /// Remove all duplicate occurences of a number inside the array. @@ -146,7 +205,20 @@ pub fn remove_even(inner: &mut Vec) { /// ``` #[allow(clippy::ptr_arg)] pub fn remove_duplicate(inner: &mut Vec) { - todo!() + let mut set = HashSet::new(); + let mut indices = vec![]; + + for (i, v) in inner.iter().enumerate() { + if set.contains(v) { + indices.push(i); + } else { + let _ = set.insert(*v); + } + } + + for &i in indices.iter().rev() { + let _ = inner.remove(i); + } } /// Returns the natural join of two tables using the first column as the join argument. @@ -172,15 +244,32 @@ pub fn remove_duplicate(inner: &mut Vec) { /// 20231234 | Mike | ME /// ``` pub fn natural_join(table1: Vec>, table2: Vec>) -> Vec> { - todo!() + let mut result = vec![]; + + for row1 in &table1 { + for row2 in &table2 { + if row1[0] == row2[0] { + let mut temp = vec![]; + temp.append(&mut row1.clone()); + temp.extend_from_slice(&row2[1..]); + + result.push(temp); + } + } + } + + result } /// You can freely add more fields. -struct Pythagorean; +struct Pythagorean { + a: u64, + c: u64, +} impl Pythagorean { fn new() -> Self { - todo!() + Pythagorean { a: 3, c: 5 } } } @@ -188,7 +277,44 @@ impl Iterator for Pythagorean { type Item = (u64, u64, u64); fn next(&mut self) -> Option { - todo!() + fn gcd(lhs: u64, rhs: u64) -> u64 { + let (mut a, mut b) = if lhs >= rhs { (lhs, rhs) } else { (rhs, lhs) }; + + while b != 0 { + let r = a % b; + a = b; + b = r; + } + + a + } + + loop { + let a_max = ((self.c as f64) / SQRT_2).floor() as u64; + + while self.a <= a_max { + let b = ((self.c * self.c - self.a * self.a) as f64).sqrt(); + if b.floor() == b { + let b = b as u64; + if gcd(self.a, gcd(b, self.c)) == 1 + && self.a * self.a + b * b == self.c * self.c + { + self.a += 1; + + if self.a - 1 < b { + return Some((self.a - 1, b, self.c)); + } else { + return Some((b, self.a - 1, self.c)); + } + } + } + + self.a += 1; + } + + self.c += 1; + self.a = 1; + } } }