summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-12-24 05:18:45 -0500
committerJesse Luehrs <doy@tozt.net>2021-12-24 05:18:45 -0500
commitefd2635dd73b7806d75d23e21f37bd82288820c1 (patch)
tree2e827cb4983154ce1bc274983609c0da3287c2b1
parent8d117c794835091d3c3416fc5944149372bd369c (diff)
downloadadvent-of-code-efd2635dd73b7806d75d23e21f37bd82288820c1.tar.gz
advent-of-code-efd2635dd73b7806d75d23e21f37bd82288820c1.zip
random code for day 24 that doesn't really do anything useful
-rw-r--r--data/2021/24.txt252
-rw-r--r--src/2021/24/mod.rs437
-rw-r--r--src/2021/mod.rs4
3 files changed, 693 insertions, 0 deletions
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<Expr> {
+ match self {
+ W => &mut alu.w,
+ X => &mut alu.x,
+ Y => &mut alu.y,
+ Z => &mut alu.z,
+ }
+ }
+
+ fn rvalue(&self, alu: &Alu) -> Rc<Expr> {
+ 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<Self, Self::Err> {
+ 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<Expr> {
+ 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<Self, Self::Err> {
+ 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<Expr>, Rc<Expr>),
+ Mul(Rc<Expr>, Rc<Expr>),
+ Div(Rc<Expr>, Rc<Expr>),
+ Mod(Rc<Expr>, Rc<Expr>),
+ Eql(Rc<Expr>, Rc<Expr>),
+}
+
+impl Expr {
+ fn possible(&self) -> std::ops::RangeInclusive<i64> {
+ 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<Expr>,
+ x: Rc<Expr>,
+ y: Rc<Expr>,
+ z: Rc<Expr>,
+
+ 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<Item = String>) {
+ 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<Expr>) -> Rc<Expr> {
+ 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<impl Iterator<Item = String>> {
+ Ok(parse::lines(fh))
+}
+
+pub fn part1(lines: impl Iterator<Item = String>) -> Result<i64> {
+ 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<Item = String>) -> Result<i64> {
+ 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<i64> {
@@ -96,6 +98,8 @@ pub fn run(day: u8, puzzle: u8) -> Result<i64> {
(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)),
}