diff --git a/inputs/day10.txt b/inputs/day10.txt new file mode 100644 index 0000000..89ec3f1 --- /dev/null +++ b/inputs/day10.txt @@ -0,0 +1,137 @@ +noop +addx 7 +addx -1 +addx -1 +addx 5 +noop +noop +addx 1 +addx 3 +addx 2 +noop +addx 2 +addx 5 +addx 2 +addx 10 +addx -9 +addx 4 +noop +noop +noop +addx 3 +addx 5 +addx -40 +addx 26 +addx -23 +addx 2 +addx 5 +addx 26 +addx -35 +addx 12 +addx 2 +addx 17 +addx -10 +addx 3 +noop +addx 2 +addx 3 +noop +addx 2 +addx 3 +noop +addx 2 +addx 2 +addx -39 +noop +addx 15 +addx -12 +addx 2 +addx 10 +noop +addx -1 +addx -2 +noop +addx 5 +noop +addx 5 +noop +noop +addx 1 +addx 4 +addx -25 +addx 26 +addx 2 +addx 5 +addx 2 +noop +addx -3 +addx -32 +addx 1 +addx 4 +addx -2 +addx 3 +noop +noop +addx 3 +noop +addx 6 +addx -17 +addx 27 +addx -7 +addx 5 +addx 2 +addx 3 +addx -2 +addx 4 +noop +noop +addx 5 +addx 2 +addx -39 +noop +noop +addx 2 +addx 5 +addx 3 +addx -2 +addx 2 +addx 11 +addx -4 +addx -5 +noop +addx 10 +addx -18 +addx 19 +addx 2 +addx 5 +addx 2 +addx 2 +addx 3 +addx -2 +addx 2 +addx -37 +noop +addx 5 +addx 4 +addx -1 +noop +addx 4 +noop +noop +addx 1 +addx 4 +noop +addx 1 +addx 2 +noop +addx 3 +addx 5 +noop +addx -3 +addx 5 +addx 5 +addx 2 +addx 3 +noop +addx -32 +noop diff --git a/src/bin/day10_1.rs b/src/bin/day10_1.rs new file mode 100644 index 0000000..24ed333 --- /dev/null +++ b/src/bin/day10_1.rs @@ -0,0 +1,8 @@ +use std::fs; + +use aoc2022::day10::process_part_1; + +fn main() { + let file = fs::read_to_string("./inputs/day10.txt").unwrap(); + println!("{}", process_part_1(&file)); +} diff --git a/src/bin/day10_2.rs b/src/bin/day10_2.rs new file mode 100644 index 0000000..cfe9109 --- /dev/null +++ b/src/bin/day10_2.rs @@ -0,0 +1,8 @@ +use std::fs; + +use aoc2022::day10::process_part_2; + +fn main() { + let file = fs::read_to_string("./inputs/day10.txt").unwrap(); + println!("{}", process_part_2(&file)); +} diff --git a/src/day10.rs b/src/day10.rs new file mode 100644 index 0000000..daf3657 --- /dev/null +++ b/src/day10.rs @@ -0,0 +1,264 @@ +use nom::branch::alt; +use nom::bytes::complete::tag; +use nom::character::complete; +use nom::character::complete::newline; +use nom::combinator::map; +use nom::multi::separated_list1; +use nom::IResult; + +pub fn process_part_1(input: &str) -> i32 { + let (_, instructions) = parse_instructions(input).unwrap(); + let mut x = 1; + let mut strengths: Vec = vec![]; + let mut cycle = 1; + + for instruction in instructions { + match instruction { + Instruction::AddX(v) => { + cycle += 1; + if (cycle + 20) % 40 == 0 { + strengths.push(cycle * x); + } + x += v; + } + Instruction::Noop => {} + } + + cycle += 1; + if (cycle + 20) % 40 == 0 { + strengths.push(cycle * x); + } + } + + strengths.iter().sum() +} + +pub fn process_part_2(input: &str) -> String { + let window_width = 40; + let window_height = 6; + let (_, instructions) = parse_instructions(input).unwrap(); + let mut x = 1; + let mut cycle = 1; + + let mut buf = String::with_capacity((window_width + 1) * window_height); + + for instruction in instructions { + draw(&mut buf, cycle, x); + match instruction { + Instruction::AddX(v) => { + cycle += 1; + draw(&mut buf, cycle, x); + x += v; + } + Instruction::Noop => {} + } + + cycle += 1; + } + + buf +} + +// I've swapped the characters to something... more readable than the original '#' and '.' +fn draw(buf: &mut String, cycle: usize, x: i32) { + if x.abs_diff(((cycle - 1) % 40) as i32) < 2 { + buf.push('█'); + } else { + buf.push(' '); + } + + if (cycle) % 40 == 0 { + buf.push('\n'); + } +} + +#[derive(Debug)] +enum Instruction { + Noop, + AddX(i32), +} + +fn parse_instructions(input: &str) -> IResult<&str, Vec> { + separated_list1(newline, parse_instruction)(input) +} + +fn parse_instruction(input: &str) -> IResult<&str, Instruction> { + alt((map(tag("noop"), |_| Instruction::Noop), parse_addx))(input) +} + +fn parse_addx(input: &str) -> IResult<&str, Instruction> { + let (input, _) = tag("addx ")(input)?; + let (input, value) = complete::i32(input)?; + Ok((input, Instruction::AddX(value))) +} + +#[cfg(test)] +mod tests { + use super::*; + + const INPUT: &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 day1() { + assert_eq!(process_part_1(INPUT), 13140); + } + + #[test] + fn day2() { + assert_eq!( + process_part_2(INPUT), + "██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +███ ███ ███ ███ ███ ███ ███ +████ ████ ████ ████ ████ +█████ █████ █████ █████ +██████ ██████ ██████ ████ +███████ ███████ ███████ +" + ); + } +} diff --git a/src/lib.rs b/src/lib.rs index c2c0017..2aeb516 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,3 +10,4 @@ pub mod day06; pub mod day07; pub mod day08; pub mod day09; +pub mod day10;