From aedd3a237b471d0734ee2f61d0dd1f51130c2ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zo=C3=A9=20Cassiop=C3=A9e=20Gauthier?= Date: Sat, 25 Dec 2021 14:31:28 -0500 Subject: [PATCH] Day 24 (abandoned) --- Cargo.toml | 4 + inputs/day24.txt | 252 +++++++++++++++++++++++++++++++++++++++++++++++ src/day24.rs | 220 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 476 insertions(+) create mode 100644 inputs/day24.txt create mode 100644 src/day24.rs diff --git a/Cargo.toml b/Cargo.toml index bb1a901..a9b8f98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,3 +98,7 @@ path = "src/day22.rs" [[bin]] name = "day23" path = "src/day23.rs" + +[[bin]] +name = "day24" +path = "src/day24.rs" diff --git a/inputs/day24.txt b/inputs/day24.txt new file mode 100644 index 0000000..f00d2cf --- /dev/null +++ b/inputs/day24.txt @@ -0,0 +1,252 @@ +inp w +mul x 0 +add x z +mod x 26 +div z 1 +add x 10 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 2 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 1 +add x 10 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 4 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 1 +add x 14 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 8 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 1 +add x 11 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 7 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 1 +add x 14 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 12 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 26 +add x -14 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 7 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 26 +add x 0 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 10 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 1 +add x 10 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 14 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 26 +add x -10 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 2 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 1 +add x 13 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 6 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 26 +add x -12 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 8 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 26 +add x -3 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 11 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 26 +add x -11 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 5 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 26 +add x -2 +eql x w +eql x 0 +mul y 0 +add y 25 +mul y x +add y 1 +mul z y +mul y 0 +add y w +add y 11 +mul y x +add z y diff --git a/src/day24.rs b/src/day24.rs new file mode 100644 index 0000000..c77f0ae --- /dev/null +++ b/src/day24.rs @@ -0,0 +1,220 @@ +use std::str::FromStr; + +#[derive(Copy, Clone)] +enum Operand { + W, + X, + Y, + Z, + Literal(i64), +} + +impl FromStr for Operand { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + "w" => Ok(Operand::W), + "x" => Ok(Operand::X), + "y" => Ok(Operand::Y), + "z" => Ok(Operand::Z), + _ => Ok(Operand::Literal(s.parse().unwrap())), + } + } +} + +#[derive(Copy, Clone)] +enum Instruction { + Inp(Operand), + Add(Operand, Operand), + Mul(Operand, Operand), + Div(Operand, Operand), + Mod(Operand, Operand), + Eql(Operand, Operand), +} + +impl FromStr for Instruction { + type Err = (); + + fn from_str(s: &str) -> Result { + let mut iter = s.split_ascii_whitespace(); + match iter.next().unwrap() { + "inp" => Ok(Instruction::Inp(iter.next().unwrap().parse().unwrap())), + "add" => Ok(Instruction::Add( + iter.next().unwrap().parse().unwrap(), + iter.next().unwrap().parse().unwrap(), + )), + "mul" => Ok(Instruction::Mul( + iter.next().unwrap().parse().unwrap(), + iter.next().unwrap().parse().unwrap(), + )), + "div" => Ok(Instruction::Div( + iter.next().unwrap().parse().unwrap(), + iter.next().unwrap().parse().unwrap(), + )), + "mod" => Ok(Instruction::Mod( + iter.next().unwrap().parse().unwrap(), + iter.next().unwrap().parse().unwrap(), + )), + "eql" => Ok(Instruction::Eql( + iter.next().unwrap().parse().unwrap(), + iter.next().unwrap().parse().unwrap(), + )), + _ => Err(()), + } + } +} + +struct ArithmeticLogicUnit { + w: i64, + x: i64, + y: i64, + z: i64, + inputs: Vec, +} + +impl ArithmeticLogicUnit { + fn new(inputs: &[i64]) -> ArithmeticLogicUnit { + ArithmeticLogicUnit { + w: 0, + x: 0, + y: 0, + z: 0, + inputs: inputs.to_vec(), + } + } + + fn load(&self, register: Operand) -> i64 { + match register { + Operand::W => self.w, + Operand::X => self.x, + Operand::Y => self.y, + Operand::Z => self.z, + Operand::Literal(a) => a, + } + } + + fn store(&mut self, register: Operand, value: i64) { + match register { + Operand::W => { + self.w = value; + } + Operand::X => { + self.x = value; + } + Operand::Y => { + self.y = value; + } + Operand::Z => { + self.z = value; + } + Operand::Literal(_) => panic!("can't store in literal"), + } + } + + fn eval(&mut self, instruction: Instruction) { + match instruction { + Instruction::Inp(a) => { + let value = self.inputs.pop().unwrap(); + self.store(a, value); + } + Instruction::Add(a, b) => { + let a_val = self.load(a); + let b = self.load(b); + self.store(a, a_val + b); + } + Instruction::Mul(a, b) => { + let a_val = self.load(a); + let b = self.load(b); + self.store(a, a_val * b); + } + Instruction::Div(a, b) => { + let a_val = self.load(a); + let b = self.load(b); + self.store(a, a_val / b); + } + Instruction::Mod(a, b) => { + let a_val = self.load(a); + let b = self.load(b); + self.store(a, a_val % b); + } + Instruction::Eql(a, b) => { + let a_val = self.load(a); + let b = self.load(b); + self.store(a, if a_val == b { 1 } else { 0 }); + } + } + } +} + +struct ModelNumber { + digits: [i64; 14], +} + +impl ModelNumber { + fn new() -> ModelNumber { + ModelNumber { digits: [9; 14] } + } +} + +impl Iterator for ModelNumber { + type Item = [i64; 14]; + + fn next(&mut self) -> Option { + let mut i = 0; + loop { + self.digits[i] -= 1; + if self.digits[i] == 0 { + self.digits[i] = 9; + i += 1; + } else { + break; + } + } + Some(self.digits) + } +} + +fn main() { + const INPUT: &str = include_str!("../inputs/day24.txt"); + let instructions = INPUT + .lines() + .map(|line| line.parse().unwrap()) + .collect::>(); + let model_number = ModelNumber::new(); + for digits in model_number { + let mut alu = ArithmeticLogicUnit::new(&digits); + for instruction in instructions.iter() { + alu.eval(*instruction); + } + if alu.z == 0 { + println!( + "solution {}", + digits + .iter() + .rev() + .map(|d| char::from_digit(*d as u32, 10).unwrap()) + .collect::() + ); + break; + } + } +} + +#[test] +fn test_negate() { + let mut alu = ArithmeticLogicUnit::new(&[42]); + alu.eval(Instruction::Inp(Operand::X)); + alu.eval(Instruction::Mul(Operand::X, Operand::Literal(-1))); + assert_eq!(alu.x, -42); +} + +#[test] +fn test_equals_triple() { + let mut alu = ArithmeticLogicUnit::new(&[12, 4]); + alu.eval(Instruction::Inp(Operand::Z)); + alu.eval(Instruction::Inp(Operand::X)); + alu.eval(Instruction::Mul(Operand::Z, Operand::Literal(3))); + alu.eval(Instruction::Eql(Operand::Z, Operand::X)); + assert_eq!(alu.z, 1); +}