Esempio n. 1
0
class SpringDroidProgrammer:
    def __init__(self):
        self.ic = Intcode(read_comma_separated_integers('day21input.txt'))
        self.ic.start()

    def read_prompt(self):
        rtn = ''
        ch = self.ic.read_output()
        while ch != 10:
            rtn += chr(ch)
            ch = self.ic.read_output()
        return rtn

    def write_command(self, command):
        for ch in command:
            self.ic.write_input(ord(ch))
        self.ic.write_input(10)

    def read_output(self):
        while not self.ic.finished:
            ch = self.ic.read_output()
            if ch < 256:
                pass
            else:
                return ch

    def program(self, source):
        self.read_prompt()
        for line in source.splitlines():
            if sline := line.strip():
                self.write_command(' '.join(sline.split()))
Esempio n. 2
0
class NetworkInterfaceController:
    def __init__(self, address):
        self.address = address
        self.input_q = deque()
        self._idle_counter = 0
        self.ic = Intcode(read_comma_separated_integers('day23input.txt'))
        self.ic.start()
        self.ic.write_input(address)

    def __repr__(self):
        return f'<NIC {self.address!r}>'

    def communicate(self, network):
        if self.ic.requires_input:
            if self.input_q:
                self.ic.write_input(self.input_q.popleft())
                self._idle_counter = 0
            else:
                self.ic.write_input(-1)
                self._idle_counter += 1
        else:
            # if it is not taking an input, assume it has 3 outputs
            addr = self.ic.read_output()
            x = self.ic.read_output()
            y = self.ic.read_output()
            network.transmit(self.address, addr, x, y)
            self._idle_counter = 0

    def receive(self, x, y):
        self.input_q.append(x)
        self.input_q.append(y)

    def is_idle(self):
        return self._idle_counter > 50
Esempio n. 3
0
class ArcadeCabinet:
    def __init__(self):
        self.ic = Intcode(read_comma_separated_integers('day13input.txt'))
        self.screen = {}
        self.score = 0

    def set_number_of_quarters(self, value):
        self.ic.memory[0] = value

    def read_tile_from_ic(self):
        data = []
        while len(data) < 3 and not self.ic.finished:
            if self.ic.requires_input:
                self.ic.write_input(self.joystick_value)
            else:
                data.append(self.ic.read_output())

        if len(data) == 3:
            return tuple(data)

    def run(self):
        self.ic.start()
        while None is not (tile := self.read_tile_from_ic()):
            x, y, tile_id = tile
            if (x, y) == (-1, 0):
                self.score = tile_id
                continue
            self.screen[(x, y)] = TileId(tile_id)
Esempio n. 4
0
class EmergencyHulPaintingProgram:

    DIRECTIONS = (0, 1), (1, 0), (0, -1), (-1, 0)  # up, right, down, left

    def __init__(self, hul: dict):
        self.ic = Intcode(read_comma_separated_integers('day11input.txt'))
        self.ic.start()

        self.hul = hul
        self.position = 0, 0
        self.direction_index = 0

    def _read_value(self):
        while True:
            if self.ic.requires_input:
                self.ic.write_input(self.hul.get(self.position, 0))
            else:
                return self.ic.read_output()

    def _rotate(self, value):
        rotation = 1 if value else -1
        self.direction_index = (self.direction_index + rotation) % 4
        x, y = self.position
        dx, dy = self.DIRECTIONS[self.direction_index]
        self.position = x + dx, y + dy

    def paint(self):
        while not self.ic.finished:
            color = self._read_value()
            self.hul[self.position] = color
            rotation = self._read_value()
            self._rotate(rotation)
Esempio n. 5
0
    def _test_coordinates(self, x, y):
        assert 0 <= x <= self.max_coord
        assert 0 <= y <= self.max_coord

        ic = Intcode(self.opcodes)
        ic.start()
        ic.write_input(x)
        ic.write_input(y)
        return {1: True, 0: False}[ic.read_output()]
Esempio n. 6
0
def part1(data):
    cpu = Intcode()
    cpu.set_ascii_mode(True)
    cpu.load_program(data)
    while True:
        try:
            cpu.run()
        except KeyboardInterrupt:
            pass
        print(''.join([chr(c) for c in cpu.read_output()]))
Esempio n. 7
0
class DiagnosticProgram:
    def __init__(self):
        self.ic = Intcode(read_comma_separated_integers('day5input.txt'))

    def run(self, system_id):
        self.ic.start()
        self.ic.write_input(system_id)

        while not self.ic.finished:
            yield self.ic.read_output()
Esempio n. 8
0
class BoostProgram:
    def __init__(self):
        self.ic = Intcode(read_comma_separated_integers('day9input.txt'))

    def _read_all(self):
        while not self.ic.finished:
            yield self.ic.read_output()

    def run(self, input_value):
        self.ic.start()
        self.ic.write_input(input_value)
        return list(self._read_all())
Esempio n. 9
0
class AftScaffoldingControlAndInformationInterface:
    def __init__(self, wake_vacuum_robot_up=False):
        opcodes = read_comma_separated_integers('day17input.txt')
        if wake_vacuum_robot_up:
            assert opcodes[0] == 1
            opcodes[0] = 2
        self.ic = Intcode(opcodes)
        self.ic.start()

    def scan_cameras(self):
        line = []
        while True:
            while (ch := self.ic.read_output()) != 10:
                if ch is None:
                    break
                line.append(chr(ch))
            if line:
                yield ''.join(line)
                line = []
            else:
                return
Esempio n. 10
0
class Amplifier:
    def __init__(self, phase_setting):
        self.ic = Intcode(read_comma_separated_integers('day7input.txt'))
        self.ic.start()
        self.ic.write_input(phase_setting)

    def run(self, input_value):
        self.ic.write_input(input_value)
        return self.ic.read_output()

    @property
    def finished(self):
        return self.ic.finished
Esempio n. 11
0
class DroidRemote:
    def __init__(self):
        self.ic = Intcode(read_comma_separated_integers('day15input.txt'))
        self.ic.start()

    def move(self, direction):
        command = {
            Direction.NORTH: 1,
            Direction.SOUTH: 2,
            Direction.WEST: 3,
            Direction.EAST: 4
        }[direction]
        self.ic.write_input(command)
        return Status(self.ic.read_output())
Esempio n. 12
0
def part1(data):
    cpu = Intcode()
    cpu.load_program(data)
    cpu.run()
    scaf = ''.join([chr(c) for c in cpu.read_output()]).strip().split('\n')

    scafpts = [(x, y) for y, line in enumerate(scaf)
               for x, c in enumerate(line) if c == '#']
    isect = []
    for pt in scafpts:
        ptx, pty = pt
        if all([(x, y) in scafpts
                for x, y in ((ptx + 1, pty), (ptx - 1, pty), (ptx, pty - 1),
                             (ptx, pty + 1))]):
            isect.append((ptx, pty))
    return sum((x * y for x, y in isect))
Esempio n. 13
0
def part1(data):
    prog = '\n'.join((
        'NOT C J',
        'AND D J',
        'NOT A T',
        'OR T J',
        'WALK\n',
    ))

    cpu = Intcode()
    cpu.load_program(data)
    cpu.set_ascii_mode(True)
    cpu.feed_inputs(*prog)
    cpu.run()
    out = cpu.read_output()

    try:
        print(''.join([chr(c) for c in out]))
    except ValueError:
        return (out[-1])
Esempio n. 14
0
def part2(data):
    prog = '\n'.join((
        'NOT I J',
        'AND H J',
        'NOT F T',
        'AND G T',
        'OR T J',
        'AND D J',
        'AND H J',
        'NOT A T',
        'OR T J',
        'NOT C T',
        'AND D T',
        'OR T J',
        #    'NOT C T',
        #    'AND D T',
        #    'OR T J',
        'RUN\n',
    ))

    prog = '\n'.join(('NOT A T', 'OR T J', 'AND G T', 'AND D T', 'AND H T',
                      'OR T J', 'NOT C T', 'AND D T', 'OR T J', 'RUN\n'))

    prog = '\n'.join(('NOT A J', 'OR E T', 'OR C T', 'NOT T T', 'AND D T',
                      'OR T J', 'OR B T', 'OR E T', 'NOT T T', 'OR T J',
                      'NOT I T', 'AND D T', 'OR T J', 'RUN\n'))

    cpu = Intcode()
    cpu.load_program(data)
    cpu.set_ascii_mode(True)
    cpu.feed_inputs(*prog)
    cpu.run()
    out = cpu.read_output()

    try:
        print(''.join([chr(c) for c in out]))
    except ValueError:
        return (out[-1])
    test_springscript(prog)
Esempio n. 15
0
def part2(data):
    cpu = Intcode(wfi_mode=True)
    cpu.set_ascii_mode(True)
    cpu.load_program(data)
    cpu.ram[0] = 2
    cpu.run()

    cpu.feed_inputs(
        *
        'A,B,A,B,C,C,B,A,C,A\nL,10,R,8,R,6,R,10\nL,12,R,8,L,12\nL,10,R,8,R,8\nn\n'
    )
    cpu.run()

    #cam = ''.join([chr(x) if chr(x).isprintable() or x == 10 and x < 0x110000 else str(x) for x in cpu.read_output() ]).strip().split('\n')
    cam = cpu.read_output()
    print(cam)
    '''
  from PIL import Image
  img = Image.new('RGB', (len(cam[0]), len(cam)), 'black')
  pix = img.load()
  for y, line in enumerate(cam):
    print(line)

    for x, char in enumerate(line):
      if char == '#':
        pix[x,y] = (0, 255, 128)

  img.save('day17.bmp')
  '''

    # L10 R8 R6 R10 L12 R8 L12 L10 R8 R6 R10 L12 R8 L12 L10 R8 R8 L10 R8 R8 L12 R8 L12 L10 R8 R6 R10 L10 R8 R8 L10 R8 R6 R10
    # L10 R8 R6 R10  = A
    # L12 R8 L12 = B
    # L10 R8 R8 = C
    # A B A B C C B A C A

    print(cpu.outputs)
Esempio n. 16
0
class Robot:
    def __init__(self):
        self.ic = Intcode(read_comma_separated_integers('day25input.txt'))
        self.ic.start()

    def run_manually(self):
        print(self._read_output(), end='')

        while self.ic.requires_input:
            txt = input()
            self.write_input(f'{txt}\n')
            print(self._read_output(), end='')

    def go(self, direction) -> Room:
        self.write_input(f'{direction}\n')
        return self.read_room_info()

    def take(self, item):
        self.write_input(f'take {item}\n')
        output = self.parse_output()
        assert output['lines'] == [f'You take the {item}.']

    def drop(self, item):
        self.write_input(f'drop {item}\n')
        output = self.parse_output()
        assert output['lines'] == [f'You drop the {item}.']

    def inv(self):
        self.write_input(f'inv\n')
        output = self.parse_output()
        if output['lines'] == ["You aren't carrying any items."]:
            return []
        else:
            return output['Items in your inventory:']

    def write_input(self, s):
        for ch in s:
            self.ic.write_input(ord(ch))

    def _read_output(self):
        rtn = []
        while self.ic.has_output:
            rtn.append(chr(self.ic.read_output()))
        return ''.join(rtn)

    def parse_output(self):
        rtn = {'lines': []}
        list_name = None
        end = False
        for line in self._read_output().splitlines():
            assert not end
            if line.endswith(':'):
                assert not list_name
                list_name = line
                rtn[list_name] = []
            elif not line:
                list_name = None
            elif list_name:
                assert line.startswith('- ')
                rtn[list_name].append(line[2:])
            elif line == 'Command?':
                end = True
            else:
                rtn['lines'].append(line)

        return rtn

    def read_room_info(self) -> Room:

        output = self.parse_output()
        lines = output['lines']

        assert lines[0].startswith('== ') and lines[0].endswith(' ==')
        room_name = lines[0][3:-3]
        doors = output.get('Doors here lead:', [])
        items = output.get('Items here:', [])

        TOO_LIGHT = 'A loud, robotic voice says '\
                    '"Alert! Droids on this ship are heavier than the detected value!"'\
                    ' and you are ejected back to the checkpoint.'

        TOO_HEAVY = 'A loud, robotic voice says '\
                    '"Alert! Droids on this ship are lighter than the detected value!"'\
                    ' and you are ejected back to the checkpoint.'

        if TOO_LIGHT in lines:
            raise SecurityCheckpointFailed(False)

        if TOO_HEAVY in lines:
            raise SecurityCheckpointFailed(True)

        for line in lines:
            if m := re.search(
                    r'You should be able to get in by typing (\d+) on the keypad',
                    line):
                raise PasswordFound(m.group(1))

        return Room(room_name=room_name, doors=doors, items=items)