From fbfcfa65fbbb4145d9a4e10ad37f8850ec5e5cf3 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Sat, 10 Dec 2022 21:50:31 +0100 Subject: [PATCH] Implement 2022 day 10 --- 2022/inputs/10.txt | 140 ++++++++++++++++++++++++++++++++++++++ 2022/src/day10.rs | 125 ++++++++++++++++++++++++++++++++-- 2022/src/samples/10.txt | 146 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 407 insertions(+), 4 deletions(-) create mode 100644 2022/inputs/10.txt create mode 100644 2022/src/samples/10.txt diff --git a/2022/inputs/10.txt b/2022/inputs/10.txt new file mode 100644 index 0000000..8af17c6 --- /dev/null +++ b/2022/inputs/10.txt @@ -0,0 +1,140 @@ +noop +addx 5 +noop +noop +noop +addx 1 +addx 2 +addx 5 +addx 2 +addx 5 +noop +noop +noop +noop +noop +addx -12 +addx 18 +addx -1 +noop +addx 3 +addx 5 +addx -5 +addx 7 +noop +addx -36 +addx 18 +addx -16 +noop +noop +noop +addx 5 +addx 2 +addx 5 +addx 2 +addx 13 +addx -6 +addx -4 +addx 5 +addx 2 +addx 4 +addx -3 +addx 2 +noop +addx 3 +addx 2 +addx 5 +addx -40 +addx 25 +addx -22 +addx 25 +addx -21 +addx 5 +addx 3 +noop +addx 2 +addx 19 +addx -10 +addx -4 +noop +addx -4 +addx 7 +noop +addx 3 +addx 2 +addx 5 +addx 2 +addx -26 +addx 27 +addx -36 +noop +noop +noop +noop +addx 4 +addx 6 +noop +addx 12 +addx -11 +addx 2 +noop +noop +noop +addx 5 +addx 5 +addx 2 +noop +noop +addx 1 +addx 2 +addx 5 +addx 2 +addx 1 +noop +noop +addx -38 +noop +addx 9 +addx -4 +noop +noop +addx 7 +addx 10 +addx -9 +addx 2 +noop +addx -9 +addx 14 +addx 5 +addx 2 +addx -24 +addx 25 +addx 2 +addx 5 +addx 2 +addx -30 +addx 31 +addx -38 +addx 7 +noop +noop +noop +addx 1 +addx 21 +addx -16 +addx 8 +addx -4 +addx 2 +addx 3 +noop +noop +addx 5 +addx -2 +addx 5 +addx 3 +addx -1 +addx -1 +addx 4 +addx 5 +addx -38 +noop diff --git a/2022/src/day10.rs b/2022/src/day10.rs index acd2238..4ab3f72 100644 --- a/2022/src/day10.rs +++ b/2022/src/day10.rs @@ -1,9 +1,126 @@ +use anyhow::Context; use anyhow::Result; +use nom::branch::alt; +use nom::bytes::complete::tag; +use nom::character::complete::newline; +use nom::combinator::iterator; +use nom::combinator::map; +use nom::sequence::preceded; +use nom::sequence::terminated; +use nom::IResult; -pub fn part1(_input: &[u8]) -> Result { - anyhow::bail!("not implemented") +#[derive(Copy, Clone, Debug)] +enum Instruction { + AddX(i32), + Noop, } -pub fn part2(_input: &[u8]) -> Result { - anyhow::bail!("not implemented") +impl Instruction { + pub fn cycles(self) -> usize { + match self { + Instruction::AddX(_) => 2, + Instruction::Noop => 1, + } + } +} + +fn parse_instruction(input: &[u8]) -> IResult<&[u8], Instruction> { + terminated( + alt(( + map(tag("noop"), |_| Instruction::Noop), + map(preceded(tag("addx "), nom::character::complete::i32), |v| { + Instruction::AddX(v) + }), + )), + newline, + )(input) +} + +pub fn part1(input: &[u8]) -> Result { + let mut x = 1; + // Count from one like a scrub + let mut cycle = 1; + + let mut input_it = iterator(input, parse_instruction); + + let mut total = 0; + + for instruction in &mut input_it { + let cycles = instruction.cycles(); + + let old_x = x; + + match instruction { + Instruction::AddX(val) => x += val, + Instruction::Noop => (), + } + + if cycle % 40 < 20 && (cycle + cycles) % 40 >= 20 { + let to_report = if (cycle + cycles) % 40 == 20 { + x + } else { + old_x + }; + + let checkpoint = (cycle + cycles) / 20 * 20; + total += to_report * (checkpoint as i32); + } + + cycle += cycles; + + if cycle >= 220 { + return Ok(total.to_string()); + } + } + + anyhow::bail!("out of instructions") +} + +pub fn part2(input: &[u8]) -> Result { + let mut x = 1; + let mut input_it = iterator(input, parse_instruction); + + let mut output = String::with_capacity(226); + + let mut cpu_cycle = 0; + + let mut next_instruction = (&mut input_it).next().context("No instructions?")?; + + for crt_cycle in 1..=240 { + while cpu_cycle + next_instruction.cycles() < crt_cycle { + match next_instruction { + Instruction::AddX(v) => x += v, + Instruction::Noop => (), + } + + cpu_cycle += next_instruction.cycles(); + next_instruction = (&mut input_it).next().unwrap_or(next_instruction); + } + + let beam_pos = ((crt_cycle + 39) % 40) as i32; + + if (beam_pos - x).abs() <= 1 { + output.push('#'); + } else { + output.push(' '); + } + + if crt_cycle % 40 == 0 { + output.push('\n'); + } + } + + Ok(output) +} + +#[cfg(test)] +mod tests { + use super::*; + + const SAMPLE: &[u8] = include_bytes!("samples/10.txt"); + + #[test] + fn sample_part1() { + assert_eq!(part1(SAMPLE).unwrap(), "13140"); + } } diff --git a/2022/src/samples/10.txt b/2022/src/samples/10.txt new file mode 100644 index 0000000..37ee8ee --- /dev/null +++ b/2022/src/samples/10.txt @@ -0,0 +1,146 @@ +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