diff --git a/data/input-08.txt b/data/input-08.txt new file mode 100644 index 0000000..0adb4af --- /dev/null +++ b/data/input-08.txt @@ -0,0 +1,654 @@ +acc +50 +acc -11 +nop +378 +acc +15 +jmp +508 +acc -3 +jmp +1 +jmp +135 +jmp +1 +acc -6 +acc +14 +acc +32 +jmp +315 +acc -16 +jmp +249 +jmp +283 +acc -14 +acc +5 +acc +29 +jmp +366 +acc +22 +jmp +77 +acc +19 +jmp +496 +acc -2 +acc -16 +nop +284 +nop +36 +jmp +178 +jmp +281 +acc +32 +acc +45 +acc +16 +jmp +403 +nop +86 +nop +32 +acc +10 +jmp +47 +acc -13 +acc +35 +jmp +270 +jmp +1 +acc +34 +acc -3 +nop +116 +jmp +552 +acc +27 +nop +113 +jmp +495 +acc -18 +acc +47 +acc +19 +jmp +180 +acc -8 +acc -1 +acc -14 +acc +17 +jmp +431 +acc +49 +acc +22 +acc +39 +acc +28 +jmp +74 +jmp -10 +acc -5 +acc +35 +jmp +251 +acc +31 +acc -11 +jmp -49 +acc -12 +acc +49 +jmp +36 +acc -19 +acc -9 +acc +11 +acc -1 +jmp +419 +jmp +307 +acc +36 +jmp +563 +acc +32 +acc +1 +jmp +270 +acc +17 +jmp +464 +jmp +133 +acc +29 +acc +31 +jmp +394 +acc -2 +jmp +94 +acc +44 +acc +28 +acc +32 +jmp +543 +acc +18 +jmp +325 +acc +16 +acc +42 +jmp +315 +acc -6 +jmp +371 +acc +41 +acc +29 +jmp +44 +acc -19 +jmp +393 +acc +4 +jmp +81 +acc +25 +jmp +108 +acc -18 +jmp +1 +jmp +1 +acc +34 +jmp +124 +acc +25 +acc +45 +jmp -46 +acc -11 +acc +43 +acc +50 +jmp +6 +acc +3 +acc -6 +acc +38 +acc +9 +jmp +402 +acc +26 +nop +97 +acc +26 +jmp +115 +acc -1 +acc +2 +jmp +7 +acc +38 +nop +5 +jmp -75 +acc +41 +nop +470 +jmp +15 +acc -15 +acc +19 +acc +22 +jmp +240 +acc +14 +acc +26 +jmp +71 +acc +38 +acc +25 +jmp +349 +acc +25 +acc +31 +acc +41 +jmp +419 +jmp -69 +acc +50 +nop +218 +jmp -106 +nop +225 +jmp +307 +acc +33 +acc -4 +acc +36 +jmp -57 +acc +14 +acc +0 +acc -2 +jmp +184 +acc +47 +nop +161 +acc -4 +jmp -149 +jmp +103 +acc +39 +acc +25 +acc +8 +acc +2 +jmp +364 +acc +48 +jmp +241 +nop +432 +acc +9 +jmp +304 +acc +20 +jmp +223 +acc +12 +acc +21 +jmp +121 +acc +12 +acc +47 +acc +50 +acc +8 +jmp +283 +jmp +1 +jmp +81 +acc +22 +acc -6 +jmp +1 +acc -9 +jmp +340 +acc -9 +acc +5 +acc +11 +jmp +204 +acc -13 +acc +12 +jmp +322 +acc +38 +acc +50 +nop +211 +jmp +91 +acc +31 +acc +34 +jmp -95 +acc +12 +acc +13 +jmp -172 +nop +419 +jmp +1 +nop -191 +acc +48 +jmp +157 +acc +22 +acc +27 +jmp +61 +acc +23 +nop +181 +jmp -121 +nop +367 +jmp -168 +jmp +1 +nop -218 +jmp -142 +jmp +295 +jmp +112 +acc +9 +acc -12 +jmp +114 +acc +50 +jmp -28 +acc +18 +nop -223 +acc +37 +acc -14 +jmp +169 +acc +0 +acc +42 +jmp +115 +acc +2 +acc +31 +jmp -189 +acc +7 +acc +45 +acc -2 +acc +34 +jmp -121 +acc -13 +acc +4 +nop -94 +acc +34 +jmp +123 +acc -11 +acc -13 +jmp -29 +acc -11 +nop -169 +acc -11 +nop +369 +jmp +189 +acc -4 +jmp +20 +nop +19 +acc -13 +nop +368 +jmp -79 +acc -19 +acc +23 +acc -7 +acc -11 +jmp +36 +acc -18 +acc +31 +nop +349 +acc +11 +jmp -106 +acc +43 +jmp +185 +acc +20 +nop +297 +jmp +138 +acc +8 +acc +26 +acc -2 +jmp -18 +nop -276 +jmp +44 +jmp +1 +acc +39 +jmp +314 +acc +0 +jmp -194 +acc +32 +acc +17 +acc +43 +jmp -298 +acc +28 +acc -10 +jmp -103 +acc -17 +acc +3 +jmp +25 +acc +35 +acc +7 +acc -2 +jmp -39 +acc +19 +acc +19 +acc -8 +jmp -282 +jmp -275 +acc -7 +jmp +196 +acc +14 +acc +5 +jmp +6 +acc -7 +jmp +29 +nop +275 +acc -12 +jmp +165 +acc +21 +acc +4 +jmp +95 +acc +15 +jmp -283 +jmp +199 +acc -9 +acc +0 +jmp -220 +acc +28 +acc +1 +jmp -313 +acc +13 +acc -5 +acc +38 +jmp +62 +acc +43 +jmp -159 +acc -14 +acc +44 +jmp -314 +acc +3 +acc +34 +jmp +47 +jmp -171 +acc +27 +acc +11 +acc +16 +jmp +16 +acc +27 +acc +40 +jmp +66 +acc +30 +acc -15 +jmp +177 +acc +36 +acc +41 +jmp -189 +acc -19 +jmp +106 +nop +271 +nop -176 +acc +13 +jmp +40 +nop +33 +jmp -324 +acc +18 +jmp -76 +acc +38 +acc +39 +acc +34 +jmp +231 +jmp -131 +acc +46 +acc +38 +acc -3 +jmp -161 +acc +31 +acc +10 +jmp +158 +acc -18 +acc +46 +jmp -291 +jmp +48 +acc +18 +acc +36 +acc +16 +jmp -77 +acc +9 +jmp -289 +acc +38 +jmp -388 +nop +137 +acc +42 +acc +17 +nop -37 +jmp -145 +jmp -336 +acc +46 +acc -18 +acc -13 +acc +21 +jmp -97 +acc +49 +nop -189 +acc +21 +jmp -186 +acc +25 +acc +37 +jmp +193 +jmp +1 +acc -14 +acc +4 +jmp +87 +acc +3 +nop -95 +jmp -243 +acc +30 +acc +35 +jmp -128 +jmp +1 +nop +55 +acc +48 +jmp +129 +jmp +1 +acc +37 +jmp -326 +acc -2 +acc -13 +acc +37 +jmp -72 +acc +23 +jmp +130 +acc +18 +acc +0 +acc +36 +jmp -345 +acc +0 +acc +23 +acc +10 +jmp +1 +jmp -112 +nop -430 +acc +8 +acc +42 +jmp +1 +jmp +180 +nop -16 +acc +22 +jmp +1 +acc +2 +jmp +43 +acc +29 +acc +23 +acc -2 +jmp -364 +acc +14 +jmp -250 +acc -11 +nop -359 +jmp +132 +jmp -24 +nop +90 +acc +32 +jmp -461 +jmp -311 +acc +11 +acc +21 +jmp -320 +jmp -194 +jmp -165 +acc +43 +acc +5 +acc +12 +jmp -419 +jmp -467 +acc +47 +acc +35 +jmp +133 +acc +10 +nop -394 +acc +35 +nop -109 +jmp -298 +acc -10 +nop -451 +jmp -445 +jmp +57 +acc +31 +nop -1 +jmp -59 +acc +19 +acc +7 +jmp -5 +acc +31 +acc +0 +acc +29 +acc -8 +jmp -118 +jmp -119 +acc +35 +jmp -339 +acc +14 +nop +28 +acc +0 +acc +25 +jmp -265 +acc -9 +acc +29 +jmp -365 +nop +19 +acc +31 +acc +16 +jmp -116 +jmp -442 +acc +24 +acc -3 +jmp -505 +acc -5 +jmp -485 +acc -12 +acc +15 +jmp +1 +jmp -16 +acc +23 +nop -135 +jmp +26 +acc -16 +jmp -374 +jmp -171 +jmp -518 +acc +23 +acc +23 +jmp -282 +nop -78 +nop -230 +jmp -285 +acc +39 +acc +31 +jmp -219 +acc -18 +jmp +1 +acc +43 +jmp -175 +acc +46 +nop -391 +jmp -305 +acc -11 +acc +41 +acc +33 +acc -9 +jmp +70 +nop -8 +acc -3 +acc -16 +acc +8 +jmp -139 +nop -237 +acc +1 +nop -405 +acc +16 +jmp +14 +acc +0 +acc +35 +acc +26 +acc +43 +jmp +71 +nop -187 +nop -188 +jmp -7 +acc +34 +acc +11 +nop -35 +jmp -104 +jmp -37 +jmp +1 +acc +37 +acc +1 +nop -78 +jmp +19 +acc +35 +acc +35 +acc -3 +acc +0 +jmp -377 +acc +49 +jmp -519 +acc -18 +acc -5 +acc -15 +nop -76 +jmp -530 +acc +7 +acc +0 +jmp -19 +acc +15 +acc +37 +jmp -79 +jmp -339 +nop -398 +acc -16 +jmp +20 +acc -15 +acc -5 +acc +20 +acc -12 +jmp -21 +acc +39 +acc +32 +acc +34 +jmp -330 +acc +48 +acc +2 +acc -8 +acc -15 +jmp -231 +acc +35 +acc -16 +acc +26 +nop -547 +jmp -548 +acc +6 +acc +20 +acc +1 +jmp -439 +jmp -310 +acc +7 +acc +18 +jmp -58 +nop -444 +jmp -423 +acc -5 +jmp -40 +acc -14 +acc -11 +nop -283 +jmp -122 +acc +13 +acc +5 +nop -259 +acc +12 +jmp +1 diff --git a/data/output-08.txt b/data/output-08.txt new file mode 100644 index 0000000..40fdfab --- /dev/null +++ b/data/output-08.txt @@ -0,0 +1,2 @@ +2025 +0 diff --git a/src/day08.rs b/src/day08.rs new file mode 100644 index 0000000..3fb9677 --- /dev/null +++ b/src/day08.rs @@ -0,0 +1,133 @@ +// ==== day 8 + +use crate::utils; +use anyhow::{anyhow, Result}; +use std::str::FromStr; + +#[derive(Debug)] +enum Instruction { + Acc(i32), + Jmp(i32), + Nop(i32), +} + +impl FromStr for Instruction { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + let parsed: Vec<&str> = s.trim().split(' ').collect(); + if parsed.len() != 2 { + return Err(anyhow!("instruction parse error")); + } + let opcode = parsed[0]; + let operand = parsed[1].parse::()?; + + match opcode { + "acc" => Ok(Instruction::Acc(operand)), + "jmp" => Ok(Instruction::Jmp(operand)), + "nop" => Ok(Instruction::Nop(operand)), + _ => Err(anyhow!("unknown instruction")), + } + } +} + +#[derive(Debug, Default)] +struct Console { + pc: usize, // program counter + hits: Vec, // instruction hits + accumulator: i32, // accumulator (starts at 0) + program: Vec, // program is just an array of instructions +} + +impl FromStr for Console { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + let memory: Vec = s + .lines() + .map(|l| Instruction::from_str(l).unwrap()) + .collect(); + Ok(Console { + pc: 0, + hits: vec![0; memory.len()], + accumulator: 0, + program: memory, + }) + } +} + +#[derive(PartialEq)] +enum Status { + Running, + Completed, + Halted, +} + +impl Console { + fn reset(&mut self) { + self.pc = 0; + self.accumulator = 0; + self.hits = vec![0; self.program.len()]; + } + + fn get_run_state(&self) -> Status { + // check pc + if !(0..self.program.len()).contains(&self.pc) { + Status::Completed + } + // guard against infinite loops + else if self.hits[self.pc] > 0 { + Status::Halted + } else { + Status::Running + } + } + + fn step(&mut self) -> Status { + // verify we're running + if self.get_run_state() != Status::Running { + return self.get_run_state(); + } + + // execute instruction at pc + self.hits[self.pc] += 1; + match self.program[self.pc] { + Instruction::Acc(n) => { + self.accumulator += n; + self.pc += 1; + } + Instruction::Jmp(n) => { + if n < 0 { + self.pc -= n.abs() as usize; + } else { + self.pc += n as usize; + } + } + Instruction::Nop(_) => { + self.pc += 1; + } + } + Status::Running + } + + fn run(&mut self) -> i32 { + self.reset(); + while self.step() == Status::Running {} + self.accumulator + } +} + +pub fn run() -> Result<(i32, i32)> { + let data = utils::read_file("data/input-08.txt")?; + let answers = utils::read_i64s("data/output-08.txt")?; + + let mut console = Console::from_str(&data)?; + println!("{:?}", console); + + let p1 = console.run(); + let p2 = 0; + + assert_eq!(p1, answers[0] as i32); + assert_eq!(p2, answers[1] as i32); + Ok((p1, p2)) +} diff --git a/src/main.rs b/src/main.rs index 982fc79..c2a3519 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ mod day04; mod day05; mod day06; mod day07; +mod day08; mod utils; // TODO @@ -27,5 +28,6 @@ fn main() -> Result<()> { println!("Day 05: {:?}", day05::run()?); println!("Day 06: {:?}", day06::run()?); println!("Day 07: {:?}", day07::run()?); + println!("Day 08: {:?}", day08::run()?); Ok(()) }