From 319d8bf80de4f61897b32f351be38d3cbd58b425 Mon Sep 17 00:00:00 2001 From: Glenn Griffin Date: Tue, 8 Dec 2020 05:55:13 -0800 Subject: [PATCH] day 8 --- input/2020/day8.txt | 653 ++++++++++++++++++++++++++++++++++++++++++++ src/day8.rs | 147 ++++++++++ src/lib.rs | 1 + 3 files changed, 801 insertions(+) create mode 100644 input/2020/day8.txt create mode 100644 src/day8.rs diff --git a/input/2020/day8.txt b/input/2020/day8.txt new file mode 100644 index 0000000..1f0d43c --- /dev/null +++ b/input/2020/day8.txt @@ -0,0 +1,653 @@ +acc +9 +acc -2 +acc -12 +acc +33 +jmp +301 +nop +508 +jmp +216 +acc +27 +acc +35 +acc +43 +acc +31 +jmp +309 +acc +18 +acc -19 +acc +7 +jmp +44 +acc -13 +acc -17 +acc +31 +jmp +311 +nop +612 +jmp +143 +acc +22 +nop +85 +jmp +458 +acc -3 +jmp +13 +acc -19 +acc +27 +acc +12 +jmp +483 +acc +40 +acc +6 +jmp +128 +jmp +10 +acc +0 +acc -3 +acc -2 +jmp -11 +acc +43 +acc -12 +jmp +158 +acc +0 +jmp +240 +jmp +1 +acc +5 +acc +15 +jmp +187 +nop +563 +jmp +51 +acc -16 +jmp +158 +jmp +322 +acc +47 +nop -1 +jmp +299 +acc +26 +acc +25 +jmp +232 +jmp -9 +acc +15 +jmp +54 +jmp +558 +acc +7 +acc -7 +jmp +399 +nop +447 +jmp +71 +acc +26 +acc +46 +jmp +145 +acc +38 +acc +30 +acc +21 +jmp +263 +acc +10 +jmp +168 +acc +22 +nop +561 +jmp -26 +jmp +1 +acc -7 +jmp -5 +acc +28 +acc -6 +jmp +370 +jmp +94 +acc +50 +acc +42 +acc -9 +acc +30 +jmp +70 +acc +29 +jmp +166 +acc -5 +acc -18 +nop +84 +acc +2 +jmp +366 +jmp -40 +acc -4 +acc -15 +acc -1 +jmp +169 +jmp +1 +acc -4 +acc +0 +jmp -45 +nop -21 +nop +241 +acc -18 +acc +19 +jmp +26 +nop -51 +jmp +260 +acc +17 +jmp +428 +acc +6 +jmp +405 +acc +22 +acc +10 +nop +471 +jmp +352 +acc -6 +acc +48 +acc +7 +acc +3 +jmp +57 +acc -10 +acc +16 +acc +16 +acc +43 +jmp +432 +acc -5 +acc +0 +nop +339 +acc +49 +jmp +17 +acc +33 +nop +166 +acc -5 +jmp +392 +nop +246 +acc -7 +acc +21 +acc +30 +jmp +398 +acc +36 +acc +24 +acc -15 +acc -9 +jmp +114 +acc +19 +jmp +11 +acc +43 +nop +182 +jmp -129 +nop -29 +acc -6 +acc +2 +jmp +398 +jmp +78 +acc +36 +jmp +393 +acc +15 +nop -11 +acc -7 +acc -9 +jmp +76 +acc +0 +acc +27 +jmp +25 +acc +27 +nop -54 +jmp +458 +acc +3 +acc +29 +acc -4 +acc +43 +jmp +413 +acc +33 +acc +13 +jmp +382 +jmp -83 +acc +42 +acc +24 +jmp +64 +acc +23 +acc -13 +nop +110 +acc -5 +jmp +114 +jmp +113 +nop +112 +acc +26 +jmp -133 +jmp -12 +jmp +1 +jmp +330 +acc +25 +acc -1 +acc +30 +acc +42 +jmp -187 +jmp +1 +acc +20 +acc +35 +acc +36 +jmp -125 +jmp +165 +acc +28 +acc -17 +acc -12 +jmp +1 +jmp -120 +nop +1 +acc +2 +acc +26 +jmp +398 +acc +20 +acc -1 +jmp -127 +acc +36 +acc +14 +jmp +1 +jmp +331 +acc +50 +acc +1 +acc -10 +nop +159 +jmp -83 +jmp +374 +acc +17 +jmp +372 +acc +44 +nop -39 +jmp +228 +acc +17 +jmp +74 +acc +16 +acc +33 +acc -2 +jmp +152 +jmp +29 +acc +8 +acc +27 +nop +59 +jmp -32 +acc +28 +jmp -227 +nop -35 +jmp -168 +acc +13 +nop +390 +jmp -204 +acc +16 +acc +44 +jmp -230 +jmp +25 +acc +30 +jmp +383 +acc -11 +acc +38 +acc +11 +jmp +341 +acc +35 +acc +46 +acc -1 +jmp +94 +acc -4 +acc +12 +jmp +111 +jmp +133 +nop +283 +acc +13 +acc +37 +jmp +74 +nop -218 +jmp -178 +acc +46 +acc +25 +acc -5 +jmp -174 +acc +28 +acc +39 +acc +36 +acc +22 +jmp -172 +acc +19 +jmp -250 +nop +62 +acc +44 +nop +347 +acc +40 +jmp +345 +acc -3 +acc -13 +acc -11 +jmp +56 +jmp -180 +acc +17 +acc -4 +acc +46 +nop -165 +jmp +321 +acc -4 +jmp +1 +acc +9 +acc -12 +jmp -155 +acc +5 +jmp -96 +acc +0 +acc -2 +acc +38 +jmp +67 +acc -4 +nop -283 +acc +28 +jmp +324 +acc -9 +acc +43 +acc -1 +acc +9 +jmp -290 +acc +3 +acc +22 +nop +84 +acc -17 +jmp -210 +acc +7 +jmp -260 +nop -232 +nop +87 +acc +43 +acc +36 +jmp +96 +jmp +238 +acc +13 +acc -14 +acc +32 +acc +11 +jmp -146 +acc +13 +acc +37 +acc -10 +jmp +187 +acc +49 +acc +15 +jmp -234 +jmp -328 +jmp -136 +jmp +143 +jmp +1 +acc +27 +acc +22 +jmp +1 +jmp -5 +acc +30 +nop -7 +acc -6 +jmp -71 +acc -17 +acc +15 +jmp -52 +jmp -126 +acc -4 +jmp +151 +jmp +52 +nop -86 +acc +25 +jmp +187 +nop -22 +jmp -219 +acc +33 +nop -120 +acc +0 +jmp +215 +acc +46 +acc +38 +jmp +1 +jmp -262 +jmp +157 +acc -15 +acc +48 +acc +39 +acc +10 +jmp -137 +acc +47 +acc +50 +jmp -324 +nop +214 +acc +39 +jmp -178 +acc +49 +acc -10 +jmp -268 +jmp +50 +acc -14 +nop -100 +jmp +20 +acc +45 +acc -12 +acc -4 +jmp -208 +acc -19 +jmp -340 +acc +36 +nop -358 +acc +5 +jmp -348 +acc +47 +nop -18 +acc -12 +jmp -131 +acc +19 +acc +10 +acc +19 +acc +31 +jmp -164 +nop +162 +nop -260 +jmp +146 +acc +32 +acc -1 +nop -14 +jmp -192 +acc +3 +acc +31 +nop -185 +jmp -208 +jmp -69 +acc +43 +acc +43 +jmp -68 +acc -16 +acc +5 +acc -9 +jmp +126 +acc +33 +acc +2 +acc +34 +acc -9 +jmp -16 +acc +34 +acc -19 +jmp -266 +nop +135 +nop -389 +acc +33 +jmp -195 +acc +48 +jmp +1 +acc -12 +jmp +143 +nop -317 +acc -14 +nop -127 +acc +32 +jmp -372 +acc +24 +nop -41 +nop -42 +jmp -344 +acc +23 +nop +117 +nop +92 +acc +42 +jmp +143 +acc +48 +acc -6 +nop -272 +acc -13 +jmp -379 +acc -2 +acc +44 +acc +9 +jmp -369 +acc +6 +acc +25 +acc +34 +jmp -301 +nop -227 +acc +43 +jmp -141 +acc +12 +acc +41 +acc +17 +acc -11 +jmp +29 +jmp -121 +acc +6 +acc +7 +acc +7 +jmp +131 +nop +144 +nop -142 +acc -13 +acc -18 +jmp +149 +acc +14 +acc +49 +acc +25 +acc -17 +jmp -9 +acc +26 +acc -4 +jmp -230 +acc -18 +acc +36 +acc +27 +nop -142 +jmp +21 +acc +34 +nop +54 +jmp -476 +acc +10 +jmp -174 +nop -354 +acc +1 +jmp -324 +acc +40 +jmp +94 +acc -12 +jmp -136 +nop -454 +acc -14 +jmp +116 +acc +12 +acc -1 +nop -453 +jmp -241 +jmp -479 +acc -19 +jmp -87 +acc +27 +acc +48 +acc +0 +jmp -476 +acc +16 +acc +46 +jmp -534 +acc +0 +jmp -344 +acc +0 +acc +28 +jmp +10 +jmp -248 +nop -186 +jmp +1 +acc +26 +jmp -153 +acc +14 +acc -8 +nop -416 +jmp -91 +jmp -409 +jmp -326 +acc +2 +acc +8 +acc -18 +acc +33 +jmp -468 +jmp -175 +acc -7 +acc +45 +jmp -18 +jmp -375 +acc -8 +jmp +28 +acc -16 +nop -38 +acc +37 +acc +48 +jmp -343 +acc +10 +acc +26 +acc -9 +acc -16 +jmp -348 +acc +37 +jmp -453 +acc -2 +acc +27 +acc +17 +acc +28 +jmp -406 +acc +25 +acc +24 +acc +44 +acc +44 +jmp -532 +acc +10 +jmp -531 +acc +39 +acc +40 +jmp -284 +acc +19 +acc +3 +nop -533 +acc -3 +jmp -162 +nop -438 +acc -5 +jmp -114 +acc +45 +acc +1 +acc +28 +acc +9 +jmp -550 +jmp -222 +jmp -106 +acc -7 +nop -263 +nop -375 +jmp -381 +acc -4 +nop -223 +jmp -171 +jmp -465 +acc -2 +nop -562 +jmp -190 +acc +40 +jmp -4 +acc +30 +acc +21 +jmp -435 +acc +1 +acc +10 +jmp +1 +jmp -157 +acc -7 +acc +18 +acc -3 +acc +24 +jmp -113 +acc +21 +jmp -339 +acc +34 +jmp -563 +acc +27 +jmp -589 +jmp -61 +acc +35 +acc +50 +acc +8 +jmp -553 +acc +48 +acc -15 +acc +29 +acc +24 +jmp +1 diff --git a/src/day8.rs b/src/day8.rs new file mode 100644 index 0000000..e3ca719 --- /dev/null +++ b/src/day8.rs @@ -0,0 +1,147 @@ +use aoc_runner_derive::aoc; + +#[derive(Debug, Copy, Clone)] +enum Instr { + Nop(isize), + Acc(isize), + Jmp(isize), +} + +impl Instr { + fn parse(input: &str) -> Option { + let space_idx = input.find(' ')?; + let (op, arg) = (&input[..space_idx], &input[space_idx + 1..]); + let arg = arg.parse().ok()?; + Some(match op { + "nop" => Instr::Nop(arg), + "acc" => Instr::Acc(arg), + "jmp" => Instr::Jmp(arg), + _ => return None, + }) + } +} + +#[derive(Debug, Clone)] +struct BitSet(Vec); + +impl BitSet { + fn new(max_bits: usize) -> Self { + BitSet(vec![0; (max_bits - 1) / 64 + 1]) + } + + fn contains(&self, bit_idx: usize) -> bool { + let byte_idx = bit_idx / 64; + let bit_offset = bit_idx & 63; + self.0[byte_idx] & (1 << bit_offset) != 0 + } + + fn insert(&mut self, bit_idx: usize) { + let byte_idx = bit_idx / 64; + let bit_offset = bit_idx & 63; + self.0[byte_idx] |= 1 << bit_offset; + } +} + +fn run_program( + program: &[Instr], + mut prev_instrs: BitSet, + mut pc: usize, + mut accum: isize, +) -> (usize, isize) { + while pc < program.len() { + if prev_instrs.contains(pc) { + return (pc, accum); + } + let (new_pc, new_accum) = step(program[pc], &mut prev_instrs, pc, accum); + pc = new_pc; + accum = new_accum; + } + (pc, accum) +} + +fn step( + instr: Instr, + mut prev_instrs: &mut BitSet, + mut pc: usize, + mut accum: isize, +) -> (usize, isize) { + prev_instrs.insert(pc); + pc = match instr { + Instr::Nop(_) => pc + 1, + Instr::Acc(arg) => { + accum += arg; + pc + 1 + } + Instr::Jmp(arg) => (pc as isize + arg) as usize, + }; + (pc, accum) +} + +#[aoc(day8, part1)] +pub fn solve_d8_p1(input: &str) -> isize { + let program = input + .split('\n') + .map(|line| Instr::parse(line)) + .collect::>>() + .unwrap(); + run_program(&program, BitSet::new(program.len()), 0, 0).1 +} + +#[aoc(day8, part2)] +pub fn solve_d8_p2(input: &str) -> isize { + let mut program = input + .split('\n') + .map(|line| Instr::parse(line)) + .collect::>>() + .unwrap(); + let mut pc = 0; + let mut accum = 0; + let mut prev_instrs = BitSet::new(program.len()); + loop { + match program[pc] { + Instr::Nop(arg) => { + program[pc] = Instr::Jmp(arg); + let (new_pc, new_accum) = run_program(&program, prev_instrs.clone(), pc, accum); + if new_pc == program.len() { + return new_accum; + } + program[pc] = Instr::Nop(arg); + } + Instr::Jmp(arg) => { + program[pc] = Instr::Nop(arg); + let (new_pc, new_accum) = run_program(&program, prev_instrs.clone(), pc, accum); + if new_pc == program.len() { + return new_accum; + } + program[pc] = Instr::Jmp(arg); + } + _ => {} + } + let (new_pc, new_accum) = step(program[pc], &mut prev_instrs, pc, accum); + pc = new_pc; + accum = new_accum; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_bitset() { + let mut bs = BitSet::new(192); + for bit in 0..191 { + assert!(!bs.contains(bit)); + } + bs.insert(5); + assert!(bs.contains(5)); + bs.insert(191); + assert!(bs.contains(191)); + bs.insert(63); + assert!(bs.contains(63)); + bs.insert(64); + assert!(bs.contains(64)); + bs.insert(65); + assert!(bs.contains(65)); + } +} diff --git a/src/lib.rs b/src/lib.rs index 5fede06..f230e09 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,5 +5,6 @@ pub mod day4; pub mod day5; pub mod day6; pub mod day7; +pub mod day8; aoc_runner_derive::aoc_lib! { year = 2020 }