Пример #1
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)
Пример #2
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)
Пример #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
Пример #4
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
Пример #5
0
def run_program(prog, start_panel_colour):
    context = {
        "cells": defaultdict(lambda: 0),
        "curr_pos": [0, 0],
        "direction": 0,
        "output_mode": 0,
    }

    context["cells"][(0, 0)] = start_panel_colour

    def handle_input():
        # Robot's camera: return the value of the current cell
        return context["cells"][tuple(context["curr_pos"])]

    def handle_output(x):
        if context["output_mode"] == 0:

            # Paint the current cell
            context["cells"][tuple(context["curr_pos"])] = x

            # Change output_mode ready for next direction change
            context["output_mode"] = 1

        else:
            # Rotate 90° left (0) or 90° right (1)
            if x == 0:
                context["direction"] = (context["direction"] - 1) % 4
            elif x == 1:
                context["direction"] = (context["direction"] + 1) % 4

            # Move forward 1 cell based on new direction
            if context["direction"] == 0:  # UP
                context["curr_pos"][1] -= 1
            elif context["direction"] == 1:  # RIGHT
                context["curr_pos"][0] += 1
            elif context["direction"] == 2:  # DOWN
                context["curr_pos"][1] += 1
            elif context["direction"] == 3:  # LEFT
                context["curr_pos"][0] -= 1

            # Reset output_mode ready for next paint
            context["output_mode"] = 0

    # Run the painting robot's program until it halts, handling input and
    # output using the above functions
    intcode.run_until_halt(prog, handle_input, handle_output)

    return context
Пример #6
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
Пример #7
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
Пример #8
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
Пример #9
0
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")
Пример #10
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]
Пример #11
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]
Пример #12
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]
Пример #13
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]
Пример #14
0
def test_examples():

	# Quine (should output a copy of itself)
	prog = [109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99]
	output = []
	intcode.run_until_halt(prog.copy(), lambda: 0, lambda x: output.append(x))
	assert output == prog

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

	# Should output the second large value
	prog = [104,1125899906842624,99]
	output = []
	intcode.run_until_halt(prog, lambda: 0, lambda x: output.append(x))
	assert len(output) == 1 and output[0] == prog[1]
Пример #15
0
def run_BOOST(mode):
	program = get_input()
	output = []
	intcode.run_until_halt(program.copy(), lambda: mode, lambda x: output.append(x))
	return output
Пример #16
0
def run_program(prog, quarters):
    context = {
        "cells": defaultdict(lambda: " "),
        "draw_pos": [0, 0],
        "output_mode": 0,
        "score": 0,
    }

    # "Insert" quarters if necessary
    if quarters is not None:
        prog[0] = quarters

    def handle_input():
        # Obtain position of the ball ("O") and bat ("=") and return
        # the appropriate joystick input (left: -1, right: 1, centered:
        # 0) to try to keep the bat below the ball
        ball_pos = get_element_pos(context["cells"], "O")
        bat_pos = get_element_pos(context["cells"], "=")
        if ball_pos is None or bat_pos is None:
            return 0
        if ball_pos[0] < bat_pos[0]:
            return -1
        elif ball_pos[0] > bat_pos[0]:
            return 1
        else:
            return 0

    def handle_output(x):

        # Set X coordinate
        if context["output_mode"] == 0:
            context["draw_pos"][0] = x
            context["output_mode"] += 1

        # Set Y coordinate
        elif context["output_mode"] == 1:
            context["draw_pos"][1] = x
            context["output_mode"] += 1

        # Set tile ID
        elif context["output_mode"] == 2:
            pos = tuple(context["draw_pos"])
            if pos == (-1, 0):
                context["score"] = x
            else:
                context["tile_id"] = x

                # Update grid
                if x == 1:
                    ch = "#"
                elif x == 2:
                    ch = "x"
                elif x == 3:
                    ch = "="
                elif x == 4:
                    ch = "O"
                else:
                    ch = " "
                context["cells"][pos] = ch

            # Reset output_mode back to 0 (set X)
            context["output_mode"] = 0

    # Run the game until it halts
    intcode.run_until_halt(prog, handle_input, handle_output)

    return context