From: Greg Burri Date: Sat, 10 Dec 2022 09:36:57 +0000 (+0100) Subject: Day 10 X-Git-Url: https://git.euphorik.ch/?a=commitdiff_plain;h=47752fe649aa726f6d8e528613d71491a1f62d9e;p=advent_of_code_2022.git Day 10 --- diff --git a/src/day10.rs b/src/day10.rs new file mode 100644 index 0000000..27bb5ab --- /dev/null +++ b/src/day10.rs @@ -0,0 +1,249 @@ +pub enum Instruction { + Noop, + Addx(i32), +} + +pub fn parse(input: &str) -> Vec { + input.lines().map(|l| { + let split: Vec<&str> = l.trim().split(' ').collect(); + match split[0] { + "noop" => Instruction::Noop, + "addx" => Instruction::Addx(split[1].parse::().unwrap()), + other => panic!("Unknown instruction: {}", other), + } + }).collect() +} + +pub struct Screen { + screen: Vec>, +} + +impl Screen { + pub fn new() -> Self { + Screen { screen: Vec::new() } + } + + pub fn draw_screen(&mut self, instructions: &[Instruction]) -> i32 { + let mut x = 1; // Middle sprite position, sprite is 3 pixels wide. + let mut signal_strength = 0; + let mut cycle = 0; + + let mut tick = |x: &i32| { + let pos_x = cycle % 40; + let pos_y = cycle / 40; + if pos_x == 0 { + self.screen.push(vec![false; 40]) + } + + if pos_x >= x - 1 && pos_x <= x + 1 { + self.screen[pos_y as usize][pos_x as usize] = true; + } + + cycle += 1; + + if (cycle - 20) % 40 == 0 { + signal_strength += x * cycle; + } + + }; + + for i in instructions { + match i { + Instruction::Noop => tick(&x), + Instruction::Addx(v) => { + tick(&x); + tick(&x); + x += *v; + } + } + } + + signal_strength + } + + pub fn to_ascii(&self) -> String { + let mut ascii = String::new(); + for line in self.screen.iter() { + ascii += &line.iter().map(|p| if *p { '#' } else { '.' }).collect::(); + ascii += "\n"; + } + ascii + } +} + +#[cfg(test)] +mod tests { + use super::*; + + static INSTRUCTION: &str = + "addx 15 + addx -11 + addx 6 + addx -3 + addx 5 + addx -1 + addx -8 + addx 13 + addx 4 + noop + addx -1 + addx 5 + addx -1 + addx 5 + addx -1 + addx 5 + addx -1 + addx 5 + addx -1 + addx -35 + addx 1 + addx 24 + addx -19 + addx 1 + addx 16 + addx -11 + noop + noop + addx 21 + addx -15 + noop + noop + addx -3 + addx 9 + addx 1 + addx -3 + addx 8 + addx 1 + addx 5 + noop + noop + noop + noop + noop + addx -36 + noop + addx 1 + addx 7 + noop + noop + noop + addx 2 + addx 6 + noop + noop + noop + noop + noop + addx 1 + noop + noop + addx 7 + addx 1 + noop + addx -13 + addx 13 + addx 7 + noop + addx 1 + addx -33 + noop + noop + noop + addx 2 + noop + noop + noop + addx 8 + noop + addx -1 + addx 2 + addx 1 + noop + addx 17 + addx -9 + addx 1 + addx 1 + addx -3 + addx 11 + noop + noop + addx 1 + noop + addx 1 + noop + noop + addx -13 + addx -19 + addx 1 + addx 3 + addx 26 + addx -30 + addx 12 + addx -1 + addx 3 + addx 1 + noop + noop + noop + addx -9 + addx 18 + addx 1 + addx 2 + noop + noop + addx 9 + noop + noop + noop + addx -1 + addx 2 + addx -37 + addx 1 + addx 3 + noop + addx 15 + addx -21 + addx 22 + addx -6 + addx 1 + noop + addx 2 + addx 1 + noop + addx -10 + noop + noop + addx 20 + addx 1 + addx 2 + addx 2 + addx -6 + addx -11 + noop + noop + noop"; + + #[test] + fn part1() { + let instructions = parse(INSTRUCTION); + let mut screen = Screen::new(); + assert_eq!(screen.draw_screen(&instructions), 13140); + } + + #[test] + fn part2() { + let instructions = parse(INSTRUCTION); + let mut screen = Screen::new(); + screen.draw_screen(&instructions); + println!("{}", screen.to_ascii()); + + assert_eq!(screen.to_ascii(), + "##..##..##..##..##..##..##..##..##..##.. +###...###...###...###...###...###...###. +####....####....####....####....####.... +#####.....#####.....#####.....#####..... +######......######......######......#### +#######.......#######.......#######..... +"); + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 44cbcd1..d7d6d19 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ mod day06; mod day07; mod day08; mod day09; +mod day10; fn day01() -> String { let f = fs::File::open("data/day01.input").unwrap(); @@ -76,6 +77,13 @@ fn day09() -> String { format!("part1: {}, part2: {}", day09::nb_positions_visited_by_tail::<2>(&movements), day09::nb_positions_visited_by_tail::<10>(&movements)) } +fn day10() -> String { + let instructions = day10::parse(&fs::read_to_string("data/day10.input").unwrap()); + let mut screen = day10::Screen::new(); + let sum_signal_strength = screen.draw_screen(&instructions); + format!("part1: {}, part2: \n{}", sum_signal_strength, screen.to_ascii()) +} + fn format_micros(t: u128) -> String { if t < 10_000 { format!("{} μs", t) @@ -104,6 +112,7 @@ fn main() { day07, day08, day09, + day10, ); let args: Vec = env::args().skip(1).collect();