Example #1
0
class Arcade:
    """ Executes the given intcode program, to play a game"""
    def __init__(self, intcode: List[int]):
        self.intcode = intcode
        self.current_position = (0, 0)
        self.screen = defaultdict(int)
        self.intcode_computer = IntcodeComputer(intcode, self.get_input,
                                                self.generate_output)
        self.offset = 0
        self.score = 0

    def get_input(self):
        return 0

    def generate_output(self, value: int):
        if self.offset == 0:
            self.x = value
            self.offset += 1
        elif self.offset == 1:
            self.y = value
            self.offset += 1
        elif self.offset == 2:
            if self.x == -1 and self.y == 0:
                logging.warning(f"Setting score to {value}")
                self.score = value
            else:
                logging.warning(
                    f"Setting tile in {self.x},{self.y} with {value}")
                self.screen[(self.x, self.y)] = value
            self.offset = 0

    def execute(self):
        self.intcode_computer.execute()
Example #2
0
class PaintingRobot:
    """ Executes the given intcode program, painting tiles based on its output"""
    def __init__(self, intcode: List[int]):
        self.intcode = intcode
        self.current_position = (0, 0)
        self.orientation = (0, 1)
        self.painting_area = defaultdict(int)
        self.intcode_computer = IntcodeComputer(intcode, self.get_input,
                                                self.generate_output)
        self.waiting_for_direction = False

    def get_input(self):
        logging.info(
            f"Reading tile {self.current_position} with color {self.painting_area[self.current_position]}"
        )
        return self.painting_area[self.current_position]

    def generate_output(self, x: int):
        if self.waiting_for_direction:
            if x == 0:
                # Turn left 90 degrees
                if self.orientation == (0, 1):
                    self.orientation = (-1, 0)
                elif self.orientation == (-1, 0):
                    self.orientation = (0, -1)
                elif self.orientation == (0, -1):
                    self.orientation = (1, 0)
                elif self.orientation == (1, 0):
                    self.orientation = (0, 1)
            else:
                if self.orientation == (0, 1):
                    self.orientation = (1, 0)
                elif self.orientation == (-1, 0):
                    self.orientation = (0, 1)
                elif self.orientation == (0, -1):
                    self.orientation = (-1, 0)
                elif self.orientation == (1, 0):
                    self.orientation = (0, -1)
            self.current_position = (self.current_position[0] +
                                     self.orientation[0],
                                     self.current_position[1] +
                                     self.orientation[1])
            self.waiting_for_direction = False
            logging.info(
                f"Updated orientation to  {self.orientation} and position to  {self.current_position}"
            )
        else:
            logging.info(f"Painting {self.current_position} with {x}")
            self.painting_area[self.current_position] = x
            self.waiting_for_direction = True

    def execute(self):
        self.intcode_computer.execute()
Example #3
0
class Robot():
    move = {
        direction.UP    : lambda c : (c[0],c[1]+1),
        direction.DOWN  : lambda c : (c[0],c[1]-1),
        direction.LEFT  : lambda c : (c[0]-1,c[1]),
        direction.RIGHT : lambda c : (c[0]+1,c[1]),
    }

    def __init__(self, prog):
        self.p    = direction.UP # pointing
        self.loc  = (0,0)
        self.grid = {}

        self.grid[self.loc] = 1

        self.brain   = IntcodeComputer([], prog)
        self.painted = []

        self.paint()

    def rotate(self, by):
        if self.p == direction.UP:
            self.p = direction.LEFT if by == 0 else direction.RIGHT
        elif self.p == direction.DOWN:
            self.p = direction.RIGHT if by == 0 else direction.LEFT
        elif self.p == direction.RIGHT:
            self.p = direction.UP if by == 0 else direction.DOWN
        elif self.p == direction.LEFT:
            self.p = direction.DOWN if by == 0 else direction.UP

    def paint(self):
        while(True):
            try:
                col = self.grid[self.loc]
            except:
                col = 0
                self.grid[self.loc] = col

            self.brain.outputs  = []
            self.brain.input = [col]*100000
            self.brain.execute()

            if len(self.brain.outputs) > 0:
                paint, turn = self.brain.outputs[0], self.brain.outputs[1]
                #print(paint, turn)
                self.grid[self.loc] = paint
                self.painted.append(self.loc)
                self.rotate(turn)
                self.loc = self.move[self.p](self.loc)
            else:
                break
Example #4
0
class PaintingRobot:
    """ Executes the given intcode program, painting tiles based on its output"""
    def __init__(self, intcode: List[int]):
        self.intcode = intcode
        self.current_position = (0, 0)
        self.orientation = (0, 1)
        self.painting_area = defaultdict(int)
        self.painting_area[self.current_position] = 1
        self.intcode_computer = IntcodeComputer(intcode, self.get_input,
                                                self.generate_output)
        self.waiting_for_direction = False

    def get_input(self):
        logging.info(
            f"Reading tile {self.current_position} with color {self.painting_area[self.current_position]}"
        )
        return self.painting_area[self.current_position]

    def update_orientation(self, turn_to: int):
        x, y = self.orientation
        # Change sign if x=0 and have to turn left, or if x=1 and have to turn right
        sign = -1 if abs(x) == turn_to else 1
        self.orientation = (sign * y, sign * x)

    def generate_output(self, value: int):
        if self.waiting_for_direction:
            self.update_orientation(value)
            ox, oy, x, y = (*self.orientation, *self.current_position)
            self.current_position = (x + ox, y + oy)
            self.waiting_for_direction = False
            logging.info(
                f"Updated orientation to  {self.orientation} and position to  {self.current_position}"
            )
        else:
            logging.info(f"Painting {self.current_position} with {value}")
            self.painting_area[self.current_position] = value
            self.waiting_for_direction = True

    def execute(self):
        self.intcode_computer.execute()
Example #5
0
async def part2():
    input = asyncio.Queue()
    output = asyncio.Queue()
    computer = IntcodeComputer('day17.txt', input, output)
    computer._state._memory[0] = 2

    tasks = [
        asyncio.create_task(inout_handler(input, output)),
        asyncio.create_task(computer.execute())
    ]
    await asyncio.gather(*tasks)

    print('Part 2 complete')
Example #6
0
class Amplifier:
    """ Executes the given intcode program, adjusted by the phase and initial signal value provided

    It will read further required inputs from input_signal, and output any generated signal to 
    output_signal
    """
    def __init__(self,
                 id: int,
                 intcode: List[int],
                 phase: int,
                 initial_signal_value: int = None,
                 input_queue=None,
                 output_queue=None):
        self.intcode = intcode
        self.id = id
        self.phase = phase
        self.input_queue = input_queue
        self.input_queue.put(phase)
        if initial_signal_value != None:
            self.input_queue.put(initial_signal_value)
        self.output_queue = output_queue
        self.intcode_computer = IntcodeComputer(intcode, self.get_input,
                                                self.generate_output)

    def get_input(self):
        value = self.input_queue.get()
        logging.info(f"Got {value} value from queue in amplifier {self.id}")
        return value

    def generate_output(self, x: int):
        self.last_value = x
        self.output_queue.put(x)

    def execute(self):
        logging.info(f"Starting amplifier with phase {self.phase}")
        self.intcode_computer.execute()
Example #7
0
    # Part 1
    computer.run(program_code, inputs)
    outputs = computer.outputs
    tiles = process_outputs(outputs)
    num_blocks = sum([1 for x in tiles if x[2] == 2])
    print('Num blocks:', num_blocks)
    assert num_blocks == 344

    # Part 2
    program_code[0] = 2
    computer.initialize(program_code, inputs)

    score = 0
    while True:
        computer.reset_outputs()
        done = computer.execute()
        outputs = computer.outputs
        if not render:
            print('outputs', outputs)

        tiles = process_outputs(outputs)

        for x, y, id in tiles:
            if x == -1 and y == 0:
                score = id
                if score > 0:
                    num_blocks -= 1
                if not render:
                    print('Display score:', score, '- Remaining blocks:', num_blocks)
            if id == 3:
                x_paddle = x
Example #8
0
class NetworkComputer:
    """ Executes the given intcode program, to act as a Network computer"""
    def __init__(self, _id: int, intcode: List[int], queues: List[queue.Queue],
                 nat_queue: queue.Queue):
        self.intcode = intcode
        self.id = _id
        self.network_address = -1
        self.queue_list = queues
        self.nat_queue = nat_queue
        self.intcode_computer = IntcodeComputer(intcode, self.get_input,
                                                self.generate_output)
        self.next_output = 0
        self.current_incoming_packet = None
        self.current_outgoing_packet = None
        self.send_to_address = None
        self.waiting_input = False

    def get_input(self):
        if self.network_address < 0:
            self.network_address = self.id
            print(
                f"Computer {self.id} got network adress {self.network_address}"
            )
            return self.network_address
        if self.current_incoming_packet:
            value = self.current_incoming_packet.pop()
            print(f"Computer {self.id} getting {value} from existing packet")
            return value
        else:
            try:
                self.current_incoming_packet = self.queue_list[
                    self.id].get_nowait()
                print(
                    f"Computer {self.id} receiving {self.current_incoming_packet}"
                )
                self.waiting_input = False
                return self.current_incoming_packet.pop()
            except:
                self.waiting_input = True
                return -1

    def generate_output(self, value: int):
        self.waiting_input = False
        if self.next_output == 0:
            self.send_to_address = value
            self.next_output += 1
        elif self.next_output == 1:
            self.current_outgoing_packet = [value]
            self.next_output += 1
        elif self.next_output == 2:
            self.current_outgoing_packet.append(value)
            to_send = list(reversed(self.current_outgoing_packet))
            if self.send_to_address == 255:
                print(f"**** Sending {to_send} to NAT ****")
                self.nat_queue.put_nowait(to_send)
            else:
                print(
                    f"Computer {self.id} sending {to_send} to address {self.send_to_address}"
                )
                self.queue_list[self.send_to_address].put_nowait(to_send)
            self.next_output = 0

    def execute(self):
        print(f"Computer {self.id} starting...")
        self.intcode_computer = IntcodeComputer(self.intcode, self.get_input,
                                                self.generate_output)
        self.intcode_computer.execute()
Example #9
0
    items = [
        'boulder', 'shell', 'mug', 'hypercube', 'space law space brochure',
        'festive hat', 'astronaut ice cream', 'whirled peas'
    ]

    for i in reversed(range(1, 8)):
        print('\nTesting 8 choose', i, '\n')
        combos = combinations(items, i)
        for combo in list(combos):
            print('Combo:', combo)
            cmds = get_item_cmds(items, combo)
            inputs.clear()
            inputs.extend(get_inputs(cmds))
            computer.reset_outputs()
            computer.execute()
            status_map = process_outputs(computer.outputs)
            text = render(status_map, False)
            if 'lighter' in text:
                print('  lighter')
            if 'heavier' in text:
                print('  heavier')
            if 'ejected back to the checkpoint' not in text:
                print(text)
                exit(0)

# Items in your inventory:
# - hypercube
# - festive hat
# - shell
# - astronaut ice cream
Example #10
0
def main(intcode: List[int] = None):
    if not intcode:
        intcode = read_input(input_file=_INPUT_FILE)
    intcode_computer = IntcodeComputer(intcode, lambda: 2,
                                       lambda x: print(f"BOOST keycode: {x}"))
    intcode_computer.execute()
Example #11
0
    linestr = ' '
    i = 0
    for x in range(min_x, max_x):
        if i % 5 == 0:
            linestr = linestr + str(i)
        else:
            linestr = linestr + ' '
        i += 1

    gridstr = gridstr + (linestr + '\n')

    print(gridstr)


brain = IntcodeComputer([], prog)
brain.execute()

j = 0

# ind = 114
inp_seq = [1] + ([0]*45) + [-1,-1] + ([0]*12) + [-1,-1] + ([0]*44)    + [-1,-1,-1,-1] \
        + ([0]*25) + [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]     + ([0]*33)   + [1,1,1,1,1,1,1,1,1,-1,-1,-1] \
        + ([0]*30) + ([1]*15)  + [-1,-1]   + ([0]*30) + ([1]*6)   + ([-1]*6)   + ([-1]*15) + ([0]*5) + ([1]*3) \
        + ([0]*140) + ([1]*8)  + ([0]*50)  + ([1]*2)  + ([0]*10)  +  ([-1]*10) + ([0]*40)  + ([1]*9) +([0]*37) \
        + ([1]*7)  + ([-1]*2)  + ([0]*20)  + ([1]*10) + ([0]*100) + ([-1]*15)  + ([0]*30)  + ([-1]*6) + ([0]*3) + ([1]*3) \
        + ([0]*425) + ([1]*12) + ([0]*120) + ([1]*14) + ([0]*65)  + ([-1]*8)   + ([0]*240) + ([-1]*27) + ([0]*27) + ([1]*35) \
        + [-1]     + ([0]*5)   + ([-1]*33) + ([0]*23) + [1]       + ([0]*26)   + ([1]*33)  + [0]     + [-1] + ([0]*3) + ([-1]*32) + [0] \
        + [-1]     + ([0]*250) + ([1]*22)  + ([0]*8)  + ([-1]*22) + ([0]*10)   + ([1]*22)  + ([0]*5) + ([-1]*22) + ([0]*8) \
        + ([1]*21) + ([0]*50)  + ([-1]*9)  + ([0]*70) + ([1]*12)  + ([0]*25)   + ([-1]*12) + ([0]*3) + ([1]*12) \
        + ([0]*35) + ([-1]*12) + ([0]*10)  + ([1]*12) + ([0]*15)  + ([-1]*12)  + ([0]*20)  + ([1]*12) \
        + ([0]*30) + ([-1]*11) + ([0]*33)  + ([1]*13) + ([0]*54)  + ([-1]*31)  + ([1]*30)  + ([0]*10) \