diff options
author | Santo Cariotti <santo@dcariotti.me> | 2023-05-02 11:44:58 +0200 |
---|---|---|
committer | Santo Cariotti <santo@dcariotti.me> | 2023-05-02 11:44:58 +0200 |
commit | 2e7401338f8f13ba7584f5ce54e8e660c8a49cd4 (patch) | |
tree | 99665fa19208a36f6bada643f2cbba8b768b4cb4 /2022/day5/src | |
parent | 234aed363e1e181f458611505afaf06a54e377d3 (diff) |
Add day 5
Diffstat (limited to '2022/day5/src')
-rw-r--r-- | 2022/day5/src/lib.rs | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/2022/day5/src/lib.rs b/2022/day5/src/lib.rs new file mode 100644 index 0000000..c5f7458 --- /dev/null +++ b/2022/day5/src/lib.rs @@ -0,0 +1,163 @@ +use std::collections::HashMap; +use std::collections::VecDeque; + +pub fn part1(input: &str) -> String { + let mut h: Vec<VecDeque<char>> = Vec::with_capacity(10); + h.resize(10, VecDeque::new()); + + let split: Vec<&str> = input.split("\n\n").collect(); + let mut m: HashMap<usize, usize> = HashMap::new(); + let mut i = 0; + let mut j = 1; + while i < 10 { + m.insert(j, i); + j += 4; + i += 1; + } + + assert!(split.len() == 2); + + for line in split[0].lines() { + if line.chars().nth(1).unwrap() == '1' { + continue; + } + + for (i, ch) in line.chars().enumerate() { + match ch { + ' ' | '[' | ']' => { + continue; + } + x => { + let idx = m[&i]; + h[idx].push_front(x); + } + }; + } + } + + for line in split[1].lines() { + let actions: Vec<usize> = line + .split(' ') + .enumerate() + .filter(|&(i, _)| i % 2 == 1) + .map(|(_, e)| e.parse::<usize>().unwrap()) + .collect(); + + for _ in 0..actions[0] { + let x = h[actions[1] - 1].pop_back().unwrap(); + h[actions[2] - 1].push_back(x); + } + } + + let mut s = String::new(); + + for mut e in h { + if e.len() == 0 { + continue; + } + + let x = e.pop_back().unwrap().to_string(); + s += &x; + } + + s +} + +pub fn part2(input: &str) -> String { + let mut h: Vec<VecDeque<char>> = Vec::with_capacity(10); + h.resize(10, VecDeque::new()); + + let split: Vec<&str> = input.split("\n\n").collect(); + let mut m: HashMap<usize, usize> = HashMap::new(); + let mut i = 0; + let mut j = 1; + while i < 10 { + m.insert(j, i); + j += 4; + i += 1; + } + + assert!(split.len() == 2); + + for line in split[0].lines() { + if line.chars().nth(1).unwrap() == '1' { + continue; + } + + for (i, ch) in line.chars().enumerate() { + match ch { + ' ' | '[' | ']' => { + continue; + } + x => { + let idx = m[&i]; + h[idx].push_front(x); + } + }; + } + } + + for line in split[1].lines() { + let actions: Vec<usize> = line + .split(' ') + .enumerate() + .filter(|&(i, _)| i % 2 == 1) + .map(|(_, e)| e.parse::<usize>().unwrap()) + .collect(); + + let mut xs = Vec::<char>::new(); + for _ in 0..actions[0] { + xs.push(h[actions[1] - 1].pop_back().unwrap()); + } + xs.reverse(); + for x in xs { + h[actions[2] - 1].push_back(x); + } + } + + let mut s = String::new(); + + for mut e in h { + if e.len() == 0 { + continue; + } + + let x = e.pop_back().unwrap().to_string(); + s += &x; + } + + s +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_example() { + let input = include_str!("../example.txt"); + + assert_eq!(part1(input), String::from("CMZ")); + } + + #[test] + fn test_input1() { + let input = include_str!("../input.txt"); + + assert_eq!(part1(input), String::from("RTGWZTHLD")); + } + + #[test] + fn test_example2() { + let input = include_str!("../example.txt"); + + assert_eq!(part2(input), String::from("MCD")); + } + + #[test] + fn test_input2() { + let input = include_str!("../input.txt"); + + assert_eq!(part2(input), String::from("STHGRZZFR")); + } +} |