Beispiel #1
0
def check_phase_settings_loop(program, phase_settings):
    amplifiers = []
    for i in range(5):
        cpu = intcode.CPU(memory=program.copy(), input=[phase_settings[i]])
        amplifiers.append(cpu)

    last_output = 0
    amplifier_idx = 0
    while True:
        cpu = amplifiers[amplifier_idx]
        # print(f"amplifier {amplifier_idx} last_interrupt {cpu.last_interrupt}")

        if cpu.last_interrupt == intcode.Interrupt.HALT:
            # print(f"amplifier {amplifier_idx} stopped")
            if amplifier_idx == 4:
                break
            else:
                amplifier_idx += 1
                continue

        # print(f"amplifier {amplifier_idx} add_input {last_output}")
        cpu.add_input(last_output)
        cpu.execute_until_interrupt()
        last_output = cpu.last_output()

        if amplifier_idx == 4:
            amplifier_idx = 0
        else:
            amplifier_idx += 1

    return last_output
Beispiel #2
0
def runNATnetwork(ins):
    global inputQueues

    nics = [intcode.CPU(ins, inGen(x), outGen(x)) for x in range(50)]
    previousY = [math.inf]

    while not all([nic.finished() for nic in nics]):
        for n in nics:
            n.run(1)

        # Check the NAT status - remember only last packet
        if len(inputQueues[255]) > 1:
            inputQueues[255] = [inputQueues[255][-1]]

        # Check network status
        if all([len(inputQueues[x]) == 0
                for x in range(50)] + [len(inputQueues[255]) > 0]):

            # It's idle! Send to 0, but check for the double send
            previousY.append(inputQueues[255][0][1])
            if previousY[0] == previousY[1]:
                raise Exception("Part 2: Sent Y", previousY[0],
                                "back to back from NAT")
            else:
                previousY.pop(0)

            inputQueues[0].append(inputQueues[255].pop())
Beispiel #3
0
def paint(hull, ins):
    pos = complex(0,0)
    mov = complex(0,1)
    painted = set()

    def outputer():
        mode = 0
        TURN = [1j, -1j]
        def o(x):
            # I don't love having to use nonlocal, but...
            nonlocal mode
            nonlocal pos
            nonlocal mov
            
            if mode == 0:
                hull[pos] = x
                painted.add(pos)
            else:
                mov *= TURN[x]
                pos += mov
            mode = (mode+1)%2

        return o

    def input():
        while True:
            yield hull[pos]
    
    cpu = intcode.CPU(ins,input, outputer())
    while not cpu.finished():
        cpu.run()

    return painted
Beispiel #4
0
def test_case3():
    prog = [104, 1125899906842624, 99]
    cpu = intcode.CPU(code=prog)
    # print("")
    # cpu.debug = True
    cpu.execute()
    # print("case3 output:", cpu.output)
    assert [1125899906842624] == cpu.output
Beispiel #5
0
def check_phase_settings(program, phase_settings):
    last_output = 0
    for i in range(5):
        cpu = intcode.CPU(memory=program.copy(),
                          input=[phase_settings[i], last_output])
        cpu.execute()
        last_output = cpu.last_output()
    return last_output
Beispiel #6
0
def runNetwork(ins):
    global inputQueues
    nics = [intcode.CPU(ins, inGen(x), outGen(x)) for x in range(50)]
    while not all([nic.finished() for nic in nics]):
        for n in nics:
            n.run(1)

        if len(inputQueues[255]) != 0:
            raise Exception("Part 1: ", inputQueues[255][0][1])
Beispiel #7
0
def test_case1():
    prog = [
        109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0,
        99
    ]
    cpu = intcode.CPU(code=prog)
    # print()
    # cpu.debug = True
    cpu.execute()
    assert cpu.output == prog
Beispiel #8
0
def spring(ins, command):
    def outputter(x):
        if x <= 127:
            if chr(x) in PRINTABLE:
                print(chr(x), end='')
            else:
                raise Exception("Unexpected chr")
        else:
            print("End of path:", x)

    cpu = intcode.CPU(ins, command, outputter)
    cpu.run()
Beispiel #9
0
def test_case2():
    prog = [
        1102,
        34915192,
        34915192,
        7,  # write 1219070632396864 to [7] (last elem)
        4,
        7,  # re
        99,
        0
    ]
    cpu = intcode.CPU(code=prog)
    # print("")
    # cpu.debug = True
    cpu.execute()
    assert 16 == len(str(cpu.last_output()))
Beispiel #10
0
def runAdventure(ins):
    def outputter(x):
        if x < 128:
            print(chr(x), end='')
        else:
            raise Exception("NotASCII")

    def inputter():
        commands = [
            "east", "east", "take fuel cell", "west", "take jam", "south",
            "take shell", "north", "west", "south", "west", "take easter egg",
            "north", "east", "take space heater", "west", "south", "west",
            "west", "take monolith", "south", "west", "north", "take coin",
            "south", "east", "north", "west", "take mug", "north", "drop jam",
            "drop easter egg", "drop monolith", "drop mug", "north"
        ]
        for c in commands:
            for l in c:
                yield (ord(l))
            yield (10)

        # We are now at checkpoint - code below exhausts the options, but I've added the requirements to the list above
        # before commiting
        #items = ["fuel cell", "jam", "shell", "easter egg", "space heater", "monolith", "coin", "mug"]
        #for numitems in range(8,0,-1):
        #    for testcomb in itertools.combinations(items,numitems):
        #        for item in items:
        #            for l in "drop " + item:
        #                yield(ord(l))
        #            yield(10)
        #        for item in testcomb:
        #            for l in "take " + item:
        #                yield(ord(l))
        #            yield(10)
        #        for l in "north":
        #            yield(ord(l))
        #        yield(10)
        #
        #while True:
        #    buffer = input("*INPUT*: ")
        #    for c in buffer:
        #        yield ord(c)
        #    yield(10)

    adv = intcode.CPU(ins, inputter, outputter)
    adv.run()
Beispiel #11
0
def part2(ins):
    screen = collections.defaultdict(lambda: EMPTY, {})
    score = 0

    def outputter():
        buf = []

        def o(x):
            nonlocal buf
            nonlocal screen
            nonlocal score
            buf.append(x)
            if len(buf) == 3:
                pos = complex(buf[0], -buf[1])
                if pos == complex(-1, 0):
                    score = buf[2]
                else:
                    screen[pos] = buf[2]
                buf = []

        return o

    def input():
        nonlocal screen
        nonlocal score

        while True:
            printscreen(screen, score)
            paddlex = [x for x in screen.keys() if screen[x] == PADDLE][0]
            ballx = [x for x in screen.keys() if screen[x] == BALL][0]
            if ballx.real < paddlex.real:
                yield -1
            elif ballx.real > paddlex.real:
                yield 1
            else:
                yield 0

    ins[0] = 2  # Set free play
    cpu = intcode.CPU(ins, input, outputter())
    while not cpu.finished():
        cpu.run()

    return score
Beispiel #12
0
def part1(ins):
    screen = {}

    def outputter():
        buf = []

        def o(x):
            nonlocal buf
            nonlocal screen
            buf.append(x)
            if len(buf) == 3:
                pos = complex(buf[0], -buf[1])
                screen[pos] = buf[2]
                buf = []

        return o

    cpu = intcode.CPU(ins, None, outputter())
    cpu.run()

    blocks = sum([1 for x in screen.values() if x == BLOCK])
    return blocks
Beispiel #13
0
def findOxygen(ins):
    # Try building a graph of our progress
    G = networkx.Graph()
    G.add_node(0+0j)

    # Position
    pos = 0+0j
    options = {0+0j: [1,2,3,4]}
    path = []
    reverse = False
    
    # Moving around is hard!
    def inputter():
        nonlocal pos
        nonlocal reverse
        nonlocal path
        lastpos = pos
        while True:
            # We find ourselves at pos, with some options in options. Pick the next and
            # execute it if there are any. If no options remain, choose the direction to
            # send us back one
            if len(options[pos]) == 0:
                reverse = True
                yield pathrev[path[-1]] # This will throw when we've exhausted everything
            else:
                go = options[pos].pop(-1)
                path.append(go)
                yield go
            

    def outputter(response):
        nonlocal pos
        nonlocal reverse
        global oxygen

        if response == 0:
            # Hit a wall. Remove from path, don't update position
            path.pop(-1)
        else:
            if not reverse:
                # Found a spot we could move into. Could be a place we've encountered
                # before if there are loops
                newpos = pos + steps[path[-1]]

                # Add a link in the graph
                G.add_edge(pos, newpos)

                # Update pos
                pos = newpos

                if pos not in options:
                    options[pos] = [x for x in range(1,5) if x != pathrev[path[-1]]]

                # Remeber if this is oxygen
                if response == 2:
                    oxygen = pos
            else:
                # Unwind
                newpos = pos + steps[pathrev[path[-1]]]
                pos = newpos
                reverse = False
                path.pop(-1)
            
    cpu = intcode.CPU(ins, inputter, outputter)
    try:
        cpu.run()
    except Exception as e:
        pass

    return G
Beispiel #14
0
#                 # print(f"==SET INPUT: {color}")
#                 cpu.set_input([color])
#             continue
#         except intcode.HaltInt:
#             print("STOP: Got HaltInt")
#             print("")
#             print("CPU STATE:")
#             print(cpu.state())
#             pass
#         break
#     print("painted_once =", painted_once)
#     print("paints_count =", paints_count)
#     print("len(painted) =", len(painted))

# if __name__ == "__main__":
#     amplifiers = []
#     program = intcode.read_file('code.txt')
#     cpu = intcode.CPU(code=program, input=[1])
#     probe_paint_code(cpu)

if __name__ == "__main__":
    amplifiers = []
    program = intcode.read_file('code.txt')

    cpu = intcode.CPU(code=program)
    robo = robopaint.Robot(cpu=cpu)

    robo.paint(start_color=robopaint.ColorNum.Black)
    robo.draw_painted()

    print(robo.painted_count())
Beispiel #15
0
import intcode

if __name__ == "__main__":
    amplifiers = []
    program = intcode.read_file('code.txt')
    cpu = intcode.CPU(code=program, input=[1])
    cpu.debug = True
    cpu.execute()

    print("output:", cpu.output)
Beispiel #16
0
import intcode

if __name__ == "__main__":
    amplifiers = []
    program = intcode.read_file('code.txt')
    cpu = intcode.CPU(code=program, input=[2], max_steps=1_000_000)
    cpu.execute()

    print("CPU steps:", cpu.step)  # 371205 (~40s on MacbookPro 2018)
    print("output:", cpu.output)
Beispiel #17
0
import intcode

if __name__ == "__main__":
    program = intcode.read_file('code.txt')
    # print(program)
    cpu = intcode.CPU(memory=program, input=1)
    cpu.execute()
    # print("[0]", cpu.memory[0])
Beispiel #18
0
def test_memory_rw():
    cpu = intcode.CPU(code=[])
    value = 1125899906842624
    cpu.write_memory(10000, value)
    got_value = cpu.read_memory(10000)
    assert value == got_value
Beispiel #19
0
def test_cpu_init():
    cpu = intcode.CPU(memory=[], input=[])
    assert [] == cpu.output