Skip to content

Instantly share code, notes, and snippets.

@ntreu14
Last active December 6, 2019 23:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ntreu14/2b492aaf66302118bdbff71ded027d88 to your computer and use it in GitHub Desktop.
Save ntreu14/2b492aaf66302118bdbff71ded027d88 to your computer and use it in GitHub Desktop.
Solution for Advent of Code 2019 Day 5 Part 2
from collections import deque
from abc import abstractmethod
puzzle_input = deque([3,225,1,225,6,6,1100,1,238,225,104,0,1002,114,19,224,1001,224,-646,224,4,224,102,8,223,223,1001,224,7,224,1,223,224,223,1101,40,62,225,1101,60,38,225,1101,30,29,225,2,195,148,224,1001,224,-40,224,4,224,1002,223,8,223,101,2,224,224,1,224,223,223,1001,143,40,224,101,-125,224,224,4,224,1002,223,8,223,1001,224,3,224,1,224,223,223,101,29,139,224,1001,224,-99,224,4,224,1002,223,8,223,1001,224,2,224,1,224,223,223,1101,14,34,225,102,57,39,224,101,-3420,224,224,4,224,102,8,223,223,1001,224,7,224,1,223,224,223,1101,70,40,225,1102,85,69,225,1102,94,5,225,1,36,43,224,101,-92,224,224,4,224,1002,223,8,223,101,1,224,224,1,224,223,223,1102,94,24,224,1001,224,-2256,224,4,224,102,8,223,223,1001,224,1,224,1,223,224,223,1102,8,13,225,1101,36,65,224,1001,224,-101,224,4,224,102,8,223,223,101,3,224,224,1,223,224,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,8,677,226,224,1002,223,2,223,1006,224,329,1001,223,1,223,1108,226,226,224,1002,223,2,223,1005,224,344,101,1,223,223,1108,226,677,224,1002,223,2,223,1006,224,359,101,1,223,223,107,226,226,224,1002,223,2,223,1005,224,374,101,1,223,223,1107,226,226,224,1002,223,2,223,1005,224,389,101,1,223,223,107,677,677,224,102,2,223,223,1006,224,404,101,1,223,223,1008,226,226,224,1002,223,2,223,1006,224,419,101,1,223,223,108,677,226,224,1002,223,2,223,1006,224,434,101,1,223,223,1108,677,226,224,102,2,223,223,1005,224,449,101,1,223,223,1008,677,226,224,102,2,223,223,1006,224,464,1001,223,1,223,108,677,677,224,102,2,223,223,1005,224,479,101,1,223,223,7,677,677,224,102,2,223,223,1005,224,494,1001,223,1,223,8,226,677,224,102,2,223,223,1006,224,509,101,1,223,223,107,677,226,224,1002,223,2,223,1005,224,524,1001,223,1,223,7,677,226,224,1002,223,2,223,1005,224,539,1001,223,1,223,1007,226,677,224,1002,223,2,223,1005,224,554,1001,223,1,223,8,677,677,224,102,2,223,223,1006,224,569,101,1,223,223,7,226,677,224,102,2,223,223,1006,224,584,1001,223,1,223,1008,677,677,224,102,2,223,223,1005,224,599,101,1,223,223,1007,677,677,224,1002,223,2,223,1006,224,614,101,1,223,223,1107,677,226,224,1002,223,2,223,1006,224,629,101,1,223,223,1107,226,677,224,1002,223,2,223,1006,224,644,101,1,223,223,1007,226,226,224,102,2,223,223,1005,224,659,1001,223,1,223,108,226,226,224,102,2,223,223,1006,224,674,101,1,223,223,4,223,99,226])
class OpCode:
def __init__(self, opCode):
self.code = opCode[-2:]
self.parameterModes = opCode[:(len(opCode)-2)][::-1]
def getOpCode(self):
return self.code
def getParameterModeFromPosition(self, pos):
try:
return self.parameterModes[pos]
except IndexError:
return '0'
class Instruction():
def __init__(self, opCode, parameters, rotationAmount, program):
self.opCode = opCode
self.parameters = parameters
self.rotationAmount = rotationAmount
self.program = program
def getValueOrImmediate(self, pm, paramPos, programState):
if pm == '0':
return programState[int(self.parameters[int(paramPos)])]
elif pm == '1':
return self.parameters[int(paramPos)]
@abstractmethod
def runInstruction(self):
pass
class AddInstruction(Instruction):
def runInstruction(self):
d = deque(self.program)
d.rotate(abs(self.rotationAmount))
v1 = self.getValueOrImmediate(self.opCode.getParameterModeFromPosition(0), 0, d)
v2 = self.getValueOrImmediate(self.opCode.getParameterModeFromPosition(1), 1, d)
writeTo = int(self.parameters[2])
d[writeTo] = str(int(v1) + int(v2))
d.rotate(self.rotationAmount - 4)
return d
class MultiplyInstruction(Instruction):
def runInstruction(self):
d = deque(self.program)
d.rotate(abs(self.rotationAmount))
v1 = self.getValueOrImmediate(self.opCode.getParameterModeFromPosition(0), 0, d)
v2 = self.getValueOrImmediate(self.opCode.getParameterModeFromPosition(1), 1, d)
writeTo = int(self.parameters[2])
d[writeTo] = str(int(v1) * int(v2))
d.rotate(self.rotationAmount - 4)
return d
class InputInstruction(Instruction):
def runInstruction(self):
d = deque(self.program)
d.rotate(abs(self.rotationAmount))
writeTo = self.parameters[0]
inp = input("Input a value: ")
d[int(writeTo)] = str(inp)
d.rotate(self.rotationAmount - 2)
return d
class OutputInstruction(Instruction):
def runInstruction(self):
d = deque(self.program)
d.rotate(abs(self.rotationAmount))
readFrom = self.parameters[0]
print d[int(readFrom)]
d.rotate(self.rotationAmount - 2)
return d
class JumpIfTrue(Instruction):
def runInstruction(self):
d = deque(self.program)
d.rotate(abs(self.rotationAmount))
v1 = self.getValueOrImmediate(self.opCode.getParameterModeFromPosition(0), 0, d)
v2 = self.getValueOrImmediate(self.opCode.getParameterModeFromPosition(1), 1, d)
if int(v1) <> 0:
d.rotate(-int(v2))
return (d, ('set', -int(v2)))
else:
d.rotate(self.rotationAmount - 3)
return (d, (None, None))
class JumpIfFalse(Instruction):
def runInstruction(self):
d = deque(self.program)
d.rotate(abs(self.rotationAmount))
v1 = self.getValueOrImmediate(self.opCode.getParameterModeFromPosition(0), 0, d)
v2 = self.getValueOrImmediate(self.opCode.getParameterModeFromPosition(1), 1, d)
if int(v1) == 0:
d.rotate(-int(v2))
return (d, ('set', -int(v2)))
else:
d.rotate(self.rotationAmount - 3)
return (d, (None, None))
class LessThan(Instruction):
def runInstruction(self):
d = deque(self.program)
d.rotate(abs(self.rotationAmount))
v1 = self.getValueOrImmediate(self.opCode.getParameterModeFromPosition(0), 0, d)
v2 = self.getValueOrImmediate(self.opCode.getParameterModeFromPosition(1), 1, d)
v3 = self.parameters[2]
if int(v1) < int(v2):
d[int(v3)] = 1
else:
d[int(v3)] = 0
d.rotate(self.rotationAmount - 4)
return d
class Equals(Instruction):
def runInstruction(self):
d = deque(self.program)
d.rotate(abs(self.rotationAmount))
v1 = self.getValueOrImmediate(self.opCode.getParameterModeFromPosition(0), 0, d)
v2 = self.getValueOrImmediate(self.opCode.getParameterModeFromPosition(1), 1, d)
v3 = self.parameters[2]
if int(v1) == int(v2):
d[int(v3)] = 1
else:
d[int(v3)] = 0
d.rotate(self.rotationAmount - 4)
return d
def solve(program):
rotationAmount = 0
while program[0] <> '99':
oc = OpCode(program[0])
if oc.getOpCode() == '01' or oc.getOpCode() == '1':
p = list(program)
i = AddInstruction(oc, p[1:4], rotationAmount, program)
program = i.runInstruction()
rotationAmount -= 4
elif oc.getOpCode() == '02' or oc.getOpCode() == '2':
p = list(program)
i = MultiplyInstruction(oc, p[1:4], rotationAmount, program)
program = i.runInstruction()
rotationAmount -= 4
elif oc.getOpCode() == '03' or oc.getOpCode() == '3':
p = list(program)
i = InputInstruction(oc, p[1:2], rotationAmount, program)
program = i.runInstruction()
rotationAmount -= 2
elif oc.getOpCode() == '04' or oc.getOpCode() == '4':
p = list(program)
i = OutputInstruction(oc, p[1:2], rotationAmount, program)
program = deque(i.runInstruction())
rotationAmount -= 2
elif oc.getOpCode() == '05' or oc.getOpCode() == '5':
p = list(program)
i = JumpIfTrue(oc, p[1:3], rotationAmount, program)
(np, rotationInfo) = deque(i.runInstruction())
program = np
(toSet, amount) = rotationInfo
if toSet == 'set':
rotationAmount = amount
else:
rotationAmount -= 3
elif oc.getOpCode() == '06' or oc.getOpCode() == '6':
p = list(program)
i = JumpIfFalse(oc, p[1:3], rotationAmount, program)
(np, rotationInfo) = deque(i.runInstruction())
program = np
(toSet, amount) = rotationInfo
if toSet == 'set':
rotationAmount = amount
else:
rotationAmount -= 3
elif oc.getOpCode() == '07' or oc.getOpCode() == '7':
p = list(program)
i = LessThan(oc, p[1:4], rotationAmount, program)
program = i.runInstruction()
rotationAmount -= 4
elif oc.getOpCode() == '08' or oc.getOpCode() == '8':
p = list(program)
i = Equals(oc, p[1:4], rotationAmount, program)
program = i.runInstruction()
rotationAmount -= 4
print 'Program Done!'
if __name__ == '__main__':
program = map(str, puzzle_input)
solve(deque(program))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment