aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjacopograndi <jacopo.grandi@outlook.it>2022-02-27 13:34:33 +0100
committerjacopograndi <jacopo.grandi@outlook.it>2022-02-27 13:34:33 +0100
commit629a630b2d8a02a6c9aff2e7c8c61a6e55da2b32 (patch)
treeb230dff4ecc3882974952e3b42cabaed242e750d
parent923918a20efb15c9314bf5c621fe8744e3377a58 (diff)
day24
-rwxr-xr-x2021/day24/day24bin0 -> 279120 bytes
-rw-r--r--2021/day24/day24.cpp491
-rw-r--r--2021/day24/day24_input.txt252
-rw-r--r--2021/day24/makefile2
-rw-r--r--2021/day24/notes_exec.txt252
-rw-r--r--2021/day24/notes_prog.txt490
-rw-r--r--2021/day24/test0.txt11
7 files changed, 1498 insertions, 0 deletions
diff --git a/2021/day24/day24 b/2021/day24/day24
new file mode 100755
index 0000000..f89c93c
--- /dev/null
+++ b/2021/day24/day24
Binary files differ
diff --git a/2021/day24/day24.cpp b/2021/day24/day24.cpp
new file mode 100644
index 0000000..1121018
--- /dev/null
+++ b/2021/day24/day24.cpp
@@ -0,0 +1,491 @@
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <map>
+#include <set>
+
+#include "gtest/gtest.h"
+
+class Alu {
+ private:
+ long v[4];
+
+ public:
+ Alu() {
+ v[0] = 0; v[1] = 0; v[2] = 0; v[3] = 0;
+ }
+
+ std::string show () {
+ return "(" +
+ std::to_string(v[0]) + ", " +
+ std::to_string(v[1]) + ", " +
+ std::to_string(v[2]) + ", " +
+ std::to_string(v[3]) +
+ ")";
+ }
+
+ int operator[](const int& i) const { return v[i]; }
+
+ void inp (int i, int val) { v[i] = val; }
+ void add (int i, int val) { v[i] = v[i]+val; }
+ void mul (int i, int val) { v[i] = v[i]*val; }
+ void div (int i, int val) { v[i] = v[i]/val; }
+ void mod (int i, int val) { v[i] = v[i]%val; }
+ void eql (int i, int val) { v[i] = v[i]==val ? 1 : 0; }
+ void op (int o, int i, int j, bool imm) {
+ int val = imm ? j : v[j];
+ if (o==0) inp(i, val);
+ else if (o==1) add(i, val);
+ else if (o==2) mul(i, val);
+ else if (o==3) div(i, val);
+ else if (o==4) mod(i, val);
+ else if (o==5) eql(i, val);
+ }
+};
+
+TEST (alu, exisits) {
+ Alu alu;
+}
+
+TEST (alu, variables) {
+ Alu alu;
+ ASSERT_EQ(0, alu[0]);
+ ASSERT_EQ(0, alu[1]);
+ ASSERT_EQ(0, alu[2]);
+ ASSERT_EQ(0, alu[3]);
+}
+
+TEST (alu, inp) {
+ Alu alu;
+ alu.inp(2, 5);
+ ASSERT_EQ(5, alu[2]);
+}
+
+TEST (alu, add) {
+ Alu alu;
+ alu.inp(2, 5); alu.inp(1, 6);
+ alu.add(1, alu[2]);
+ ASSERT_EQ(11, alu[1]);
+}
+
+TEST (alu, mul) {
+ Alu alu;
+ alu.inp(0, 5); alu.inp(3, 6);
+ alu.mul(3, alu[0]);
+ ASSERT_EQ(30, alu[3]);
+}
+
+TEST (alu, div) {
+ Alu alu;
+ alu.inp(0, 31); alu.inp(1, 6);
+ alu.div(0, alu[1]);
+ ASSERT_EQ(5, alu[0]);
+ alu.inp(0, -31); alu.inp(1, 6);
+ alu.div(0, alu[1]);
+ ASSERT_EQ(-5, alu[0]);
+}
+
+TEST (alu, mod) {
+ Alu alu;
+ alu.inp(0, 32); alu.inp(1, 6);
+ alu.mod(0, alu[1]);
+ ASSERT_EQ(2, alu[0]);
+}
+
+TEST (alu, eql) {
+ Alu alu;
+ alu.inp(0, 32); alu.inp(1, 43);
+ alu.eql(0, alu[1]);
+ ASSERT_EQ(0, alu[0]);
+ alu.inp(0, 5); alu.inp(1, 5);
+ alu.eql(0, alu[1]);
+ ASSERT_EQ(1, alu[0]);
+}
+
+TEST (alu, op) {
+ Alu alu;
+ alu.op(0, 0, 10, true); alu.op(0, 1, 7, true);
+ alu.op(5, 0, 1, false);
+ ASSERT_EQ(0, alu[0]);
+}
+
+
+class Rule {
+ public:
+ Rule () { }
+ Rule (std::string raw) { parse(raw); }
+ int op, i, j;
+ bool imm;
+
+ void parse (std::string raw) {
+ auto rop = raw.substr(0, 3);
+ if (rop == "inp") op = 0;
+ else if (rop == "add") op = 1;
+ else if (rop == "mul") op = 2;
+ else if (rop == "div") op = 3;
+ else if (rop == "mod") op = 4;
+ else if (rop == "eql") op = 5;
+
+ auto par = raw.substr(4);
+ i = par[0] -'w';
+ if (op > 0) {
+ if (par[2] == 'w' || par[2] == 'x' ||
+ par[2] == 'y' || par[2] == 'z') {
+ imm = false;
+ j = par[2] -'w';
+ }
+ else {
+ imm = true;
+ j = std::stoi( par.substr(2) );
+ }
+ }
+ }
+};
+
+class State {
+ public:
+ State (): alu(), pc(0) { }
+ State (std::vector<int> in): alu(), input(in), pc(0) { }
+ State (std::string raw): alu(), pc(0) { parse(raw); }
+
+ Alu alu;
+ std::vector<int> input;
+ int pc;
+
+ void parse (std::string raw) {
+ for (char c : raw) {
+ input.push_back(std::stoi(std::string { c }));
+ }
+ }
+
+ void rule (const Rule &rule) {
+ if (rule.op == 0) {
+ alu.op(rule.op, rule.i, input[pc], true);
+ pc++;
+ } else
+ alu.op(rule.op, rule.i, rule.j, rule.imm);
+ }
+};
+
+TEST (rule, translate_one) {
+ std::string raw { "inp x" };
+ Rule r { raw };
+ ASSERT_EQ(0, r.op);
+ ASSERT_EQ(1, r.i);
+}
+
+TEST (rule, translate_two) {
+ std::string raw { "mod w x" };
+ Rule r { raw };
+ ASSERT_EQ(4, r.op);
+ ASSERT_EQ(0, r.i);
+ ASSERT_EQ(1, r.j);
+}
+
+TEST (rule, translate_immediate) {
+ std::string raw { "add z 20" };
+ Rule r { raw };
+ ASSERT_EQ(1, r.op);
+ ASSERT_EQ(3, r.i);
+ ASSERT_EQ(20, r.j);
+}
+
+
+class Program {
+ public:
+ Program(std::string raw, State s): state(s) { parse(raw); }
+ Program(std::vector<Rule> r, State s): rules(r), state(s) { }
+
+ State state;
+ std::vector<Rule> rules;
+
+ void parse (std::string raw) {
+ while (raw.size() > 0) {
+ auto newline = raw.find("\n");
+ if (newline == std::string::npos) {
+ rules.push_back(Rule { raw });
+ break;
+ } else {
+ rules.push_back(Rule { raw.substr(0, newline) });
+ raw = raw.substr(newline+1);
+ }
+ }
+ }
+
+ void run () {
+ for (Rule &rule : rules) {
+ state.rule(rule);
+ }
+ }
+};
+
+TEST (program, exists) {
+ State p;
+}
+
+TEST (program, from_input) {
+ std::vector<int> input { 1, 2, 2, 4 };
+ State p { input };
+}
+
+TEST (program, apply_rule) {
+ std::vector<int> input { 1 };
+ State p { input };
+ p.rule(Rule { "inp x" });
+ ASSERT_EQ(1, p.alu[1]);
+}
+
+TEST (program, apply_negate) {
+ std::vector<int> input { 6 };
+ State p { input };
+ p.rule(Rule { "inp x" });
+ p.rule(Rule { "mul x -1" });
+ ASSERT_EQ(-6, p.alu[1]);
+}
+
+TEST (program, apply_triple) {
+ Program p {
+ {
+ Rule { "inp z" },
+ Rule { "inp x" },
+ Rule { "mul z 3" },
+ Rule { "eql z x" }
+ },
+ State { std::string { "26" } }
+ };
+ p.run();
+ ASSERT_EQ(1, p.state.alu[3]);
+}
+
+TEST (program, bits) {
+ std::string raw;
+ std::getline(std::ifstream("test0.txt"), raw, '\0');
+ Program p { raw, State { std::vector<int>{ 15 }} };
+ p.run();
+ ASSERT_EQ(1, p.state.alu[0]);
+ ASSERT_EQ(1, p.state.alu[1]);
+ ASSERT_EQ(1, p.state.alu[2]);
+ ASSERT_EQ(1, p.state.alu[3]);
+}
+
+class Set {
+ public:
+ Set () { }
+ Set (const Set &s): v(s.v) { }
+ Set (int min, int max) {
+ for (int i=min; i<max+1; i++) v.push_back(i);
+ }
+
+ std::vector<int> v;
+
+ std::string show () {
+ std::string rep = "(Set, [";
+ for (int i=0; i<v.size(); i++) {
+ rep += std::to_string(v[i]);
+ if (i < v.size()-1) rep += ", ";
+ }
+ rep += "])";
+ return rep;
+ }
+
+ Set add (int n) const {
+ Set s;
+ for (int i=0; i<v.size(); i++)
+ s.v.push_back(v[i] + n);
+ return s;
+ };
+
+ Set sub (int n) const { return add(-n); };
+
+ Set intersect (const Set &oth) const {
+ Set s;
+ for (int i=0; i<v.size(); i++) {
+ if (std::find(
+ std::begin(oth.v), std::end(oth.v), v[i]
+ ) != std::end(oth.v))
+ {
+ s.v.push_back(v[i]);
+ }
+ }
+ return s;
+ }
+
+ Set diff (const Set &oth) const {
+ Set s;
+ for (int i=0; i<v.size(); i++) {
+ if (std::find(
+ std::begin(oth.v), std::end(oth.v), v[i]
+ ) == std::end(oth.v))
+ {
+ s.v.push_back(v[i]);
+ }
+ }
+ return s;
+ }
+};
+
+TEST (set, exists) {
+ Set set;
+}
+
+TEST (set, range) {
+ Set set(1, 9);
+ ASSERT_EQ(1, set.v[0]);
+ ASSERT_EQ(7, set.v[6]);
+ ASSERT_EQ(9, set.v[8]);
+}
+
+TEST (set, add) {
+ Set base(1, 9);
+ Set set { base.add(3) };
+ ASSERT_EQ(4, set.v[0]);
+ ASSERT_EQ(10, set.v[6]);
+ ASSERT_EQ(12, set.v[8]);
+}
+
+TEST (set, sub) {
+ Set base(1, 9);
+ Set set { base.sub(3) };
+ ASSERT_EQ(-2, set.v[0]);
+ ASSERT_EQ(4, set.v[6]);
+ ASSERT_EQ(6, set.v[8]);
+}
+
+TEST (set, intersect) {
+ Set a(1, 9);
+ Set b(4, 12);
+ Set set { a.intersect(b) };
+ ASSERT_EQ(6, set.v.size());
+}
+
+TEST (set, diff) {
+ Set a(1, 9);
+ Set b(4, 12);
+ Set set { a.diff(b) };
+ ASSERT_EQ(3, set.v.size());
+}
+
+
+int fairy[14] { 1,1,1,1,26,26,1,1,26,26,1,26,26,26 };
+int magic[14] { 13,12,12,10,-11,-13,15,10,-2,-6,14,0,-15,-4 };
+int witch[14] { 8,13,8,10,12,1,13,5,10,3,2,2,12,7 };
+
+std::vector<Set> good_ids (
+ std::vector<Set> ins, std::vector<Set> z_prev, int n)
+{
+ if (z_prev.size() > 5) { return {}; }
+ if (n == 14) {
+ if (z_prev.size() <= 0) return ins;
+ else return {};
+ }
+ std::vector<Set> z { z_prev };
+
+ Set in(1, 9);
+ Set x;
+ if (z.size() > 0) {
+ x = z[z.size()-1].add(magic[n]);
+ if (fairy[n] == 26) z.erase(z.end()-1);
+ }
+ Set other = in.diff(x);
+ Set nop = in.diff(other);
+
+ for (int i=0; i<n; i++) std::cout << " ";
+ std::cout << n << " " << z.size();
+ std::cout << ", " << nop.show() << std::endl;
+
+ std::vector<Set> ins_nop = ins;
+ if (other.v.size() > 0) {
+ std::vector<Set> ins_oth = ins; ins_oth.push_back(other);
+ std::vector<Set> z_n = z; z_n.push_back(other.add(witch[n]));
+ ins = good_ids(ins_oth, z_n, n+1);
+ }
+ if (nop.v.size() > 0) {
+ ins_nop.push_back(nop);
+ std::vector<Set> ins_f = good_ids(ins_nop, z, n+1);
+ if (ins.size() == 0) {
+ ins = ins_f;
+ }
+ }
+ return ins;
+}
+
+TEST (ranges, view) {
+ auto ids = good_ids({}, {}, 0);
+ for (auto s : ids) {
+ std::cout << s.show() << std::endl;
+ }
+ ASSERT_NE(0, ids.size());
+}
+
+long min_temp = 999999999999;
+
+std::vector<int> look_rec (
+ std::vector<Set> &s, Program &p, std::vector<int> res, int n, bool big)
+{
+ if (n == 14) {
+ Program test { p.rules, State { res } };
+ test.run();
+ //if (std::abs(test.state.alu[3]) <= 15) {
+ //if (std::abs(test.state.alu[3]) <= 455) {
+ if (std::abs(test.state.alu[3]) <= min_temp) {
+ min_temp = std::abs(test.state.alu[3]);
+ for (int i=0; i<n; i++) std::cout << res[i];
+ std::cout << " " << test.state.alu[3];
+ std::cout << std::endl;
+ }
+ if (test.state.alu[3] == 0) return res;
+ else return {};
+ }
+ for (int i=s[n].v.size()-1; i>=0; i--) {
+ std::vector<int> r { res };
+ int num = s[n].v[i];
+ if (!big) num = s[n].v[s[n].v.size()-1-i];
+ r.push_back(num);
+ auto f = look_rec(s, p, r, n+1, big);
+ if (f.size() > 0) return f;
+ }
+ return {};
+}
+
+
+std::vector<int> look (Program p, bool big) {
+ auto ids = good_ids({}, {}, 0);
+ if (big) {
+ ids[0].v.erase(ids[0].v.end()-1);
+ ids[0].v.erase(ids[0].v.end()-1);
+ ids[0].v.erase(ids[0].v.end()-1);
+ ids[0].v.erase(ids[0].v.end()-1);
+ } else {
+ ids[0].v = { 1 };
+ //ids[1].v = { 1 };
+ //ids[2].v = { 1 };
+ ids[3].v = { 2 };
+ //ids[4].v = { 1 };
+
+ ids[10].v = { 1 };
+ ids[11].v = { 3 };
+ ids[12].v = { 1 };
+ ids[13].v = { 5 };
+ }
+ return look_rec(ids, p, {}, 0, big);
+}
+
+
+int main (int argc, char *argv[]) {
+ if (argc > 1 && std::string { argv[1] } == "-t") {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+ }
+ std::string raw;
+ std::getline(std::ifstream("day24_input.txt"), raw, '\0');
+
+ auto id = 0;
+ Program p { raw, State { } };
+ if (argc > 1 && std::string { argv[1] } == "big") {
+ look(p, true);
+ }
+ if (argc > 1 && std::string { argv[1] } == "small") {
+ look(p, false);
+ }
+ return 0;
+}
diff --git a/2021/day24/day24_input.txt b/2021/day24/day24_input.txt
new file mode 100644
index 0000000..2de3ed8
--- /dev/null
+++ b/2021/day24/day24_input.txt
@@ -0,0 +1,252 @@
+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 8
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+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 13
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+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 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 10
+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 12
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+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 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 13
+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 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 10
+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 3
+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 2
+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 2
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+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 12
+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 7
+mul y x
+add z y
diff --git a/2021/day24/makefile b/2021/day24/makefile
new file mode 100644
index 0000000..5de6911
--- /dev/null
+++ b/2021/day24/makefile
@@ -0,0 +1,2 @@
+all day24.cpp:
+ g++ -std=c++20 -lgtest day24.cpp -o day24
diff --git a/2021/day24/notes_exec.txt b/2021/day24/notes_exec.txt
new file mode 100644
index 0000000..5885b37
--- /dev/null
+++ b/2021/day24/notes_exec.txt
@@ -0,0 +1,252 @@
+inp w
+mul x 0 nop
+add x z nop
+mod x 26 nop
+div z 1 nop
+add x 13 w=i0, x=13
+eql x w w=i0, x=0
+eql x 0 w=i0, x=1
+mul y 0 nop
+add y 25 w=i0, x=1, y=25
+mul y x nop
+add y 1 w=i0, x=1, y=26
+mul z y nop
+mul y 0 w=i0, x=1
+add y w w=i0, y=i0, x=1
+add y 8 w=i0, y=i0+8, x=1
+mul y x nop
+add z y w=i0, x=1, y=i0+8, z=i0+8
+inp w w=i1, x=1, y=i0+8, z=i0+8
+mul x 0 w=i1, x=0, y=i0+8, z=i0+8
+add x z w=i1, x=z=y=i0+8
+mod x 26 w=i1, x=(i0+8)%26, y=i0+8, z=i0+8
+div z 1 nop
+add x 12 w=i1, x=(i0+8)%26+12, y=i0+8, z=i0+8
+eql x w w=i1, x=0, y=i0+8, z=i0+8
+eql x 0 w=i1, x=1, y=i0+8, z=i0+8
+mul y 0 w=i1, x=1, y=0, z=i0+8
+add y 25 w=i1, x=1, y=25, z=i0+8
+mul y x nop
+add y 1 w=i1, x=1, y=26, z=i0+8
+mul z y w=i1, x=1, y=26, z=(i0+8)*26
+mul y 0 w=i1, x=1, y=0, z=(i0+8)*26
+add y w w=i1, x=1, y=i1, z=(i0+8)*26
+add y 13 w=i1, x=1, y=i1+13, z=(i0+8)*26
+mul y x nop
+add z y w=i1, x=1, y=i1+13, z=(i0+8)*26 + i1+13
+inp w w=i2, x=1, y=i1+13, z=(i0+8)*26 + i1+13
+mul x 0 w=i2, x=0, y=i1+13, z=(i0+8)*26 + i1+13
+add x z w=i2, x=z, y=i1+13, z=(i0+8)*26 + i1+13
+mod x 26 w=i2, x=z%26, y=i1+13, z=(i0+8)*26 + i1+13
+div z 1 nop
+add x 12 w=i2, x=z%26+12, y=i1+13, z=(i0+8)*26 + i1+13
+eql x w w=i2, x=0, y=i1+13, z=(i0+8)*26 + i1+13
+eql x 0 w=i2, x=1, y=i1+13, z=(i0+8)*26 + i1+13
+mul y 0 w=i2, x=1, y=0, z=(i0+8)*26 + i1+13
+add y 25 w=i2, x=1, y=25, z=(i0+8)*26 + i1+13
+mul y x nop
+add y 1 w=i2, x=1, y=26, z=(i0+8)*26 + i1+13
+mul z y w=i2, x=1, y=26, z=((i0+8)*26 + i1+13)*26
+mul y 0 w=i2, x=1, y=0, z=((i0+8)*26 + i1+13)*26
+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 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 10
+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 12
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+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 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 13
+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 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 10
+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 3
+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 2
+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 2
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+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 12
+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 7
+mul y x
+add z y
diff --git a/2021/day24/notes_prog.txt b/2021/day24/notes_prog.txt
new file mode 100644
index 0000000..4658479
--- /dev/null
+++ b/2021/day24/notes_prog.txt
@@ -0,0 +1,490 @@
+just a repeated routine, except for an immediate add to x: magic
+
+{wrong}
+hidden rules:
+if curr[n]%26 + magic[n] == i[n]: curr[n] = 0
+curr[n] = (curr[n]*26) + (i[n]+8)
+
+requirement:
+curr[last] = 0
+
+// evidence
+99998499593576 z[14] = 455
+99998499594676 z[14] = 455
+99998499595776 z[14] = 455
+99998499596876 z[14] = 455
+99998499597976 z[14] = 455
+
+99998422592476 z[14] = 13
+89998422592476 z[14] = 13
+98998422592466 z[14] = 13
+99987422592476 z[14] = 13
+69998422592476 z[14] = 13
+
+59998426997979 z[14] = 0
+49998426997978 z[14] = 0
+39998426997977 z[14] = 0
+
+// evidence smaller
+51112188486865 352
+11112111481316 6461
+11114332481315 248
+11113232481315 248
+11114332481315 248
+
+fairy = 1, 1, 1, 1, 26, 26, 1, 1, 26, 26, 1, 26, 26, 26
+magic = 13, 12, 12, 10, -11, -13, 15, 10, -2, -6, 14, 0, -15, -4
+witch = 8, 13, 8, 10, 12, 1, 13, 5, 10, 3, 2, 2, 12, 7
+
+w = in[n]
+x *= 0
+x += z
+x %= 26
+z /= fairy[n]
+x += magic[n]
+x = x==w ? 1 : 0
+x = x==0 ? 1 : 0
+y = 25
+y *= x
+y ++
+z *= y
+y = w+witch[n]
+y *= x
+z += y
+
+// procedure:
+w = in[n]
+x = z%26 + magic[n]
+z /= fairy[n]
+y = 25
+if x == w:
+ z not modified
+else:
+ y = 26
+ z *= 26
+ z += in[n] + witch[n]
+
+// working forwards
+
+n = 0
+x = 13
+z = 9..17
+
+n = 1
+x = 9..17 + 12
+z = (9..17)*26 + 14..22
+
+n = 2
+x = z%26 + 12
+z = z*26 + 9..17
+ = ((9..17)*26 + 14..22)*26 + 9..17
+
+n = 3
+x = z%26 + 10
+z = z*26 + 11..19
+ = (((9..17)*26 + 14..22)*26 + 9..17)*26 + 11..19
+
+n = 4
+x = z%26 - 11 = 11..19 - 11 => 0..8
+z /= 26 => z =
+ = ((9..17)*26 + 14..22)*26 + 9..17
+if 1..9 != 0..8:
+ in[4] = 9
+ z = (z*26 + 21)
+ = (((9..17)*26 + 14..22)*26 + 9..17)*26 + 21
+else:
+ in[4] = 1..8
+ z = ((9..17)*26 + 14..22)*26 + 9..17
+
+n = 5
+case in[4] == 1..8:
+x = z%26 - 13 = 9..17 - 13 = -4..4
+z /= 26 => z = (9..17)*26 + 14..22
+if 1..9 != -4..4:
+ in[5] = 5..9
+ z = z*26 + 5..9 + 1
+ = ((9..17)*26 + 14..22)*26 + 6..10
+else:
+ in[5] = 1..4
+ z = (9..17)*26 + 14..22
+case in[4] == 9:
+x = z%26 - 13 = 21 - 13 = 8
+z /= 26 => z = ((9..17)*26 + 14..22)*26 + 9..17
+if 1..9 != 8:
+ in[5] = 1..7,9
+ z = z*26 + 1..7,9 + 1
+ = (((9..17)*26 + 14..22)*26 + 9..17)*26 + 2..8,10
+else:
+ in[5] = 8
+ z = ((9..17)*26 + 14..22)*26 + 9
+
+n = 6
+case in[4] == 1..8:
+case in[5] == 5..9:
+
+case in[5] == 1..4:
+
+case in[4] == 9:
+case in[5] == 1..7,9:
+z = (((9..17)*26 + 14..22)*26 + 9..17)*26 + 2..8,10
+x = z%26 + 15 = 2..8,10 + 15 > 9
+z = z*26 + 1..9 + 13 =
+ = ((((9..17)*26 + 14..22)*26 + 9..17)*26 + 2..8,10)*26 + 14..22
+z is too big, further down it cant be divided enough to be 0
+case in[5] == 8:
+
+// procedure:
+w = in[n]
+x = z%26 + magic[n]
+z /= fairy[n]
+y = 25
+if x == w:
+ z not modified
+else:
+ y = 26
+ z *= 26
+ z += in[n] + witch[n]
+
+// working backwards
+
+n = 9
+x = z%26 -6
+z = z/26
+if in[n] != x:
+ z = (z*26 + 3 + in[n])
+
+ at the end z in R[10]
+ if x == in[n] => z%26-6 == 1..9
+ => z%26 = 7..15
+ => S[9] = (j*26+7..15 | j in R[10])
+ else
+ at the end z is a multiple of 26 + 3..12
+ => T[9] = (j+3..12 | j%26 != 7..15, j in R[10])
+ R[9] = S[9] + T[9]
+
+n = 10
+x = z%26 + 14
+if in[n] != x:
+ z = (z*26 + 2 + in[n])
+
+ at the end z in R[11]
+ if x == in[n] => z%26+14 == 1..9
+ z%26 == 15..23
+ but every j in R[11], j%26 = 1..9, impossible
+ else
+ => z%26 = 0..14 u 24..25
+ => z = z*26 + 3..11, in R[11] if 3..9
+ => z = z*26 + 3..9
+ => R[10] = { j | j%26 != 15..23, j*26+3..9 in R[11] }
+
+n = 11
+x = z%26
+z = z/26
+if in[n] != x:
+ z = (z*26) + 2 + in[n]
+
+ at the end z=0 or (z=4*26..14*26, z%26=16..24) = R[12]
+ at the start z=0 -> z = 2+in[n] == 0 impossible
+ if x == in[n] => z%26 == in[n]
+ => at the end z in R[12]
+ => in[n] = z%26
+ => z%26 = 1..9
+ => z = (j+i..9 | j in R[12]*26) = R[11]
+ else
+ z is a multiple of 26 + 3..11 and z in R[12]
+ but every j in R[12] j%26=16..24 so z not in R[12]
+
+n = 12
+x = -15 + z%26
+z = z / 26
+if in[n] != x:
+ z = (z*26) + 7 + in[n]
+
+ at the end z is in 4..14
+ at the start either z = 0 -> z=7+in[n] -> in[n] = 1..7
+ or z in 5*26..14*26 and z%26-15 == in[n]
+ so in[n] = 1..9
+ so z%26 = 16..24, z=5*26..14*26
+ len(R[12]) = 90
+
+n = 13
+x = -4 + z%26
+z = z / 26
+if in[n] != x:
+ z = (z*26) + 7 + in[n]
+
+ at the end z has to be 0
+ so at the start z < 26, z-4>0, z-4<10
+ so z < 26, z>4, z<14
+ so in[n] = 1..9
+
+n = 14
+z = 0
+
+
+
+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 8
+mul y x
+add z y
+
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+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 13
+mul y x
+add z y
+
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+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 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 10
+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 12
+mul y x
+add z y
+
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+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 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 13
+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 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 10
+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 3
+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 2
+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 2
+mul y x
+add z y
+
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+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 12
+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 7
+mul y x
+add z y
diff --git a/2021/day24/test0.txt b/2021/day24/test0.txt
new file mode 100644
index 0000000..6b1b0e6
--- /dev/null
+++ b/2021/day24/test0.txt
@@ -0,0 +1,11 @@
+inp w
+add z w
+mod z 2
+div w 2
+add y w
+mod y 2
+div w 2
+add x w
+mod x 2
+div w 2
+mod w 2