Beispiel #1
0
def test_large_ints():

    # Should output a 16-digit number
    prog = [1102, 34915192, 34915192, 7, 4, 7, 99, 0]
    output = []
    res = run_until_halt(load_program(prog),
                         output_cb=lambda x: output.append(x))
    assert len(output) == 1 and len(str(output[0])) == 16

    # Should output the number in the middle
    prog = [104, 1125899906842624, 99]
    output = []
    res = run_until_halt(load_program(prog),
                         output_cb=lambda x: output.append(x))
    assert len(output) == 1 and output[0] == 1125899906842624
Beispiel #2
0
def run_row(prog, row, xs, xe):
    print("run_row()", row, xs, xe)
    context = {
        "output": [0 for x in range(xs, xe + 1)],
        "curr_pos": [xs, row],
        "input_axis": 0,
    }

    def handle_input():
        axis = context["input_axis"]
        res = context["curr_pos"][axis]
        #print("Axis {}: {}".format(axis, res))
        context["input_axis"] = (context["input_axis"] + 1) % 2
        return res

    def handle_output(x):
        coord = context["curr_pos"]
        context["output"][coord[0] - xs] = x

        context["curr_pos"][0] += 1

    while context["curr_pos"][0] < xe:
        vm_prog = intcode.load_program(prog.copy())
        intcode.run_until_halt(vm_prog, handle_input, handle_output)

    if 1 in context["output"]:
        first_one = xs + context["output"].index(1)
        last_one = xs + len(
            context["output"]) - context["output"][::-1].index(1)
    else:
        first_one = 0
        last_one = 0

    return (context["output"], first_one, last_one)
Beispiel #3
0
def run_program_step1(prog):
    context = {
        "grid": [[0 for x in range(50)] for y in range(50)],
        "curr_pos": [0, 0],
        "input_axis": 0,
    }

    def handle_input():
        axis = context["input_axis"]
        res = context["curr_pos"][axis]
        #time.sleep(0.1)
        #print("Axis {}: {}".format(axis, res))
        context["input_axis"] = (context["input_axis"] + 1) % 2
        return res

    def handle_output(x):
        coord = context["curr_pos"]
        context["grid"][coord[1]][coord[0]] = x

        context["curr_pos"][0] += 1
        if context["curr_pos"][0] >= 50:
            context["curr_pos"][1] += 1
            context["curr_pos"][0] = 0

    while context["curr_pos"][1] < 50:
        vm_prog = intcode.load_program(prog.copy())
        intcode.run_until_halt(vm_prog, handle_input, handle_output)

    return context
Beispiel #4
0
def run_row(row):
    global GRID, PROG

    context = {
        "curr_pos": [0, row],
        "input_axis": 0,
    }

    def handle_input():
        axis = context["input_axis"]
        res = context["curr_pos"][axis]
        context["input_axis"] = (context["input_axis"] + 1) % 2
        return res

    def handle_output(x):
        coord = context["curr_pos"]
        GRID[(coord[1] * 50) + coord[0]] = x

        context["curr_pos"][0] += 1
        if context["curr_pos"][0] >= 50:
            context["curr_pos"][1] += 1
            context["curr_pos"][0] = 0

    while context["curr_pos"][1] == row:
        vm_prog = intcode.load_program(PROG)
        intcode.run_until_halt(vm_prog, handle_input, handle_output)
Beispiel #5
0
def test_quine():
    prog = [
        109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0,
        99
    ]
    output = []
    res = run_until_halt(load_program(prog),
                         output_cb=lambda x: output.append(x))
    assert output == prog
def main():
    progs = [
        [1, 0, 0, 0, 99],
        [2, 3, 0, 3, 99],
        [2, 4, 4, 5, 99, 0],
        [1, 1, 1, 4, 99, 5, 6, 0, 99],
        [1, 1, 1, 4, 99, 5, 6, 0, 99],
        [1002, 4, 3, 4, 33],

        # LESS THAN and EQUALS tests
        [3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8],
        [3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8],
        [3, 3, 1108, -1, 8, 3, 4, 3, 99],
        [3, 3, 1107, -1, 8, 3, 4, 3, 99],

        # JUMP tests
        [3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9],
        [3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1],
        [
            3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31,
            1106, 0, 36, 98, 0, 0, 1002, 21, 125, 20, 4, 20, 1105, 1, 46, 104,
            999, 1105, 1, 46, 1101, 1000, 1, 20, 4, 20, 1105, 1, 46, 98, 99
        ],

        # Quine
        [
            109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101,
            0, 99
        ]
    ]
    for prog in progs:
        run_and_disassemble(prog)

    with open("../09/input.txt", "rt") as f:
        prog = [int(x) for x in f.read().strip().split(",") if len(x) > 0]
        print("Disassembling BOOST (test mode)...")
        prog_c = intcode.load_program(prog)
        for ctx in intcode.run_single_steps(prog_c, input_cb=lambda: 1):
            print(intcode.disassemble(ctx, prog_c))
        print("")

        print("Running BOOST (full)...")
        intcode.run_until_halt(intcode.load_program(prog), input_cb=lambda: 2)
        print("DONE")
Beispiel #7
0
def test_complex():
    prog = load_program([
        3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31,
        1106, 0, 36, 98, 0, 0, 1002, 21, 125, 20, 4, 20, 1105, 1, 46, 104, 999,
        1105, 1, 46, 1101, 1000, 1, 20, 4, 20, 1105, 1, 46, 98, 99
    ])
    for test in [(7, 999), (8, 1000), (9, 1001)]:
        output = []
        res = run_until_halt(prog.copy(), lambda: test[0],
                             lambda x: output.append(x))
        assert output[0] == test[1]
Beispiel #8
0
def test_simple():
    programs = [
        ([1, 0, 0, 0, 99], [2, 0, 0, 0, 99]),
        ([2, 3, 0, 3, 99], [2, 3, 0, 6, 99]),
        ([2, 4, 4, 5, 99, 0], [2, 4, 4, 5, 99, 9801]),
        ([1, 1, 1, 4, 99, 5, 6, 0, 99], [30, 1, 1, 4, 2, 5, 6, 0, 99]),
        ([1, 1, 1, 4, 99, 5, 6, 0, 99], [30, 1, 1, 4, 2, 5, 6, 0, 99]),
        ([1002, 4, 3, 4, 33], [1002, 4, 3, 4, 99]),
    ]
    for prog in programs:
        res = run_until_halt(load_program(prog[0]), lambda: 0, lambda x: 0)
        assert list(res.values()) == prog[1]
Beispiel #9
0
def test_less_than_equals():
    programs = [
        ([3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], [(8, 1), (7, 0), (9, 0)]),
        ([3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], [(8, 0), (7, 1), (9, 0)]),
        ([3, 3, 1108, -1, 8, 3, 4, 3, 99], [(8, 1), (7, 0), (9, 0)]),
        ([3, 3, 1107, -1, 8, 3, 4, 3, 99], [(8, 0), (7, 1), (9, 0)]),
    ]
    for prog in programs:
        for test in prog[1]:
            output = []
            res = run_until_halt(load_program(prog[0]), lambda: test[0],
                                 lambda x: output.append(x))
            assert output[0] == test[1]
Beispiel #10
0
def test_jumps():
    programs = [
        ([3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9], [(-1, 1),
                                                                     (0, 0),
                                                                     (1, 1)]),
        ([3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1], [(-1, 1), (0, 0),
                                                             (1, 1)]),
    ]
    for prog in programs:
        for test in prog[1]:
            output = []
            res = run_until_halt(load_program(prog[0]), lambda: test[0],
                                 lambda x: output.append(x))
            assert output[0] == test[1]
Beispiel #11
0
def run_program_step2(prog, view_feed, seq):

    # TODO: parse movement sequence and find longest repeating patterns for function definitions
    # TODO: convert 3 longest repeated sequences to function definitions and update main_routine to be a list of function calls
    print("TODO: compress sequence: {}".format(seq))

    main_routine = "A,A,B,C,B,C,B,C,B,A"
    functions = [
        "R,10,L,12,R,6",
        "R,6,R,10,R,12,R,6",
        "R,10,L,12,L,12",
    ]

    context = {
        "output": "",
        "input_idx": 0,
    }

    # Concatenate the main_routine, functions and live feed answer to a
    # single string of characters to sent as input to the robot
    command_str = main_routine + "\n" + "\n".join(functions) + "\n" + (
        "y" if view_feed else "n") + "\n"

    def handle_input():
        res = 0
        if context["input_idx"] < len(command_str):
            res = ord(command_str[context["input_idx"]])
            context["input_idx"] += 1
        return res

    def handle_output(x):
        if view_feed:
            if x == 10:
                context["output"] += "\n"
                print(context["output"])
            else:
                context["output"] += chr(x)
        else:
            context["output"] = x

    # Wake up robot
    prog[0] = 2

    prog = intcode.load_program(prog)
    intcode.run_until_halt(prog, handle_input, handle_output)

    return context
Beispiel #12
0
def run_program_step1(prog):
	context = {
		"output": "",
	}

	def handle_input():
		return 0

	def handle_output(x):
		if x == 10:
			context["output"] += "\n"
		else:
			context["output"] += chr(x)

	prog = intcode.load_program(prog)
	intcode.run_until_halt(prog, handle_input, handle_output)

	return context
Beispiel #13
0
import intcode
from threading import Thread
from queue import Queue
from numpy import array
import time

program = intcode.load_program('input.dat')

def executor(program, qi, qo):
    print('Running a program...')
    intcode.execute(program, lambda: qi.get(timeout=2), qo.put)
    print('Finished running a program...')
    qo.put(None)

def rotate(direction, left=True):
    directions = ((0, -1), (1, 0), (0, 1), (-1, 0))
    shift = -1 if left else 1
    return directions[(directions.index(direction) + shift) % len(directions)]

def painter(qi, qo, start_color=0):
    panels = {}
    position = array((0, 0))
    direction = (0, -1)

    print('Start painting...')
    qo.put(start_color)

    while True:
        paint = qi.get(timeout=1)
        if paint is None:
            print(f'Received {paint}. Finish painting...')
def run_and_disassemble(prog):
    print("Disassembling...")
    prog = intcode.load_program(prog)
    for ctx in intcode.run_single_steps(prog):
        print(intcode.disassemble(ctx, prog))
    print("")
Beispiel #15
0
def run_program(prog, break_on_oxy_unit):
    """
	Runs the repair droid IntCode program and handles I/O.

	The I/O routines effectively perform a depth-first search (DFS) through
	the maze contained within the program.
	"""

    context = {
        # Current repair droid position (only for rendering)
        "droid_pos": [0, 0],

        # Index of the current cell in the open list
        "curr_cell": 0,

        # Closed list: cells fully explored (all neighbours visited or
        # a wall)
        "closed_cells": [],

        # Open list: cells whose surroundings have not been fully
        # explored
        "open_cells": [
            {
                "pos": (0, 0),
                "dir": 1,
                "typ": 1
            },
        ],

        # Location of the oxygen generator (once found)
        "oxy_unit": None,
    }

    def handle_input():
        if context["curr_cell"] < 0 or context["curr_cell"] >= len(
                context["open_cells"]):
            return 0

        cell = context["open_cells"][context["curr_cell"]]
        d = cell["dir"]

        # If the current cell's direction is None then all directions
        # have been explored, so move it to the closed list and move
        # the droid back to the previous cell in the open list
        if d is None:
            return move_backwards(context)

        # Check all directions from the current cell that haven't
        # already been explored
        while True:
            new_pos = get_new_coord(cell["pos"], d)
            if not is_in_list(new_pos, context):
                break
            d += 1
            if d > 4:
                break

        # If an unexplored direction exists, follow it and add the new
        # cell to the open list
        if d <= 4:
            cell["dir"] = d
            context["open_cells"].append({
                "pos": get_new_coord(cell["pos"], d),
                "dir": 1,
                "typ": None,
            })
            context["curr_cell"] += 1
            return d

        # Otherwise, this cell has been fully explored so move it to
        # the closed list and move the droid back to the previous cell
        # in the open list
        else:
            return move_backwards(context)

    def handle_output(x):
        cell = context["open_cells"][context["curr_cell"]]

        # Droid hit a wall and remained at its previous location
        if x == 0:
            cell["typ"] = 0
            context["closed_cells"].append(context["open_cells"].pop(-1))
            back_track(context)

        # Droid moved to the new cell
        elif x == 1:
            cell["typ"] = 1
            context["droid_pos"][0] = cell["pos"][0]
            context["droid_pos"][1] = cell["pos"][1]

        # Droid moved to the new cell and the oxygen unit was
        # discovered there
        elif x == 2:
            cell["typ"] = 2
            context["droid_pos"][0] = cell["pos"][0]
            context["droid_pos"][1] = cell["pos"][1]
            context["oxy_unit"] = cell

    prog = intcode.load_program(prog)

    # Single-step the program and break as soon as the oxygen unit is found
    # (if necessary)
    for vm_ctx in intcode.run_single_steps(prog, handle_input, handle_output):
        if break_on_oxy_unit and context["oxy_unit"] is not None:
            break

    return context
Beispiel #16
0
from intcode import load_program, run_program

program = load_program("./5.in")
# stdin is defined as [1] in the problem
run_program(program, [1])