def puzzle_1(data): machine = IntCode(data) command = [] # x __# # abcd # !B && !C && D # Jump, if there is a two-space gap with ground afterwards command.append("NOT B T") command.append("NOT C J") command.append("AND T J") command.append("AND D J") # x_ # Always jump, if we have to (A is a gap) command.append("NOT A T") command.append("OR T J") # x _# # !C && D # Whatever... works. Like the first one, but ignoring B. Don't ask. command.append("NOT C T") command.append("AND D T") command.append("OR T J") for c in command: machine.set_inputs(list(map(ord, c + "\n"))) machine.set_inputs(list(map(ord, "WALK\n"))) outputs = machine.get_outputs() # Print output from IntCode machine. This also gives nices images when the puzzle fails #print("".join(list(map(chr, outputs[:-1])))) return outputs[-1]
def run_intcode(data, id, other_input_queues, stop_queue, nat_queue): m = IntCode(data) in_queue = other_input_queues[id] m.set_input(id) m.set_input(-1) while True: if not stop_queue.empty(): return while not in_queue.empty(): in_data = in_queue.get() m.set_inputs([in_data[0], in_data[1]]) out = m.get_outputs() if len(out) > 0: for oi in range(len(out) // 3): if out[oi * 3] == 255: nat_queue.put((out[oi * 3 + 1], out[oi * 3 + 2])) else: # directly feeds the correct input queue with data! other_input_queues[out[oi * 3]].put( (out[oi * 3 + 1], out[oi * 3 + 2]))
def try_beam_count(y): dx = 0 dy = y last_value = 0 beam_cnt = 0 while True: machine = IntCode(data) machine.set_inputs([dx, dy]) beam = machine.get_outputs()[0] if beam == 0 and last_value == 1: return first_x, dy + 1, beam_cnt if beam == 1 and last_value == 0: first_x = dx beam_cnt += beam last_value = beam dx += 1 dy -= 1 return 0, 0, 0
def puzzle_2(data): machine = IntCode(data) command = [] # x # # abcdefghi # H || E && I || E && F # Either the second jump works right away, or we can go one step and then jump, or we can just continue walking with # no second jump (At least for two further steps. We deal with what comes after walking/jumping for a bit). command.append("OR E T") command.append("AND F T") command.append("OR E J") command.append("AND I J") command.append("OR T J") command.append("OR H J") # !A || !B || !C # Don't jump, if there is nothing to jump over! command.append("NOT A T") command.append("NOT T T") command.append("AND B T") command.append("AND C T") command.append("NOT T T") # combine command.append("AND T J") # D # Immediate jump location MUST be ground! command.append("AND D J") for c in command: machine.set_inputs(list(map(ord, c + "\n"))) machine.set_inputs(list(map(ord, "RUN\n"))) outputs = machine.get_outputs() # Print output from IntCode machine. This also gives nices images when the puzzle fails #print("".join(list(map(chr, outputs[:-1])))) return outputs[-1]
22201, -4, -1, 1, 22101, 0, -2, 3, 21102, 343, 1, 0, 1105, 1, 303, 1106, 0, 415, 22207, -2, -3, -1, 1206, -1, 387, 22201, -3, -2, -3, 21202, -2, -1, -1, 22201, -3, -1, 3, 21202, 3, -1, -1, 22201, -3, -1, 2, 21201, -4, 0, 1, 21101, 0, 384, 0, 1105, 1, 303, 1106, 0, 415, 21202, -4, -1, -4, 22201, -4, -3, -4, 22202, -3, -2, -2, 22202, -2, -4, -4, 22202, -3, -2, -3, 21202, -4, -1, -2, 22201, -3, -2, 1, 21201, 1, 0, -4, 109, -5, 2106, 0, 0 ] field = defaultdict(int) for y in range(50): for x in range(50): machine = IntCode(data) machine.set_inputs([x, y]) beam = machine.get_outputs()[0] field[(x, y)] = beam # solution for puzzle 1 print(sum(field.values())) #draw(field) x = y = 0 # just make it kinda large. diff = 2000 while True: p_x, p_y, cnt = try_beam_count(y) if cnt > 100: diff //= 2 y -= diff
22201, -4, -2, -4, 109, -5, 2106, 0, 0 ] machine = IntCode(data) painted_color = defaultdict(int) pos = (0, 0) direction = (0, 1) # for puzzle 2: painted_color[pos] = 1 while not machine.is_finished(): machine.set_inputs([painted_color[pos]]) out = machine.get_outputs() painted_color[(pos)] = out[0] direction = rotate(direction, not out[1]) pos = (pos[0] + direction[0], pos[1] + direction[1]) # Output for puzzle 1: print(len(painted_color)) min_x = min(painted_color.keys(), key=lambda x: x[0])[0] max_x = max(painted_color.keys(), key=lambda x: x[0])[0] min_y = min(painted_color.keys(), key=lambda x: x[1])[1] max_y = max(painted_color.keys(), key=lambda x: x[1])[1] # Output for puzzle 2:
12, 87, 77, 89, 7, 25, 21, 68, 48, 23, 1, 48, 21, 79, 66, 38, 16, 26, 86, 46, 74, 24, 68, 94, 43, 78, 73, 72, 5, 73, 8, 60, 95, 76, 40, 62, 57, 56, 59, 22, 82, 32, 43, 22, 83, 85, 13, 5, 12, 37, 31, 39, 25, 43, 46, 75, 5, 84, 52, 36, 25, 80, 65, 10, 4, 71, 11, 9, 68, 50, 38, 97, 33, 93, 83, 45, 60, 86, 8, 56, 55, 24, 73, 90, 24, 30, 96, 68, 70, 16, 56, 30, 61, 13, 38, 76, 21, 27, 66, 70, 82, 87, 45, 39, 51, 57, 62, 9, 47, 44, 37, 82, 49, 41, 17, 13, 68, 42, 49, 87, 52, 37, 6, 12, 74, 5, 37, 43, 79, 25, 85, 18, 39, 56, 37, 67, 34, 82, 71, 91, 54, 40, 16, 10, 51, 7, 22, 83, 31, 72, 46, 74, 29, 13, 40, 57, 85, 94, 40, 33, 10, 25, 9, 61, 87, 30, 44, 78, 23, 41, 35, 36, 30, 23, 96, 27, 10, 25, 32, 55, 25, 15, 70, 39, 90, 38, 8, 561969 ] data[0] = 2 game = IntCode(data) states = game.get_outputs() field = dict() ball_pos_x = 0 last_js_x = 0 # build up the game for s in split(states, 3): if s[2] == 4: ball_pos_x = s[0] elif s[2] == 3: last_js_x = s[0] field[(s[0], s[1])] = s[2]
23, 1, 18, 1, 23, 1, 18, 1, 23, 1, 10, 7, 1, 1, 19, 9, 6, 1, 5, 1, 1, 1, 19, 1, 3, 1, 3, 1, 6, 1, 5, 1, 1, 5, 15, 1, 3, 1, 3, 1, 6, 1, 5, 1, 5, 1, 15, 1, 3, 1, 3, 1, 6, 11, 1, 1, 1, 7, 3, 5, 3, 11, 6, 1, 3, 1, 1, 1, 1, 1, 9, 1, 11, 1, 5, 1, 6, 1, 1, 9, 7, 1, 11, 1, 5, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 1, 11, 1, 5, 1, 6, 9, 1, 9, 11, 7, 8, 1, 1, 1, 1, 1, 3, 1, 30, 9, 3, 1, 30, 1, 3, 1, 1, 1, 5, 1, 30, 1, 3, 1, 1, 7, 30, 1, 3, 1, 38, 1, 3, 1, 38, 1, 3, 1, 38, 5, 34 ] data[0] = 2 machine = IntCode(data) field = defaultdict(int) x = y = 0 hoover = (0, 0) for c in machine.get_outputs(): if c == 10: y += 1 x = 0 continue if chr(c) in "<>v^": hoover = (x, y) if chr(c) in "<>v^#": field[(x, y)] = c x += 1 #draw(field, {-1: " ", ord("#"): "█", ord("^"): "^"}) # solution for puzzle 1:
755, 4, 739, 1001, 64, 1, 64, 1105, 1, 755, 1002, 64, 2, 64, 109, 2, 21101, 47, 0, -2, 1008, 1013, 47, 63, 1005, 63, 777, 4, 761, 1106, 0, 781, 1001, 64, 1, 64, 1002, 64, 2, 64, 109, 10, 1205, -5, 793, 1106, 0, 799, 4, 787, 1001, 64, 1, 64, 1002, 64, 2, 64, 109, -1, 2105, 1, -1, 1001, 64, 1, 64, 1105, 1, 817, 4, 805, 1002, 64, 2, 64, 109, 9, 2105, 1, -9, 4, 823, 1001, 64, 1, 64, 1105, 1, 835, 1002, 64, 2, 64, 109, -36, 2108, 38, 7, 63, 1005, 63, 855, 1001, 64, 1, 64, 1106, 0, 857, 4, 841, 1002, 64, 2, 64, 109, 13, 2102, 1, -6, 63, 1008, 63, 36, 63, 1005, 63, 879, 4, 863, 1106, 0, 883, 1001, 64, 1, 64, 1002, 64, 2, 64, 109, 10, 2106, 0, 8, 4, 889, 1105, 1, 901, 1001, 64, 1, 64, 4, 64, 99, 21101, 0, 27, 1, 21101, 915, 0, 0, 1106, 0, 922, 21201, 1, 49329, 1, 204, 1, 99, 109, 3, 1207, -2, 3, 63, 1005, 63, 964, 21201, -2, -1, 1, 21102, 1, 942, 0, 1105, 1, 922, 21201, 1, 0, -1, 21201, -2, -3, 1, 21102, 957, 1, 0, 1106, 0, 922, 22201, 1, -1, -2, 1105, 1, 968, 22102, 1, -2, -2, 109, -3, 2105, 1, 0 ] #data = [109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99] #data = [104,1125899906842624,99] #data = [1102,34915192,34915192,7,4,7,99,0] ic = IntCode(data) ic.set_inputs([1]) print(ic.get_outputs()) ic2 = IntCode(data) ic2.set_inputs([2]) print(ic2.get_outputs()) # solution for 09.01: 2457252183 # solution for 09.02: 70634