From efd2635dd73b7806d75d23e21f37bd82288820c1 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Fri, 24 Dec 2021 05:18:45 -0500 Subject: random code for day 24 that doesn't really do anything useful --- data/2021/24.txt | 252 ++++++++++++++++++++++++++++++ src/2021/24/mod.rs | 437 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/2021/mod.rs | 4 + 3 files changed, 693 insertions(+) create mode 100644 data/2021/24.txt create mode 100644 src/2021/24/mod.rs diff --git a/data/2021/24.txt b/data/2021/24.txt new file mode 100644 index 0000000..a7d1226 --- /dev/null +++ b/data/2021/24.txt @@ -0,0 +1,252 @@ +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 1 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 1 +add x 15 +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 15 +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 13 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 26 +add x -6 +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 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 0 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 26 +add x -4 +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 13 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 1 +add x 15 +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 1 +add x 15 +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 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 1 +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 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 11 +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 14 +mul y x +add z y +inp w +mul x 0 +add x z +mod x 26 +div z 26 +add x -9 +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 26 +add x -9 +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 diff --git a/src/2021/24/mod.rs b/src/2021/24/mod.rs new file mode 100644 index 0000000..b060f1a --- /dev/null +++ b/src/2021/24/mod.rs @@ -0,0 +1,437 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +// i have no idea what i'm doing here, this code doesn't do anything useful + +use crate::prelude::*; +use std::rc::Rc; + +#[derive(Debug)] +enum Register { + W, + X, + Y, + Z, +} +use Register::*; + +impl Register { + fn lvalue<'a>(&self, alu: &'a mut Alu) -> &'a mut Rc { + match self { + W => &mut alu.w, + X => &mut alu.x, + Y => &mut alu.y, + Z => &mut alu.z, + } + } + + fn rvalue(&self, alu: &Alu) -> Rc { + match self { + W => Rc::clone(&alu.w), + X => Rc::clone(&alu.x), + Y => Rc::clone(&alu.y), + Z => Rc::clone(&alu.z), + } + } +} + +impl std::str::FromStr for Register { + type Err = anyhow::Error; + fn from_str(s: &str) -> std::result::Result { + match s { + "w" => Ok(W), + "x" => Ok(X), + "y" => Ok(Y), + "z" => Ok(Z), + _ => Err(anyhow::anyhow!(s.to_string())), + } + } +} + +#[derive(Debug)] +enum Value { + Register(Register), + Number(i64), +} + +impl Value { + fn rvalue(&self, alu: &Alu) -> Rc { + match self { + Self::Register(r) => r.rvalue(alu), + Self::Number(n) => Rc::new(Expr::Num(*n)), + } + } +} + +impl std::str::FromStr for Value { + type Err = anyhow::Error; + fn from_str(s: &str) -> std::result::Result { + match s { + "w" => Ok(Self::Register(W)), + "x" => Ok(Self::Register(X)), + "y" => Ok(Self::Register(Y)), + "z" => Ok(Self::Register(Z)), + _ => Ok(Self::Number(s.parse()?)), + } + } +} + +#[derive(Debug, PartialEq, Eq)] +enum Expr { + Num(i64), + Inp(usize), + Add(Rc, Rc), + Mul(Rc, Rc), + Div(Rc, Rc), + Mod(Rc, Rc), + Eql(Rc, Rc), +} + +impl Expr { + fn possible(&self) -> std::ops::RangeInclusive { + match self { + Self::Num(n) => *n..=*n, + Self::Inp(_) => (1..=9), + Self::Add(a, b) => { + let ap = a.possible(); + let bp = b.possible(); + (ap.start() + bp.start())..=(ap.end() + bp.end()) + } + Self::Mul(a, b) => { + let ap = a.possible(); + let bp = b.possible(); + let a1 = ap.start(); + let a2 = ap.end(); + let b1 = bp.start(); + let b2 = bp.end(); + (a1 * b1).min(a1 * b2).min(a2 * b1).min(a2 * b2) + ..=(a1 * b1).max(a1 * b2).max(a2 * b1).max(a2 * b2) + } + Self::Div(a, b) => { + let ap = a.possible(); + let bp = b.possible(); + let a1 = ap.start(); + let a2 = ap.end(); + let b1 = bp.start(); + let b2 = bp.end(); + // TODO + (-a1.abs().max(a2.abs()))..=(a1.abs().max(a2.abs())) + } + Self::Mod(_, b) => 0..=*b.possible().end(), + Self::Eql(..) => (0..=1), + } + } +} + +impl std::fmt::Display for Expr { + fn fmt( + &self, + f: &mut std::fmt::Formatter<'_>, + ) -> std::result::Result<(), std::fmt::Error> { + match self { + Self::Num(n) => write!(f, "{}", n), + Self::Inp(i) => write!(f, "I{}", i), + Self::Add(a, b) => write!(f, "({} + {})", a, b), + Self::Mul(a, b) => write!(f, "({} * {})", a, b), + Self::Div(a, b) => write!(f, "({} / {})", a, b), + Self::Mod(a, b) => write!(f, "({} % {})", a, b), + Self::Eql(a, b) => write!(f, "({} == {})", a, b), + } + } +} + +#[derive(Debug)] +pub struct Alu { + w: Rc, + x: Rc, + y: Rc, + z: Rc, + + inp_idx: usize, +} + +impl Alu { + fn new() -> Self { + Self { + w: Rc::new(Expr::Num(0)), + x: Rc::new(Expr::Num(0)), + y: Rc::new(Expr::Num(0)), + z: Rc::new(Expr::Num(0)), + + inp_idx: 0, + } + } + + fn run(&mut self, lines: impl IntoIterator) { + for (i, line) in lines.into_iter().enumerate() { + // eprintln!("{}: {}", i, self); + let captures = regex_captures!( + r"(inp|add|mul|div|mod|eql) ([wxyz])(?: ([wxyz]|-?\d+))?", + &line + ) + .unwrap(); + match &captures[1] { + "inp" => { + self.inp(captures[2].parse().unwrap()); + } + "add" => { + self.add( + captures[2].parse().unwrap(), + captures[3].parse().unwrap(), + ); + } + "mul" => { + self.mul( + captures[2].parse().unwrap(), + captures[3].parse().unwrap(), + ); + } + "div" => { + self.div( + captures[2].parse().unwrap(), + captures[3].parse().unwrap(), + ); + } + "mod" => { + self.modulo( + captures[2].parse().unwrap(), + captures[3].parse().unwrap(), + ); + } + "eql" => { + self.eql( + captures[2].parse().unwrap(), + captures[3].parse().unwrap(), + ); + } + _ => panic!("unknown opcode: {}", &captures[1]), + } + } + } + + fn inp(&mut self, a: Register) { + *a.lvalue(self) = Rc::new(Expr::Inp(self.inp_idx)); + self.inp_idx += 1; + } + + fn add(&mut self, a: Register, b: Value) { + *a.lvalue(self) = Rc::new(Expr::Add(a.rvalue(self), b.rvalue(self))); + } + + fn mul(&mut self, a: Register, b: Value) { + *a.lvalue(self) = Rc::new(Expr::Mul(a.rvalue(self), b.rvalue(self))); + } + + fn div(&mut self, a: Register, b: Value) { + *a.lvalue(self) = Rc::new(Expr::Div(a.rvalue(self), b.rvalue(self))); + } + + fn modulo(&mut self, a: Register, b: Value) { + *a.lvalue(self) = Rc::new(Expr::Mod(a.rvalue(self), b.rvalue(self))); + } + + fn eql(&mut self, a: Register, b: Value) { + *a.lvalue(self) = Rc::new(Expr::Eql(a.rvalue(self), b.rvalue(self))); + } +} + +impl std::fmt::Display for Alu { + fn fmt( + &self, + f: &mut std::fmt::Formatter<'_>, + ) -> std::result::Result<(), std::fmt::Error> { + writeln!(f, "Alu {{")?; + writeln!(f, " w: {}", self.w)?; + writeln!(f, " x: {}", self.x)?; + writeln!(f, " y: {}", self.y)?; + writeln!(f, " z: {}", self.z)?; + write!(f, "}}")?; + Ok(()) + } +} + +fn simplify(r: &Rc) -> Rc { + let simpler = match &**r { + Expr::Num(_) | Expr::Inp(_) => { + return Rc::clone(r); + } + Expr::Add(a, b) => { + if let (Expr::Num(a_num), Expr::Num(b_num)) = (&**a, &**b) { + Rc::new(Expr::Num(a_num + b_num)) + } else if **a == Expr::Num(0) { + simplify(b) + } else if **b == Expr::Num(0) { + simplify(a) + } else if let (Expr::Num(a_num), Expr::Add(aa, ab)) = (&**a, &**b) + { + if let Expr::Num(aa_num) = &**aa { + Rc::new(Expr::Add( + simplify(ab), + Rc::new(Expr::Num(a_num + aa_num)), + )) + } else if let Expr::Num(ab_num) = &**ab { + Rc::new(Expr::Add( + simplify(aa), + Rc::new(Expr::Num(a_num + ab_num)), + )) + } else { + Rc::new(Expr::Add(simplify(a), simplify(b))) + } + } else if let (Expr::Add(aa, ab), Expr::Num(b_num)) = (&**a, &**b) + { + if let Expr::Num(aa_num) = &**aa { + Rc::new(Expr::Add( + simplify(ab), + Rc::new(Expr::Num(b_num + aa_num)), + )) + } else if let Expr::Num(ab_num) = &**ab { + Rc::new(Expr::Add( + simplify(aa), + Rc::new(Expr::Num(b_num + ab_num)), + )) + } else { + Rc::new(Expr::Add(simplify(a), simplify(b))) + } + } else { + Rc::new(Expr::Add(simplify(a), simplify(b))) + } + } + Expr::Mul(a, b) => { + if let (Expr::Num(a_num), Expr::Num(b_num)) = (&**a, &**b) { + Rc::new(Expr::Num(a_num * b_num)) + } else if **a == Expr::Num(0) || **b == Expr::Num(0) { + Rc::new(Expr::Num(0)) + } else if **a == Expr::Num(1) { + simplify(b) + } else if **b == Expr::Num(1) { + simplify(a) + } else { + Rc::new(Expr::Mul(simplify(a), simplify(b))) + } + } + Expr::Div(a, b) => { + if let (Expr::Num(a_num), Expr::Num(b_num)) = (&**a, &**b) { + Rc::new(Expr::Num(a_num / b_num)) + } else if **a == Expr::Num(0) { + Rc::new(Expr::Num(0)) + } else if **b == Expr::Num(1) { + simplify(a) + } else { + (|| { + if let (Expr::Add(aa, ab), Expr::Num(b_num)) = + (&**a, &**b) + { + if let Expr::Mul(ma, mb) = &**aa { + if let Expr::Num(mb_num) = &**mb { + if b_num == mb_num { + return Rc::new(Expr::Add( + simplify(ma), + Rc::new(Expr::Div( + simplify(ab), + simplify(b), + )), + )); + } + } + } + } + if let Expr::Num(b_num) = &**b { + let ap = a.possible(); + if *ap.start() >= 0 && *ap.end() < *b_num { + return simplify(a); + } + } + Rc::new(Expr::Div(simplify(a), simplify(b))) + })() + } + } + Expr::Mod(a, b) => { + if let (Expr::Num(a_num), Expr::Num(b_num)) = (&**a, &**b) { + Rc::new(Expr::Num(a_num % b_num)) + } else if **a == Expr::Num(0) { + Rc::new(Expr::Num(0)) + } else { + (|| { + if let (Expr::Add(aa, ab), Expr::Num(b_num)) = + (&**a, &**b) + { + if let Expr::Mul(ma, mb) = &**aa { + if let Expr::Num(mb_num) = &**mb { + if b_num == mb_num { + return Rc::new(Expr::Mod( + simplify(ab), + simplify(b), + )); + } + } + } + } + if let Expr::Num(b_num) = &**b { + let ap = a.possible(); + if *ap.start() >= 0 && *ap.end() < *b_num { + return simplify(a); + } + } + Rc::new(Expr::Mod(simplify(a), simplify(b))) + })() + } + } + Expr::Eql(a, b) => { + if let (Expr::Num(a_num), Expr::Num(b_num)) = (&**a, &**b) { + Rc::new(Expr::Num(if a_num == b_num { 1 } else { 0 })) + } else { + let ap = a.possible(); + let bp = b.possible(); + if ap.end() < bp.start() || bp.end() < ap.start() { + Rc::new(Expr::Num(0)) + } else { + Rc::new(Expr::Eql(simplify(a), simplify(b))) + } + } + } + }; + let possible = simpler.possible(); + if possible.start() == possible.end() { + Rc::new(Expr::Num(*possible.start())) + } else { + simpler + } +} + +pub fn parse(fh: File) -> Result> { + Ok(parse::lines(fh)) +} + +pub fn part1(lines: impl Iterator) -> Result { + let mut alu = Alu::new(); + alu.run(lines); + let mut z = Rc::clone(&alu.z); + let mut i = 0; + loop { + i += 1; + eprintln!("{}", i); + let simpler = simplify(&z); + if simpler == z { + break; + } + z = simpler; + } + println!("{}", z); + todo!() +} + +pub fn part2(_: impl Iterator) -> Result { + todo!() +} + +#[test] +fn test() { + // assert_eq!( + // part1(parse(parse::data(2021, 24).unwrap()).unwrap()).unwrap(), + // 0 + // ); + // assert_eq!( + // part2(parse(parse::data(2021, 24).unwrap()).unwrap()).unwrap(), + // 0 + // ); +} diff --git a/src/2021/mod.rs b/src/2021/mod.rs index 7d2bdad..e5cdeb2 100644 --- a/src/2021/mod.rs +++ b/src/2021/mod.rs @@ -46,6 +46,8 @@ mod day21; mod day22; #[path = "23/mod.rs"] mod day23; +#[path = "24/mod.rs"] +mod day24; // NEXT MOD pub fn run(day: u8, puzzle: u8) -> Result { @@ -96,6 +98,8 @@ pub fn run(day: u8, puzzle: u8) -> Result { (22, 2) => day22::part2(day22::parse(parse::data(2021, 22)?)?), (23, 1) => day23::part1(day23::parse(parse::data(2021, 23)?)?), (23, 2) => day23::part2(day23::parse(parse::data(2021, 23)?)?), + (24, 1) => day24::part1(day24::parse(parse::data(2021, 24)?)?), + (24, 2) => day24::part2(day24::parse(parse::data(2021, 24)?)?), // NEXT PART _ => Err(anyhow!("unknown puzzle {}-{}", day, puzzle)), } -- cgit v1.2.3-54-g00ecf