Skip to content

Instantly share code, notes, and snippets.

@skazhy
Created December 23, 2017 18:48
Show Gist options
  • Save skazhy/708af79f574d7f69280e64322940779a to your computer and use it in GitHub Desktop.
Save skazhy/708af79f574d7f69280e64322940779a to your computer and use it in GitHub Desktop.
AoC, day 23, puzzle 2
# Step-by-step reverse engineering of day 23 / problem 2.
# Initial statate:
# `a` register set to 0, all others to 0.
# 1. set b 93
# 2. set c b
# 3. jnz a 2 (to:x0)
# 4. jnz 1 5 (to:x1)
# 5. mul b 100 (from:x0)
# 6. sub b -100000
# 7. set c b
# 8. sub c -17000
# 9. set f 1 (from:x1, from:x7)
# 10. set d 2
# 11. set e 2 (from:x4)
# 12. set g d (from:x3)
# 13. mul g e
# 14. sub g b
# 15. jnz g 2 (to:x2)
# 16. set f 0
# 17. sub e -1 (from:x2)
# 18. set g e
# 19. sub g b
# 20. jnz g -8 (to:x3)
# 21. sub d -1
# 22. set g d
# 23. sub g b
# 24. jnz g -13 (to:x4)
# 25. jnz f 2 (to:x5)
# 26. sub h -1
# 27. set g b (from:x5)
# 28. sub g c
# 29. jnz g 2 (to:x6)
# 30. jnz 1 3 (to:EXIT)
# 31. sub b -17 (from:x6)
# 32. jnz 1 -23 (to:x7)
def puzzle2():
a = 1
b, c, d, e, f, g, h = 0
return h
# Pre-jump instructions, x2, and x5 jumps removed.
# `a` register removed as well, since it does not appear anyhere.
# 9. set f 1 (from:x7)
# 10. set d 2
# 11. set e 2 (from:x4)
# 12. set g d (from:x3)
# --- x2
# 20. jnz g -8 (to:x3)
# 21. sub d -1
# 22. set g d
# 23. sub g b
# 24. jnz g -13 (to:x4)
# --- x5
# 29. jnz g 2 (to:x6)
# 30. jnz 1 3 (to:EXIT)
# 31. sub b -17 (from:x6)
# 32. jnz 1 -23 (to:x7)
def puzzle2():
b = 109300
c = 126300
d, e, f, g, h = 0
# x2
g = (g * e) - b
if g == 0:
f = 0
e = e + 1
g = e - b
# x2
# x5
if f == 0:
h = h + 1
g = b - c
# x5
return h
# x3 jump removed
# 9. set f 1 (from:x7)
# 10. set d 2
# 11. set e 2 (from:x4)
# --- x3
# 21. sub d -1
# 22. set g d
# 23. sub g b
# 24. jnz g -13 (to:x4)
# --- x5
# 29. jnz g 2 (to:x6)
# 30. jnz 1 3 (to:EXIT)
# 31. sub b -17 (from:x6)
# 32. jnz 1 -23 (to:x7)
def puzzle2():
b = 109300
c = 126300
d, e, f, g, h = 0
# x3
while True:
g = (d * e) - b
if g == 0:
f = 0
e = e + 1
g = e - b
if g == 0:
break
# x3
# x5
if f == 0:
h = h + 1
g = b - c
# x5
return h
# x4 jump removed
# 9. set f 1 (from:x7)
# --- x5
# 29. jnz g 2 (to:x6)
# 30. jnz 1 3 (to:EXIT)
# 31. sub b -17 (from:x6)
# 32. jnz 1 -23 (to:x7)
def puzzle2():
b = 109300
c = 126300
d, e, f, g, h = 0
# x5
d = 2
while True:
e = 2
while True:
g = (d * e) - b
if g == 0:
f = 0
e = e + 1
g = e - b
if g == 0:
break
d = d + 1
g = d - b
if g == 0:
break
if f == 0:
h = h + 1
g = b - c
# x5
return h
# all jumps removed, initial naive Python version finished.
def puzzle2():
b = 109300
c = 126300
h = 0
while True:
f = 1
d = 2
while True:
e = 2
while True:
g = (d * e) - b
if g == 0:
f = 0
e = e + 1
g = e - b
if g == 0:
break
d = d + 1
g = d - b
if g == 0:
break
if f == 0:
h = h + 1
g = b - c
if g == 0:
break
b = b + 17
return h
# remove redundant `g` register
def puzzle2():
b = 109300
c = 126300
h = 0
while True:
f = 1
d = 2
while True:
e = 2
while True:
if (d * e) - b == 0:
f = 0
e = e + 1
if e - b == 0:
break
d = d + 1
if d - b == 0:
break
if f == 0:
h = h + 1
if b - c == 0:
break
b = b + 17
return h
# remove c register, switch to range instead of infinite loop.
def puzzle2():
h = 0
for b in range(109300, 126300, 17):
f = 1
d = 2
while True:
e = 2
while True:
if (d * e) - b == 0:
f = 0
e = e + 1
if e - b == 0:
break
d = d + 1
if d - b == 0:
break
if f == 0:
h = h + 1
return h
# remove innermost infinite loop & use range as well.
def puzzle2():
h = 0
for b in range(109300, 126300, 17):
f = 1
d = 2
while True:
for e in range(2, b):
if (d * e) - b == 0:
f = 0
d = d + 1
if d - b == 0:
break
if f == 0:
h = h + 1
return h
# remove next innermost infinite loop & use range as well.
def puzzle2():
h = 0
for b in range(109300, 126300, 17):
f = 1
for d in range(2, b):
for e in range(2, b):
if (d * e) - b == 0:
f = 0
if f == 0:
h = h + 1
return h
# skip redundant cycles & simplify
def puzzle2():
h = 0
for b in range(109300, 126300, 17):
found = False
for d in range(2, b):
for e in range(2, b):
if d * e == b:
found = True
break
if found:
break
if found:
h += 1
return h
# at this point I actually figured out, we're counting dividers. so ditch
# the innermost loop & `found` var as well, since they're redundant.
def puzzle2():
h = 0
for b in range(109300, 126300, 17):
for d in range(2, b):
if b % d == 0:
h += 1
break
return h
# obviously, get fucked by an off-by-one error as the final insult.
def puzzle2():
h = 0
for b in range(109300, 126300 + 1, 17):
for d in range(2, b):
if b % d == 0:
h += 1
break
return h
if __name__ == "__main__":
print puzzle2()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment