From ac60314a48408277bd59ce14fdb3964355381f97 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Tue, 20 Dec 2022 17:39:37 +0200 Subject: Day 20 --- 2022/src/bin/day_20.rs | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 2022/src/bin/day_20.rs (limited to '2022/src') diff --git a/2022/src/bin/day_20.rs b/2022/src/bin/day_20.rs new file mode 100644 index 0000000..dc4bf4f --- /dev/null +++ b/2022/src/bin/day_20.rs @@ -0,0 +1,91 @@ +use nom::{ + character::complete::{i64, line_ending}, + combinator::map, + multi::separated_list1, + IResult, +}; +use std::fs; + +fn main() -> Result<(), Box> { + let input = fs::read_to_string("inputs/day_20.txt")?; + let coordinates = GroveCoordinates::parser(&input).unwrap().1; + + { + let mut coordinates_1 = coordinates.clone(); + coordinates_1.mix(); + dbg!(coordinates_1.coordinate_sum()); + } + + { + let mut coordinates_2 = coordinates.clone(); + coordinates_2.decrypt(811589153); + dbg!(coordinates_2.coordinate_sum()); + } + + Ok(()) +} + +#[derive(Debug, Clone)] +struct GroveCoordinates(Vec); + +#[derive(Debug, Clone, Copy)] +struct CoordinatePoint { + val: i64, + original_order: usize, +} + +impl GroveCoordinates { + fn parser(input: &str) -> IResult<&str, Self> { + map(separated_list1(line_ending, i64), |points| { + GroveCoordinates( + points + .into_iter() + .enumerate() + .map(|(original_order, val)| CoordinatePoint { + val, + original_order, + }) + .collect(), + ) + })(input) + } + + fn decrypt(&mut self, key: i64) { + for p in &mut self.0 { + p.val *= key; + } + + for _ in 0..10 { + self.mix(); + } + } + + fn mix(&mut self) { + for original_i in 0..self.0.len() { + let encrypted_i = self + .0 + .iter() + .position(|p| p.original_order == original_i) + .unwrap(); + let to_move = self.0.remove(encrypted_i); + + let mut destination_i = encrypted_i as i64 + to_move.val; + destination_i %= self.0.len() as i64; + if destination_i < 0 { + destination_i += self.0.len() as i64; + } + self.0.insert(destination_i as usize, to_move); + } + } + + fn get(&self, i: usize) -> i64 { + self.0[i % self.0.len()].val + } + + fn coordinate_sum(&self) -> i64 { + let zero_position = self.0.iter().position(|p| p.val == 0).unwrap(); + self.get(zero_position + 1000) + + self.get(zero_position + 2000) + + self.get(zero_position + 3000) + } +} -- cgit v1.2.3