summaryrefslogtreecommitdiff
path: root/2018/aoc2018-d16.py
diff options
context:
space:
mode:
Diffstat (limited to '2018/aoc2018-d16.py')
-rw-r--r--2018/aoc2018-d16.py359
1 files changed, 359 insertions, 0 deletions
diff --git a/2018/aoc2018-d16.py b/2018/aoc2018-d16.py
new file mode 100644
index 0000000..3bb0dc1
--- /dev/null
+++ b/2018/aoc2018-d16.py
@@ -0,0 +1,359 @@
+#advent of code 2018
+#day 16
+#part 1 and part 2
+
+#when doing this puzzle I learned that I can make a list of functions and it just works
+#code could use a bit of clean up,
+#lots of multiple lines because of 16 functions
+#(I could save ~32 lines just by modifying the functions)
+#lots of work-arounds because I don't know to implement it efficently
+#but still, I got the results
+
+f = open("input.txt",'r');
+Testing = False;
+#Testing = True;
+if Testing:
+ f.close();
+ f = open("testinput.txt",'r');
+
+input_part1 = [];
+input_part2 = [];
+sublist = [];
+
+for l in f:
+ l = l.replace("\n","");
+ if (len(l) == 0):
+ input_part1.append( sublist.copy() );
+ sublist = [];
+ continue;
+ elif (l == "###"):
+ break;
+ elif (len(l) < 20):
+ sublist.append( [int(x) for x in l.split(" ")] );
+ elif (l[6] == ":"):
+ sublist.append( eval(l[7:]) );
+ elif (l[5] == ":"):
+ sublist.append( eval(l[7:]) );
+'''
+for i in input_part1:
+ print(i[0], "\t", i[1], "\t", i[2], "\t")
+'''
+
+for l in f:
+ l = l.replace("\n","");
+ input_part2.append( [int(x) for x in l.split(" ")] );
+
+'''
+print();
+print();
+print();
+for i in input_part2:
+ print(i);
+'''
+
+###opcode functions
+def addr(before, op, aft):
+ bef = before.copy();
+ C = bef[op[1]] + bef[op[2]];
+ bef[op[3]] = C;
+ return bef;
+def addi(before, op, aft):
+ bef = before.copy();
+ C = bef[op[1]] + op[2];
+ bef[op[3]] = C;
+ return bef;
+
+def mulr(before, op, aft):
+ bef = before.copy();
+ C = bef[op[1]] * bef[op[2]];
+ bef[op[3]] = C;
+ return bef;
+def muli(before, op, aft):
+ bef = before.copy();
+ C = bef[op[1]] * op[2];
+ bef[op[3]] = C;
+ return bef;
+
+def banr(before, op, aft):
+ bef = before.copy();
+ C = int(bef[op[1]] & bef[op[2]]);
+ bef[op[3]] = C;
+ return bef;
+def bani(before, op, aft):
+ bef = before.copy();
+ C = int(bef[op[1]] & op[2]);
+ bef[op[3]] = C;
+ return bef;
+
+def borr(before, op, aft):
+ bef = before.copy();
+ C = int(bef[op[1]] | bef[op[2]]);
+ bef[op[3]] = C;
+ return bef;
+def bori(before, op, aft):
+ bef = before.copy();
+ C = int(bef[op[1]] | op[2]);
+ bef[op[3]] = C;
+ return bef;
+
+def setr(before, op, aft):
+ bef = before.copy();
+ C = bef[op[1]];
+ bef[op[3]] = C;
+ return bef;
+def seti(before, op, aft):
+ bef = before.copy();
+ C = op[1];
+ bef[op[3]] = C;
+ return bef;
+
+def gtir(before, op, aft):
+ bef = before.copy();
+ C = 0 + int( op[1] > bef[op[2]] );
+ bef[op[3]] = C;
+ return bef;
+def gtri(before, op, aft):
+ bef = before.copy();
+ C = 0 + int( op[2] < bef[op[1]] );
+ bef[op[3]] = C;
+ return bef;
+def gtrr(before, op, aft):
+ bef = before.copy();
+ C = 0 + int( bef[op[1]] > bef[op[2]] );
+ bef[op[3]] = C;
+ return bef;
+
+def eqir(before, op, aft):
+ bef = before.copy();
+ C = 0 + int( op[1] == bef[op[2]] );
+ bef[op[3]] = C;
+ return bef;
+def eqri(before, op, aft):
+ bef = before.copy();
+ C = 0 + int( op[2] == bef[op[1]] );
+ bef[op[3]] = C;
+ return bef;
+def eqrr(before, op, aft):
+ bef = before.copy();
+ C = 0 + int( bef[op[1]] == bef[op[2]] );
+ bef[op[3]] = C;
+ return bef;
+
+
+def threeormore(bef, op, aft):
+ fun = 1;
+ counter = 0;
+ out = aft.copy();
+ counter += int( out == addr(bef,op,aft) );
+ counter += int( out == addi(bef,op,aft) );
+ counter += int( out == mulr(bef,op,aft) );
+ counter += int( out == muli(bef,op,aft) );
+ counter += int( out == banr(bef,op,aft) );
+ counter += int( out == bani(bef,op,aft) );
+ counter += int( out == borr(bef,op,aft) );
+ counter += int( out == bori(bef,op,aft) );
+ counter += int( out == setr(bef,op,aft) );
+ counter += int( out == seti(bef,op,aft) );
+ counter += int( out == gtir(bef,op,aft) );
+ counter += int( out == gtri(bef,op,aft) );
+ counter += int( out == gtrr(bef,op,aft) );
+ counter += int( out == eqir(bef,op,aft) );
+ counter += int( out == eqri(bef,op,aft) );
+ counter += int( out == eqrr(bef,op,aft) );
+
+ return counter;
+ '''
+ if (counter >= 3):
+ return 1;
+ else:
+ return 0;
+'''
+
+part1 = 0;
+for sample in input_part1:
+ before = sample[0];
+ instruction = sample[1];
+ after = sample[2];
+ part1 += 1*(threeormore(before, instruction, after ) >=3);
+
+print("part 1 = ", part1);
+
+#776 yoo high
+#588 correct
+#my mistake - misunderstood bitwise AND and bitwise OR
+#they dont return a boolean, just a normal integer
+#my function was int(bool(value)), which was reducing the correct value to 1
+
+
+
+#identifying single matches
+'''
+singles = [];
+doubles = [];
+triples = [];
+
+for sample in input_part1:
+ before = sample[0];
+ instruction = sample[1];
+ after = sample[2];
+ if (threeormore(before, instruction, after ) == 1):
+ singles.append(instruction[0]);
+ if (threeormore(before, instruction, after ) == 2):
+ doubles.append(instruction[0]);
+ if (threeormore(before, instruction, after ) >= 3):
+ triples.append(instruction[0]);
+ #part1 += 1*(threeormore(before, instruction, after ) >=3);
+
+singles = list(dict.fromkeys(singles));
+doubles = list(dict.fromkeys(doubles));
+triples = list(dict.fromkeys(triples));
+
+print("singles\t",len(singles), "\t", singles);
+print("doubles\t",len(doubles), "\t", doubles);
+print("triples\t",len(triples), "\t", triples);
+'''
+
+
+
+def matchingfunctions(bef, op, aft):
+ functionlist = "";
+ out = aft.copy();
+ functionlist += "addr"*( out == addr(bef,op,aft) );
+ functionlist += "addi"*( out == addi(bef,op,aft) );
+ functionlist += "mulr"*( out == mulr(bef,op,aft) );
+ functionlist += "muli"*( out == muli(bef,op,aft) );
+ functionlist += "banr"*( out == banr(bef,op,aft) );
+ functionlist += "bani"*( out == bani(bef,op,aft) );
+ functionlist += "borr"*( out == borr(bef,op,aft) );
+ functionlist += "bori"*( out == bori(bef,op,aft) );
+ functionlist += "setr"*( out == setr(bef,op,aft) );
+ functionlist += "seti"*( out == seti(bef,op,aft) );
+ functionlist += "gtir"*( out == gtir(bef,op,aft) );
+ functionlist += "gtri"*( out == gtri(bef,op,aft) );
+ functionlist += "gtrr"*( out == gtrr(bef,op,aft) );
+ functionlist += "eqir"*( out == eqir(bef,op,aft) );
+ functionlist += "eqri"*( out == eqri(bef,op,aft) );
+ functionlist += "eqrr"*( out == eqrr(bef,op,aft) );
+
+ return (op[0],functionlist);
+
+singles = [];
+doubles = [];
+triples = [];
+
+for sample in input_part1:
+ before = sample[0];
+ instruction = sample[1];
+ after = sample[2];
+ if (threeormore(before, instruction, after ) == 1):
+ singles.append(matchingfunctions(before, instruction, after ));
+ if (threeormore(before, instruction, after ) == 2):
+ doubles.append(matchingfunctions(before, instruction, after ));
+ if (threeormore(before, instruction, after ) >= 3):
+ triples.append(matchingfunctions(before, instruction, after ));
+ #part1 += 1*(threeormore(before, instruction, after ) >=3);
+
+'''
+print("singles\t",len(singles), "\t", singles);
+print("doubles\t",len(doubles), "\t", doubles);
+print("triples\t",len(triples), "\t", triples);
+'''
+
+singles = list(dict.fromkeys(singles));
+doubles = list(dict.fromkeys(doubles));
+triples = list(dict.fromkeys(triples));
+
+'''
+for s in singles:
+ print(s);
+print();
+print();
+for s in doubles:
+ print(s);
+print();
+print();
+for s in triples:
+ print(s);
+print();
+print();
+'''
+
+PossibleFunctions = {};
+total = singles + doubles + triples;
+
+for t in total:
+ PossibleFunctions.update({t[0] : t[1]});
+
+'''
+for pf in PossibleFunctions:
+ print(pf,"\t", PossibleFunctions[pf]);
+ '''
+
+IdentifiedFunctions = {};
+
+
+while (len(IdentifiedFunctions) < 16):
+ for found in IdentifiedFunctions:
+ for possible in PossibleFunctions:
+ if (len(PossibleFunctions[possible]) > 4 ):
+ s = PossibleFunctions[possible];
+ s = s.replace(IdentifiedFunctions[found], "");
+ PossibleFunctions.update({possible : s});
+
+ for pf in PossibleFunctions:
+ if (len(PossibleFunctions[pf]) == 4 ):
+ IdentifiedFunctions.update({pf : PossibleFunctions[pf]});
+
+ '''
+ for pf in PossibleFunctions:
+ print(pf,"\t", PossibleFunctions[pf]);
+ input();
+ '''
+
+'''
+print();
+print();
+print();
+print("Identified Functions");
+for pf in IdentifiedFunctions:
+ print(pf,"\t", IdentifiedFunctions[pf]);
+'''
+
+MatchFunctions = {};
+MatchFunctions.update({"addr":addr});
+MatchFunctions.update({"addi":addi});
+MatchFunctions.update({"mulr":mulr});
+MatchFunctions.update({"muli":muli});
+MatchFunctions.update({"banr":banr});
+MatchFunctions.update({"bani":bani});
+MatchFunctions.update({"borr":borr});
+MatchFunctions.update({"bori":bori});
+MatchFunctions.update({"setr":setr});
+MatchFunctions.update({"seti":seti});
+MatchFunctions.update({"gtir":gtir});
+MatchFunctions.update({"gtri":gtri});
+MatchFunctions.update({"gtrr":gtrr});
+MatchFunctions.update({"eqir":eqir});
+MatchFunctions.update({"eqri":eqri});
+MatchFunctions.update({"eqrr":eqrr});
+
+for i in IdentifiedFunctions:
+ MatchFunctions.update({i:MatchFunctions[IdentifiedFunctions[i]]});
+
+'''
+print();
+print();
+print();
+print("Matched Functions");
+for pf in MatchFunctions:
+ print(pf,"\t", MatchFunctions[pf]);
+'''
+
+reg = [0,0,0,0];
+for i in input_part2:
+ f_i = MatchFunctions[i[0]];
+ reg = f_i(reg, i, [] );
+
+part2 = reg[0];
+#print(reg);
+print("part 2 = ", part2);