diff options
Diffstat (limited to '2018/aoc2018-d16.py')
-rw-r--r-- | 2018/aoc2018-d16.py | 359 |
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); |