Advent of Code - Day 2
Advent of Code day 2 was a fun one. The explanation for part two took me a whie to wrap my head around,but once I did, the rest was pretty straightforward.
Though I did an ok job, at first. Refactored 3 or 4 times to come up with something that I’m mostly happy with.
Got my gold stars, then checked out reddit for other solutions.
Wow. After looking at a few great answers - I overengineered the shit out of this. I wasn’t going for speed, so I could afford to write some seriously verbose code.
Since it’s so large, it’s probably hard to read. I’ve included a link to the notebook that I used to work through this problem if that’s easier to read.
Either way, here’s the code in it’s entirety.
My Solution
unique_intcode = '1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,10,19,1,19,5,23,2,23,9,27,1,5,27,31,1,9,31,35,1,35,10,39,2,13,39,43,1,43,9,47,1,47,9,51,1,6,51,55,1,13,55,59,1,59,13,63,1,13,63,67,1,6,67,71,1,71,13,75,2,10,75,79,1,13,79,83,1,83,10,87,2,9,87,91,1,6,91,95,1,9,95,99,2,99,10,103,1,103,5,107,2,6,107,111,1,111,6,115,1,9,115,119,1,9,119,123,2,10,123,127,1,127,5,131,2,6,131,135,1,135,5,139,1,9,139,143,2,143,13,147,1,9,147,151,1,151,2,155,1,9,155,0,99,2,0,14,0'
class Intcode:
def __init__(self, raw_intcode, noun=12, verb=2):
self.active = True
self.__raw_intcode = raw_intcode
self.__parsed_intcode = self._pre_process_intcode(
self._parse_raw_intcode(raw_intcode),
noun=noun,
verb=verb
)
self.__data = self._process_intcode(
self.__parsed_intcode.copy(),
silent=False
)
# PUBLIC
def find_noun_and_verb(self, value=19690720):
for noun in range(100):
for verb in range(100):
# Reset the computer's memory each time a new pair is tried
memory = self.__parsed_intcode.copy()
memory[1] = noun
memory[2] = verb
memory = self._process_intcode(memory, silent=True)
if memory[0] == value:
print('noun is {}'.format(noun))
print('verb is {}'.format(verb))
# PRIVATE
def _preprocess_intcode(self, intcode, noun, verb):
new_intcode = intcode.copy()
new_intcode[1] = noun
new_intcode[2] = verb
return new_intcode
def _parse_raw_intcode(self, raw_intcode):
return list(map(int, raw_intcode.split(',')))
def _process_intcode(self, memory, silent=False):
self.active = True
instruction_length = 4
ip = 0
while self.active:
valid_opcode = Opcode(memory[ip])
if valid_opcode.value == 99:
self._terminate(silent=silent)
elif valid_opcode.value == 1:
# get instruction
opcode, *parameters = memory[ip:ip+instruction_length]
# execute instruction
addr_a, addr_b, output_addr = parameters
memory[output_addr] = memory[addr_a] + memory[addr_b]
# increment instruction pointer
ip += instruction_length
elif valid_opcode.value == 2:
# get instruction
opcode, *parameters = memory[ip:ip+instruction_length]
# mult the two address values into the output address
addr_a, addr_b, output_addr = parameters
memory[output_addr] = memory[addr_a] * memory[addr_b]
# increment instruction pointer
ip += instruction_length
else:
self.active = False
raise ValueError('Something went wrong.')
return memory
def _terminate(self, silent=False):
if self.active:
if not silent:
print('---- completed intcode processing ----')
self.active = False
# PROPERTIES
@property
def result(self):
return ','.join([str(i) for i in self.__data])
@property
def raw_intcode(self):
return self.__raw_intcode
@property
def parsed_intcode(self):
return self.__parsed_intcode
class Opcode:
def __init__(self, opcode):
self.__opcode = opcode
valid_opcodes = [1, 2, 99]
if opcode not in valid_opcodes:
raise ValueError('Incorrect opcode: {}. Must be one of {}'.format(opcode, valid_opcodes))
@property
def value(self):
return self.__opcode
Tags:
Conditional Probability and the Monty Hall Game
Plaid Inspired Inputs with React Hooks and Styled Components