diff options
| author | Louis Burda <quent.burda@gmail.com> | 2023-04-07 17:18:18 -0400 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2023-04-07 17:19:39 -0400 |
| commit | 87ab487d59fa85dbe2afa55cc841b02805ae42ca (patch) | |
| tree | cd90ab715e1b5b5803674045dbafd6d51d27ac90 /src/16/solve.py | |
| parent | 1bcc82c5bfbde87edd03c01ffdf9ee5934681592 (diff) | |
| download | aoc2018-python-87ab487d59fa85dbe2afa55cc841b02805ae42ca.tar.gz aoc2018-python-87ab487d59fa85dbe2afa55cc841b02805ae42ca.zip | |
Reorder days into src
Diffstat (limited to 'src/16/solve.py')
| -rw-r--r-- | src/16/solve.py | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/16/solve.py b/src/16/solve.py new file mode 100644 index 0000000..f9a11b6 --- /dev/null +++ b/src/16/solve.py @@ -0,0 +1,109 @@ +import sys
+sys.path.append("../common")
+import aoc
+
+def parse_log(ls):
+ data = list()
+ before = [int(v) for v in ls[0].split("[")[1].split("]")[0].split(",")]
+ ins = [int(v) for v in ls[1].split(" ")]
+ after = [int(v) for v in ls[2].split("[")[1].split("]")[0].split(",")]
+ return (before, ins, after)
+
+inslog = []
+data = aoc.data.split("\n")
+progsec = None
+for i in range(0, len(data), 4):
+ if data[i] == "\n":
+ progsec = i
+ break
+ inslog.append(parse_log(data[i:i+4]))
+
+register = list()
+
+opmap = dict()
+opmap["addr"] = lambda a, b : register[a] + register[b]
+opmap["addi"] = lambda a, b : register[a] + b
+opmap["mulr"] = lambda a, b : register[a] * register[b]
+opmap["muli"] = lambda a, b : register[a] * b
+opmap["banr"] = lambda a, b : register[a] & register[b]
+opmap["bani"] = lambda a, b : register[a] & b
+opmap["borr"] = lambda a, b : register[a] | register[b]
+opmap["bori"] = lambda a, b : register[a] | b
+opmap["setr"] = lambda a, b : register[a]
+opmap["seti"] = lambda a, b : a
+opmap["gtir"] = lambda a, b : 1 * (a > register[b])
+opmap["gtri"] = lambda a, b : 1 * (register[a] > b)
+opmap["gtrr"] = lambda a, b : 1 * (register[a] > register[b])
+opmap["eqir"] = lambda a, b : 1 * (a == register[b])
+opmap["eqri"] = lambda a, b : 1 * (register[a] == b)
+opmap["eqrr"] = lambda a, b : 1 * (register[a] == register[b])
+
+def get_possible(ins):
+ global register
+ sregister = register[:]
+ before = ins[0]
+ after = ins[2]
+ register = before
+ a = ins[1][1]
+ b = ins[1][2]
+ c = ins[1][3]
+ ops = list(opmap.values())
+ possibles = list()
+ for i in range(len(ops)):
+ op = ops[i]
+ res = None
+ try:
+ res = op(a, b)
+ except:
+ continue
+ if res == after[c]:
+ possibles.append(i)
+ register = sregister
+ return possibles
+
+def solve1(args):
+ global register
+ uncertain = 0
+ for ins in inslog:
+ if len(get_possible(ins)) >= 3:
+ uncertain += 1
+ return uncertain
+
+def solve2(args):
+ possible = dict()
+ for ins in inslog:
+ o = ins[1][0]
+ if o in possible:
+ possible[o] = [op for op in get_possible(ins) if op in possible[o]]
+ else:
+ possible[o] = get_possible(ins)
+
+ certain = False
+ while not certain:
+ singles = [p[0] for p in possible.values() if len(p) == 1]
+ for p in possible:
+ if len(possible[p]) != 1:
+ possible[p] = [v for v in possible[p] if v not in singles]
+
+ certain = True
+ for p in possible.values():
+ if len(p) != 1:
+ certain = False
+ break
+
+ ntrans = dict()
+ for p in possible: # flatten
+ ntrans[p] = possible[p][0]
+
+ for i in range(progsec, len(data)): # execute program
+ l = data[i]
+ if l == "\n": continue
+ cmd = [int(v) for v in l.split(" ")]
+ while len(register)-1 < cmd[3]:
+ register.append(0)
+
+ register[cmd[3]] = list(opmap.values())[ntrans[cmd[0]]](cmd[1], cmd[2])
+
+ return register[0]
+
+aoc.run(solve1, solve2, sols=[531, 649])
|
