# # The arcade cabinet runs Intcode software like the game the Elves sent (your puzzle input). It has a primitive screen capable of drawing square tiles on a grid. The software draws tiles to the screen with output instructions: every three output instructions specify the x position (distance from the left), y position (distance from the top), and tile id. The tile id is interpreted as follows: # # 0 is an empty tile. No game object appears in this tile. # 1 is a wall tile. Walls are indestructible barriers. # 2 is a block tile. Blocks can be broken by the ball. # 3 is a horizontal paddle tile. The paddle is indestructible. # 4 is a ball tile. The ball moves diagonally and bounces off objects. # # For example, a sequence of output values like 1,2,3,6,5,4 would draw a horizontal paddle tile (1 tile from the left and 2 tiles from the top) and a ball tile (6 tiles from the left and 5 tiles from the top). # # Start the game. How many block tiles are on the screen when the game exits? the_input = list(map(int, read_input("day13", ","))) comp = IntcodeComputer(the_input) comp.run() block_count = comp.output_list[2::3].count(2) print("Part one:", block_count) # --- Part Two --- # # The game didn't run because you didn't put in any quarters. Unfortunately, you did not bring any quarters. Memory address 0 represents the number of quarters that have been inserted; set it to 2 to play for free. # # The arcade cabinet has a joystick that can move left and right. The software reads the position of the joystick with input instructions: # # If the joystick is in the neutral position, provide 0. # If the joystick is tilted to the left, provide -1. # If the joystick is tilted to the right, provide 1. # # The arcade cabinet also has a segment display capable of showing a single number that represents the player's current score. When three output instructions specify X=-1, Y=0, the third output instruction is not a tile; the value instead specifies the new score to show in the segment display. For example, a sequence of output values like -1,0,12345 would show 12345 as the player's current score.
# ................. # .....@........... # #####.########### # # ................. # ................. # ................. # #####@########### # # However, if the springdroid successfully makes it across, it will use an output instruction to indicate the amount of damage to the hull as a single giant integer outside the normal ASCII range. # # Program the springdroid with logic that allows it to survey the hull without falling into space. What amount of hull damage does it report? if __name__ == '__main__': mem = list(map(int, util.read_input("day21", ","))) comp = IntcodeComputer(mem) program = """NOT A J NOT C T AND D T OR T J WALK """ compiled = list(map(lambda c: ord(c), program)) comp.run(compiled) result = "".join( list(map(lambda o: chr(o) if o < 127 else str(o), comp.output_list))) print(result)
# # # Then, perhaps west (3) gets a reply of 0, south (2) gets a reply of 1, south again (2) gets a reply of 0, and then west (3) gets a reply of 2: # # # ## # #..# # D.# # # # # Now, because of the reply of 2, you know you've found the oxygen system! In this example, it was only 2 moves away from the repair droid's starting position. # # What is the fewest number of movement commands required to move the repair droid from its starting position to the location of the oxygen system? program = list(map(int, read_input("day15", ","))) droid_computer = IntcodeComputer(program) area_map = Map() droid_location = Location(0, 0) area_map.set(0, 0, empty) droid_on_target = bfs(Droid(droid_computer, droid_location)) # --- Part Two --- # # You quickly repair the oxygen system; oxygen gradually fills the area. # # Oxygen starts in the location containing the repaired oxygen system. It takes one minute for oxygen to spread to all open locations that are adjacent to a location that already contains oxygen. Diagonal locations are not adjacent. # # In the example above, suppose you've used the droid to explore the area fully and have the following map (where locations that currently contain oxygen are marked O): # # ##
# For these intersections: # # The top-left intersection is 2 units from the left of the image and 2 units from the top of the image, so its alignment parameter is 2 * 2 = 4. # The bottom-left intersection is 2 units from the left and 4 units from the top, so its alignment parameter is 2 * 4 = 8. # The bottom-middle intersection is 6 from the left and 4 from the top, so its alignment parameter is 24. # The bottom-right intersection's alignment parameter is 40. # # To calibrate the cameras, you need the sum of the alignment parameters. In the above example, this is 76. # # Run your ASCII program. What is the sum of the alignment parameters for the scaffold intersections? SCAFFOLDING = "#" program = list(map(int, read_input("day17", ","))) computer = IntcodeComputer(program) computer.run() output = ''.join(list(map(chr, computer.output_list))) elements = list(map(list, output.split("\n"))) matrix = Matrix() matrix.init_from_values(elements) # matrix.print_top_left(print_headers=True) x_points = 0 for x, y in matrix.index_range(): if 0 < x < matrix.width and 0 < y < matrix.height and matrix.get(x, y) == SCAFFOLDING: if matrix.get(x - 1, y) == SCAFFOLDING and \ matrix.get(x + 1, y) == SCAFFOLDING and \ matrix.get(x, y - 1) == SCAFFOLDING and \ matrix.get(x, y + 1) == SCAFFOLDING: x_points += x * y
# # The robot is now back where it started, but because it is now on a white panel, input instructions should be provided 1. After several more outputs (0,1, 1,0, 1,0), the area looks like this: # # ..... # ..<#. # ...#. # .##.. # ..... # # Before you deploy the robot, you should probably have an estimate of the area it will cover: specifically, you need to know the number of panels it paints at least once, regardless of color. In the example above, the robot painted 6 panels at least once. (It painted its starting panel twice, but that panel is still only counted once; it also never painted the panel it ended on.) # # Build a new emergency hull painting robot and run the Intcode program on it. How many panels does it paint at least once? input_1 = list(map(int, util.read_input("day11", ","))) comp = IntcodeComputer(input_1) robot = EmergencyHullPaintingRobot(comp) robot.run() print("Part One:", robot.count_painter_tiles()) # --- Part Two --- # # You're not sure what it's trying to paint, but it's definitely not a registration identifier. The Space Police are getting impatient. # # Checking your external ship cameras again, you notice a white panel marked "emergency hull painting robot starting panel". The rest of the panels are still black, but it looks like the robot was expecting to start on a white panel, not a black one. # # Based on the Space Law Space Brochure that the Space Police attached to one of your windows, a valid registration identifier is always eight capital letters. After starting the robot on a single white panel instead, what registration identifier does it paint on your hull? # # Although it hasn't changed, you can still get your puzzle input. comp = IntcodeComputer(input_1)
def run_program(mem, x, y): comp = IntcodeComputer(mem) comp.run([x, y]) return comp.output_list[-1]
def run_program(x, y): comp = IntcodeComputer(the_input) comp.run([x, y]) return comp.output_list[-1]