diff --git a/lib/src/day14/mod.rs b/lib/src/day14/mod.rs index 5359a63..dc97a9b 100644 --- a/lib/src/day14/mod.rs +++ b/lib/src/day14/mod.rs @@ -16,14 +16,18 @@ impl Day14 { fn rotate(left: bool, array: &mut [[char; SIZE]; SIZE]) { let mut rot = [['.'; SIZE]; SIZE]; match left { - false => for i in 0..SIZE { - for j in 0..SIZE { - rot[i][j] = array[SIZE - j - 1][i]; + false => { + for i in 0..SIZE { + for j in 0..SIZE { + rot[i][j] = array[SIZE - j - 1][i]; + } } - }, - true => for i in 0..SIZE { - for j in 0..SIZE { - rot[i][j] = array[j][SIZE - i - 1]; + } + true => { + for i in 0..SIZE { + for j in 0..SIZE { + rot[i][j] = array[j][SIZE - i - 1]; + } } } } @@ -34,20 +38,27 @@ impl Day14 { impl Day for Day14 { fn part1(&mut self) -> String { let mut square_rocks = HashMap::::new(); - let mut new_dish = vec![vec![false; self.input.lines().next().unwrap().len()]; self.input.lines().count()]; + let mut new_dish = + vec![vec![false; self.input.lines().next().unwrap().len()]; self.input.lines().count()]; for (i, row) in self.input.lines().enumerate() { for (j, char) in row.chars().enumerate() { match char { '.' => continue, - '#' => { square_rocks.insert(j, i); }, + '#' => { + square_rocks.insert(j, i); + } 'O' => { let mut k = square_rocks.get(&j).map(|n| n + 1).unwrap_or(0); loop { - if new_dish[k][j] != true { new_dish[k][j] = true; break } - else { k += 1; } + if new_dish[k][j] != true { + new_dish[k][j] = true; + break; + } else { + k += 1; + } } - }, - _ => panic!() + } + _ => panic!(), } } } @@ -62,16 +73,39 @@ impl Day for Day14 { // .join("\n") // ); - new_dish.into_iter().enumerate().map(|(i, line)| line.into_iter().filter_map(|rock| if rock { Some(SIZE - i) } else { None }).sum::()).sum::().to_string() + new_dish + .into_iter() + .enumerate() + .map(|(i, line)| { + line.into_iter() + .filter_map(|rock| if rock { Some(SIZE - i) } else { None }) + .sum::() + }) + .sum::() + .to_string() } fn part2(&mut self) -> String { let mut direction = 0u8; // 0 -> North, 1 -> East, 2 -> South, 3 -> West - let mut new_dish: [[char; SIZE]; SIZE] = self.input.lines().map(|line| line.chars().collect_vec().try_into().unwrap()).collect_vec().try_into().unwrap(); - let mut cache = CLruCache::<(u8, [[char; SIZE]; SIZE]), [[char; SIZE]; SIZE]>::new(NonZeroUsize::new(100).unwrap()); + let mut new_dish: [[char; SIZE]; SIZE] = self + .input + .lines() + .map(|line| line.chars().collect_vec().try_into().unwrap()) + .collect_vec() + .try_into() + .unwrap(); + let mut cache = CLruCache::<(u8, [[char; SIZE]; SIZE]), [[char; SIZE]; SIZE]>::new( + NonZeroUsize::new(100).unwrap(), + ); for i in 0..390625u128 { - if i % 100000 == 0 { println!("{:.02}%, {}", i as f64 / 4000000000f64 * 100f64, cache.len()); } + if i % 100000 == 0 { + println!( + "{:.02}%, {}", + i as f64 / 4000000000f64 * 100f64, + cache.len() + ); + } // Cache check let cache_ref = new_dish.clone(); @@ -90,29 +124,36 @@ impl Day for Day14 { row.reverse(); } new_dish.reverse(); - }, + } 3 => Self::rotate(false, &mut new_dish), - _ => panic!() + _ => panic!(), } // Init tracking - let mut square_rocks = HashMap::::new(); + let mut square_rocks = + HashMap::::new(); let clone = new_dish.clone(); for (i, row) in clone.iter().enumerate() { for (j, char) in row.iter().enumerate() { match char { '.' => continue, - '#' => { square_rocks.insert(j, i); }, + '#' => { + square_rocks.insert(j, i); + } 'O' => { new_dish[i][j] = '.'; let mut k = square_rocks.get(&j).map(|n| n + 1).unwrap_or(0); loop { - if new_dish[k][j] != 'O' { new_dish[k][j] = 'O'; break } - else { k += 1; } + if new_dish[k][j] != 'O' { + new_dish[k][j] = 'O'; + break; + } else { + k += 1; + } } - }, - _ => panic!() + } + _ => panic!(), } } } @@ -127,19 +168,32 @@ impl Day for Day14 { row.reverse(); } new_dish.reverse(); - }, + } 3 => Self::rotate(true, &mut new_dish), - _ => panic!() + _ => panic!(), } - + // Loop direction - if direction != 0 { direction -= 1; } else { direction = 3; } + if direction != 0 { + direction -= 1; + } else { + direction = 3; + } } // Cache store cache.put((direction, cache_ref), new_dish); } - - new_dish.into_iter().enumerate().map(|(i, line)| line.into_iter().filter_map(|rock| if rock == 'O' { Some(SIZE - i) } else { None }).sum::()).sum::().to_string() + + new_dish + .into_iter() + .enumerate() + .map(|(i, line)| { + line.into_iter() + .filter_map(|rock| if rock == 'O' { Some(SIZE - i) } else { None }) + .sum::() + }) + .sum::() + .to_string() } } diff --git a/lib/src/day15/mod.rs b/lib/src/day15/mod.rs new file mode 100644 index 0000000..9c50551 --- /dev/null +++ b/lib/src/day15/mod.rs @@ -0,0 +1,76 @@ +use std::collections::HashMap; + +use crate::utils::Day; + +#[derive(Debug, Default)] +pub struct Day15 { + pub input: String, +} + +impl Day for Day15 { + fn part1(&mut self) -> String { + let mut current = 0usize; + + self.input + .split(',') + .map(|text| { + current = 0; + + for c in text.chars() { + current += c as usize; + current *= 17; + current %= 256; + } + + current + }) + .sum::() + .to_string() + } + + fn part2(&mut self) -> String { + let mut map = + HashMap::>::from_iter((0..=255usize).map(|i| (i, vec![]))); + + for operation in self.input.split(',') { + let (label, focal_length) = operation.split_once(['-', '=']).unwrap(); + let box_id = { + let mut current = 0; + + for c in label.chars() { + current += c as usize; + current *= 17; + current %= 256; + } + + current + }; + if focal_length == "" { + let lenses = map.get_mut(&box_id).unwrap(); + if let Some(position) = lenses.iter().position(|(l, _)| l == &label) { + lenses.remove(position); + } + } else { + let focal_length = focal_length.parse::().unwrap(); + + let lenses = map.get_mut(&box_id).unwrap(); + match lenses.iter().position(|(l, _)| l == &label) { + Some(position) => lenses[position].1 = focal_length, + None => lenses.push((label, focal_length)), + } + } + } + + (0..=255usize) + .map(|i| { + map.remove(&i) + .unwrap() + .into_iter() + .enumerate() + .map(|(j, (_, focal_length))| focal_length as usize * (j + 1) * (i + 1)) + .sum::() + }) + .sum::() + .to_string() + } +} diff --git a/lib/src/lib.rs b/lib/src/lib.rs index ef46b8f..4e09a00 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -7,6 +7,7 @@ use day11::Day11; use day12::Day12; use day13::Day13; use day14::Day14; +use day15::Day15; use day2::Day2; use day3::Day3; use day4::Day4; @@ -26,6 +27,7 @@ pub mod day11; pub mod day12; pub mod day13; pub mod day14; +pub mod day15; pub mod day2; pub mod day3; pub mod day4; @@ -71,6 +73,7 @@ pub fn get_day(day: u8, input: String) -> Box { }), 13 => Box::new(Day13 { input }), 14 => Box::new(Day14 { input }), + 15 => Box::new(Day15 { input }), _ => panic!("Invalid day #"), } } diff --git a/solution.txt b/solution.txt new file mode 100644 index 0000000..3c61c26 --- /dev/null +++ b/solution.txt @@ -0,0 +1,5 @@ +C\_.{⟨Ctrl+R⟩=len('⟨Ctrl+R⟩-')⟨Enter⟩}⟨Esc⟩yiWu +:%s/\v\.(⟨Ctrl+R⟩0)O/O\1./g⟨Enter⟩qaqqag&gg:redr|sl25m⟨Enter⟩@aq@a +⟨Ctrl+V⟩GI+0 *(0⟨Esc⟩gvlg⟨Ctrl+A⟩GyiWugvpjVGg⟨Ctrl+X⟩ +:%s/O/+1/g|%s/[.#]//g|%s/$/)⟨Enter⟩ +VggJ0C⟨Ctrl+R⟩=⟨Ctrl+R⟩-⟨Enter⟩⟨Esc⟩