1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
#advent of code 2020
#day 08
#a little bit bruteforce-ish,
#for part 2 I mark instruction that are actually used by boot code
#then I loop over the marked instructions and replace them 1 by 1 until
#the infinite cycle is broken
#also the input kept getting broken and needed to change the parsing
#which isn't a hard bug, but an annoying one
#ALSO during rewriting I figured out that I don't need to calculate
#part 1 separately, it's already used during cycle detection
#although this might just be a coincidence; honestly I'm not confident
#in cycle detection puzzles
BootCode = []
PuzzleInput = open("08.in","r")
for x in PuzzleInput:
if len(x) == 0: continue; #please ignore it, I'm bad at parsing
instr, val = x.split(" ");
BootCode.append(x.replace("\n",""));
PuzzleInput.close();
index = 0;
accumulator = 0;
visited = set();
#the "Im sure it works" method for part 1
while True:
instr, val = BootCode[index].split(" ");
#order += 1;
if index in visited: break;
visited.add(index);
if instr == "nop":
index += 1;
elif instr == "acc":
accumulator += int(val);
index += 1;
elif instr == "jmp":
index += int(val);
print("part 1 =",accumulator);
index = 0;
accumulator = 0;
accVals = dict();
p1 = None;
#the "it works for me but might be luck" method for part 1
while index <= len(BootCode):
instr, val = BootCode[index].split(" ");
Current, Previous = accVals.get(index,(None,None));
if Previous and Current and Previous%accumulator == Previous%accumulator:
p1 = Current;
break;
accVals[index] = (accumulator, Current);
if instr == "nop":
index += 1;
elif instr == "acc":
accumulator += int(val);
index += 1;
elif instr == "jmp":
index += int(val);
print("part 1 =",p1);
p2 = None;
for i in accVals:
if BootCode[i].split(" ")[0] == "acc": continue;
index = 0;
accumulator = 0;
accValsNested = dict();
NoCycle = True;
while index < len(BootCode):
instr, val = BootCode[index].split(" ");
Current, Previous = accValsNested.get(index,(None,None));
if Previous and Current and Previous%accumulator == Previous%accumulator:
NoCycle = False;
break;
accValsNested[index] = (accumulator, Current);
if index == i: #swap instructions
if instr == "nop":
instr = "jmp";
elif instr == "jmp":
instr = "nop";
if instr == "nop":
index += 1;
elif instr == "acc":
accumulator += int(val);
index += 1;
elif instr == "jmp":
index += int(val);
if NoCycle:
p2 = accumulator;
break;
print("part 2 =", p2);
|