In [24]:
def readfile(path):
    with open(path) as input_file: 
        return input_file.read().strip()

def params(program, i, count):
    modes = str(program[i] // 100)[::-1]
    result = []
    
    for x in range(count - 1):
        arg = program[i + 1 + x]
        if x >= len(modes) or modes[x] == "0":
            result.append(program[arg])
        elif modes[x] == "2":
            result.append(program[program.offset + arg])
        else:
            result.append(arg)
            
    output = program[i + count]
    if len(modes) >= count and modes[count - 1] == "2":
        output += program.offset
        
    result.append(output) # output
    return result

def add(program, i, **kwargs):
    assert program[i] % 100 == 1
    a, b, out = params(program, i, 3)
    program[out] = a + b
    return i + 4, None
    
def mul(program, i, **kwargs):
    assert program[i] % 100 == 2
    a, b, out = params(program, i, 3)
    program[out] = a * b
    return i + 4, None

def inp(program, i, input_value, **kwargs):
    assert program[i] % 100 == 3
    out, = params(program, i, 1)
    program[out] = input_value
    # print(f"> {program[i]} program[{out}] = {program[out]}")
    return i + 2, None

def out(program, i, **kwargs):
    assert program[i] % 100 == 4
    val, _ = params(program, i, 2)
    # print(f"> {val}")
    return i + 2, val
    
def jit(program, i, **kwargs):
    assert program[i] % 100 == 5
    test, ip, _ = params(program, i, 3)
    if test != 0:
        return ip, None
    return i + 3, None

def jif(program, i, **kwargs):
    assert program[i] % 100 == 6
    test, ip, _ = params(program, i, 3)
    if test == 0:
        return ip, None
    return i + 3, None

def lt(program, i, **kwargs):
    assert program[i] % 100 == 7
    a, b, out = params(program, i, 3)
    program[out] = int(a < b)
    return i + 4, None

def eq(program, i, **kwargs):
    assert program[i] % 100 == 8
    a, b, out = params(program, i, 3)
    program[out] = int(a == b)
    return i + 4, None

def rbo(program, i, **kwargs):
    assert program[i] % 100 == 9
    delta, _ = params(program, i, 2)
    program.offset += delta
    # print (f"> rbo = {program.offset}" )
    return i + 2, None

operations = { 1: add, 2: mul, 3: inp, 4: out, 5: jit, 6: jif, 7: lt, 8: eq, 9: rbo }

class Program(list):
    def __init__(self, *args, **kwargs):
        super(Program, self).__init__(args[0])
        self.offset = 0

def compute(program, debug=False):
    program = Program(program)
    
    l = len(program)
    i = 0
    output_value = None
    last_output = None
    
    while i < l:
        op = program[i]
        if op == 99:
            if debug: 
                print(f">> exit {output_value}")
            return 
        
        if debug:
            print(f">> {i}, {list(enumerate(program))[i:i+5]}")
            
        if op % 100 == 3:
            input_value = yield
        else:
            input_value = None
            
        i, output_value = operations[op % 100](program, i, input_value=input_value)
        
        if output_value is not None:
            yield output_value
        
    raise Exception("Didn't terminate properly")
    
def process(listing):
    lst = list(map(int, listing.split(",")))
    lst.extend([0] * 100000)
    return lst
In [32]:
tests = [
    readfile("AoC/input17.txt"),
]
In [66]:
def soln():
    result = list(compute(process(readfile("AoC/input17.txt").strip())))
    grid = {}
    x = 0
    y = 0
    for ch in result:
        if chr(ch) == '\n':
            y += 1
            x = 0
        else:
            grid[(x, y)] = chr(ch)
            x += 1
        # print(chr(ch), end='')

    total = 0
    ylast = None
    points = []
    for (x, y), c in grid.items():
        o = False
        if c == '#' and grid.get((x + 1, y)) == '#' and grid.get((x - 1, y)) == '#' and grid.get((x, y + 1)) == '#' and grid.get((x, y - 1)) == '#':
            o = True
            total += x * y
            points.append((x, y))

        if y != ylast:
            print()
            ylast = y
        print('o' if o else c, end='')

    print()
    print(points, [ x * y for x, y in points ], sum( x * y for x, y in points ))
    return total, grid

soln()
......................................#######......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
..............#########.........#######.....#......
......................#.........#...........#......
......................#.........#.........##o######
......................#.........#.........#.#.....#
......................#.........#.....####o##.....#
......................#.........#.....#...#.......#
......................##########o##...#...#.......#
................................#.#...#...#.......#
############^...................##o###o##.#.......#
#.................................#...#.#.#.......#
#.................#######.........#...##o##.#######
#.................#.....#.........#.....#...#......
#...............##o##...#.........#######...#......
#...............#.#.#...#...................#......
#########.......#.##o###o##.................#......
........#.......#...#...#.#.................#......
........#.......#...#...##o##########.......#......
........#.......#...#.....#.........#.......#......
........#.....##o####.....#.........#.......#......
........#.....#.#.........#.........#.......#......
........######o##.........#.........#.......#......
..............#...........#.........#.......#......
..............#.....#######.........#########......
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#######..............................
[(44, 10), (42, 12), (32, 14), (34, 16), (38, 16), (40, 18), (18, 20), (20, 22), (24, 22), (26, 24), (16, 26), (14, 28)] [440, 504, 448, 544, 608, 720, 360, 440, 528, 624, 416, 392] 6024
Out[66]:
(6024,
 {(0, 0): '.',
  (1, 0): '.',
  (2, 0): '.',
  (3, 0): '.',
  (4, 0): '.',
  (5, 0): '.',
  (6, 0): '.',
  (7, 0): '.',
  (8, 0): '.',
  (9, 0): '.',
  (10, 0): '.',
  (11, 0): '.',
  (12, 0): '.',
  (13, 0): '.',
  (14, 0): '.',
  (15, 0): '.',
  (16, 0): '.',
  (17, 0): '.',
  (18, 0): '.',
  (19, 0): '.',
  (20, 0): '.',
  (21, 0): '.',
  (22, 0): '.',
  (23, 0): '.',
  (24, 0): '.',
  (25, 0): '.',
  (26, 0): '.',
  (27, 0): '.',
  (28, 0): '.',
  (29, 0): '.',
  (30, 0): '.',
  (31, 0): '.',
  (32, 0): '.',
  (33, 0): '.',
  (34, 0): '.',
  (35, 0): '.',
  (36, 0): '.',
  (37, 0): '.',
  (38, 0): '#',
  (39, 0): '#',
  (40, 0): '#',
  (41, 0): '#',
  (42, 0): '#',
  (43, 0): '#',
  (44, 0): '#',
  (45, 0): '.',
  (46, 0): '.',
  (47, 0): '.',
  (48, 0): '.',
  (49, 0): '.',
  (50, 0): '.',
  (0, 1): '.',
  (1, 1): '.',
  (2, 1): '.',
  (3, 1): '.',
  (4, 1): '.',
  (5, 1): '.',
  (6, 1): '.',
  (7, 1): '.',
  (8, 1): '.',
  (9, 1): '.',
  (10, 1): '.',
  (11, 1): '.',
  (12, 1): '.',
  (13, 1): '.',
  (14, 1): '.',
  (15, 1): '.',
  (16, 1): '.',
  (17, 1): '.',
  (18, 1): '.',
  (19, 1): '.',
  (20, 1): '.',
  (21, 1): '.',
  (22, 1): '.',
  (23, 1): '.',
  (24, 1): '.',
  (25, 1): '.',
  (26, 1): '.',
  (27, 1): '.',
  (28, 1): '.',
  (29, 1): '.',
  (30, 1): '.',
  (31, 1): '.',
  (32, 1): '.',
  (33, 1): '.',
  (34, 1): '.',
  (35, 1): '.',
  (36, 1): '.',
  (37, 1): '.',
  (38, 1): '#',
  (39, 1): '.',
  (40, 1): '.',
  (41, 1): '.',
  (42, 1): '.',
  (43, 1): '.',
  (44, 1): '#',
  (45, 1): '.',
  (46, 1): '.',
  (47, 1): '.',
  (48, 1): '.',
  (49, 1): '.',
  (50, 1): '.',
  (0, 2): '.',
  (1, 2): '.',
  (2, 2): '.',
  (3, 2): '.',
  (4, 2): '.',
  (5, 2): '.',
  (6, 2): '.',
  (7, 2): '.',
  (8, 2): '.',
  (9, 2): '.',
  (10, 2): '.',
  (11, 2): '.',
  (12, 2): '.',
  (13, 2): '.',
  (14, 2): '.',
  (15, 2): '.',
  (16, 2): '.',
  (17, 2): '.',
  (18, 2): '.',
  (19, 2): '.',
  (20, 2): '.',
  (21, 2): '.',
  (22, 2): '.',
  (23, 2): '.',
  (24, 2): '.',
  (25, 2): '.',
  (26, 2): '.',
  (27, 2): '.',
  (28, 2): '.',
  (29, 2): '.',
  (30, 2): '.',
  (31, 2): '.',
  (32, 2): '.',
  (33, 2): '.',
  (34, 2): '.',
  (35, 2): '.',
  (36, 2): '.',
  (37, 2): '.',
  (38, 2): '#',
  (39, 2): '.',
  (40, 2): '.',
  (41, 2): '.',
  (42, 2): '.',
  (43, 2): '.',
  (44, 2): '#',
  (45, 2): '.',
  (46, 2): '.',
  (47, 2): '.',
  (48, 2): '.',
  (49, 2): '.',
  (50, 2): '.',
  (0, 3): '.',
  (1, 3): '.',
  (2, 3): '.',
  (3, 3): '.',
  (4, 3): '.',
  (5, 3): '.',
  (6, 3): '.',
  (7, 3): '.',
  (8, 3): '.',
  (9, 3): '.',
  (10, 3): '.',
  (11, 3): '.',
  (12, 3): '.',
  (13, 3): '.',
  (14, 3): '.',
  (15, 3): '.',
  (16, 3): '.',
  (17, 3): '.',
  (18, 3): '.',
  (19, 3): '.',
  (20, 3): '.',
  (21, 3): '.',
  (22, 3): '.',
  (23, 3): '.',
  (24, 3): '.',
  (25, 3): '.',
  (26, 3): '.',
  (27, 3): '.',
  (28, 3): '.',
  (29, 3): '.',
  (30, 3): '.',
  (31, 3): '.',
  (32, 3): '.',
  (33, 3): '.',
  (34, 3): '.',
  (35, 3): '.',
  (36, 3): '.',
  (37, 3): '.',
  (38, 3): '#',
  (39, 3): '.',
  (40, 3): '.',
  (41, 3): '.',
  (42, 3): '.',
  (43, 3): '.',
  (44, 3): '#',
  (45, 3): '.',
  (46, 3): '.',
  (47, 3): '.',
  (48, 3): '.',
  (49, 3): '.',
  (50, 3): '.',
  (0, 4): '.',
  (1, 4): '.',
  (2, 4): '.',
  (3, 4): '.',
  (4, 4): '.',
  (5, 4): '.',
  (6, 4): '.',
  (7, 4): '.',
  (8, 4): '.',
  (9, 4): '.',
  (10, 4): '.',
  (11, 4): '.',
  (12, 4): '.',
  (13, 4): '.',
  (14, 4): '.',
  (15, 4): '.',
  (16, 4): '.',
  (17, 4): '.',
  (18, 4): '.',
  (19, 4): '.',
  (20, 4): '.',
  (21, 4): '.',
  (22, 4): '.',
  (23, 4): '.',
  (24, 4): '.',
  (25, 4): '.',
  (26, 4): '.',
  (27, 4): '.',
  (28, 4): '.',
  (29, 4): '.',
  (30, 4): '.',
  (31, 4): '.',
  (32, 4): '.',
  (33, 4): '.',
  (34, 4): '.',
  (35, 4): '.',
  (36, 4): '.',
  (37, 4): '.',
  (38, 4): '#',
  (39, 4): '.',
  (40, 4): '.',
  (41, 4): '.',
  (42, 4): '.',
  (43, 4): '.',
  (44, 4): '#',
  (45, 4): '.',
  (46, 4): '.',
  (47, 4): '.',
  (48, 4): '.',
  (49, 4): '.',
  (50, 4): '.',
  (0, 5): '.',
  (1, 5): '.',
  (2, 5): '.',
  (3, 5): '.',
  (4, 5): '.',
  (5, 5): '.',
  (6, 5): '.',
  (7, 5): '.',
  (8, 5): '.',
  (9, 5): '.',
  (10, 5): '.',
  (11, 5): '.',
  (12, 5): '.',
  (13, 5): '.',
  (14, 5): '.',
  (15, 5): '.',
  (16, 5): '.',
  (17, 5): '.',
  (18, 5): '.',
  (19, 5): '.',
  (20, 5): '.',
  (21, 5): '.',
  (22, 5): '.',
  (23, 5): '.',
  (24, 5): '.',
  (25, 5): '.',
  (26, 5): '.',
  (27, 5): '.',
  (28, 5): '.',
  (29, 5): '.',
  (30, 5): '.',
  (31, 5): '.',
  (32, 5): '.',
  (33, 5): '.',
  (34, 5): '.',
  (35, 5): '.',
  (36, 5): '.',
  (37, 5): '.',
  (38, 5): '#',
  (39, 5): '.',
  (40, 5): '.',
  (41, 5): '.',
  (42, 5): '.',
  (43, 5): '.',
  (44, 5): '#',
  (45, 5): '.',
  (46, 5): '.',
  (47, 5): '.',
  (48, 5): '.',
  (49, 5): '.',
  (50, 5): '.',
  (0, 6): '.',
  (1, 6): '.',
  (2, 6): '.',
  (3, 6): '.',
  (4, 6): '.',
  (5, 6): '.',
  (6, 6): '.',
  (7, 6): '.',
  (8, 6): '.',
  (9, 6): '.',
  (10, 6): '.',
  (11, 6): '.',
  (12, 6): '.',
  (13, 6): '.',
  (14, 6): '.',
  (15, 6): '.',
  (16, 6): '.',
  (17, 6): '.',
  (18, 6): '.',
  (19, 6): '.',
  (20, 6): '.',
  (21, 6): '.',
  (22, 6): '.',
  (23, 6): '.',
  (24, 6): '.',
  (25, 6): '.',
  (26, 6): '.',
  (27, 6): '.',
  (28, 6): '.',
  (29, 6): '.',
  (30, 6): '.',
  (31, 6): '.',
  (32, 6): '.',
  (33, 6): '.',
  (34, 6): '.',
  (35, 6): '.',
  (36, 6): '.',
  (37, 6): '.',
  (38, 6): '#',
  (39, 6): '.',
  (40, 6): '.',
  (41, 6): '.',
  (42, 6): '.',
  (43, 6): '.',
  (44, 6): '#',
  (45, 6): '.',
  (46, 6): '.',
  (47, 6): '.',
  (48, 6): '.',
  (49, 6): '.',
  (50, 6): '.',
  (0, 7): '.',
  (1, 7): '.',
  (2, 7): '.',
  (3, 7): '.',
  (4, 7): '.',
  (5, 7): '.',
  (6, 7): '.',
  (7, 7): '.',
  (8, 7): '.',
  (9, 7): '.',
  (10, 7): '.',
  (11, 7): '.',
  (12, 7): '.',
  (13, 7): '.',
  (14, 7): '.',
  (15, 7): '.',
  (16, 7): '.',
  (17, 7): '.',
  (18, 7): '.',
  (19, 7): '.',
  (20, 7): '.',
  (21, 7): '.',
  (22, 7): '.',
  (23, 7): '.',
  (24, 7): '.',
  (25, 7): '.',
  (26, 7): '.',
  (27, 7): '.',
  (28, 7): '.',
  (29, 7): '.',
  (30, 7): '.',
  (31, 7): '.',
  (32, 7): '.',
  (33, 7): '.',
  (34, 7): '.',
  (35, 7): '.',
  (36, 7): '.',
  (37, 7): '.',
  (38, 7): '#',
  (39, 7): '.',
  (40, 7): '.',
  (41, 7): '.',
  (42, 7): '.',
  (43, 7): '.',
  (44, 7): '#',
  (45, 7): '.',
  (46, 7): '.',
  (47, 7): '.',
  (48, 7): '.',
  (49, 7): '.',
  (50, 7): '.',
  (0, 8): '.',
  (1, 8): '.',
  (2, 8): '.',
  (3, 8): '.',
  (4, 8): '.',
  (5, 8): '.',
  (6, 8): '.',
  (7, 8): '.',
  (8, 8): '.',
  (9, 8): '.',
  (10, 8): '.',
  (11, 8): '.',
  (12, 8): '.',
  (13, 8): '.',
  (14, 8): '#',
  (15, 8): '#',
  (16, 8): '#',
  (17, 8): '#',
  (18, 8): '#',
  (19, 8): '#',
  (20, 8): '#',
  (21, 8): '#',
  (22, 8): '#',
  (23, 8): '.',
  (24, 8): '.',
  (25, 8): '.',
  (26, 8): '.',
  (27, 8): '.',
  (28, 8): '.',
  (29, 8): '.',
  (30, 8): '.',
  (31, 8): '.',
  (32, 8): '#',
  (33, 8): '#',
  (34, 8): '#',
  (35, 8): '#',
  (36, 8): '#',
  (37, 8): '#',
  (38, 8): '#',
  (39, 8): '.',
  (40, 8): '.',
  (41, 8): '.',
  (42, 8): '.',
  (43, 8): '.',
  (44, 8): '#',
  (45, 8): '.',
  (46, 8): '.',
  (47, 8): '.',
  (48, 8): '.',
  (49, 8): '.',
  (50, 8): '.',
  (0, 9): '.',
  (1, 9): '.',
  (2, 9): '.',
  (3, 9): '.',
  (4, 9): '.',
  (5, 9): '.',
  (6, 9): '.',
  (7, 9): '.',
  (8, 9): '.',
  (9, 9): '.',
  (10, 9): '.',
  (11, 9): '.',
  (12, 9): '.',
  (13, 9): '.',
  (14, 9): '.',
  (15, 9): '.',
  (16, 9): '.',
  (17, 9): '.',
  (18, 9): '.',
  (19, 9): '.',
  (20, 9): '.',
  (21, 9): '.',
  (22, 9): '#',
  (23, 9): '.',
  (24, 9): '.',
  (25, 9): '.',
  (26, 9): '.',
  (27, 9): '.',
  (28, 9): '.',
  (29, 9): '.',
  (30, 9): '.',
  (31, 9): '.',
  (32, 9): '#',
  (33, 9): '.',
  (34, 9): '.',
  (35, 9): '.',
  (36, 9): '.',
  (37, 9): '.',
  (38, 9): '.',
  (39, 9): '.',
  (40, 9): '.',
  (41, 9): '.',
  (42, 9): '.',
  (43, 9): '.',
  (44, 9): '#',
  (45, 9): '.',
  (46, 9): '.',
  (47, 9): '.',
  (48, 9): '.',
  (49, 9): '.',
  (50, 9): '.',
  (0, 10): '.',
  (1, 10): '.',
  (2, 10): '.',
  (3, 10): '.',
  (4, 10): '.',
  (5, 10): '.',
  (6, 10): '.',
  (7, 10): '.',
  (8, 10): '.',
  (9, 10): '.',
  (10, 10): '.',
  (11, 10): '.',
  (12, 10): '.',
  (13, 10): '.',
  (14, 10): '.',
  (15, 10): '.',
  (16, 10): '.',
  (17, 10): '.',
  (18, 10): '.',
  (19, 10): '.',
  (20, 10): '.',
  (21, 10): '.',
  (22, 10): '#',
  (23, 10): '.',
  (24, 10): '.',
  (25, 10): '.',
  (26, 10): '.',
  (27, 10): '.',
  (28, 10): '.',
  (29, 10): '.',
  (30, 10): '.',
  (31, 10): '.',
  (32, 10): '#',
  (33, 10): '.',
  (34, 10): '.',
  (35, 10): '.',
  (36, 10): '.',
  (37, 10): '.',
  (38, 10): '.',
  (39, 10): '.',
  (40, 10): '.',
  (41, 10): '.',
  (42, 10): '#',
  (43, 10): '#',
  (44, 10): '#',
  (45, 10): '#',
  (46, 10): '#',
  (47, 10): '#',
  (48, 10): '#',
  (49, 10): '#',
  (50, 10): '#',
  (0, 11): '.',
  (1, 11): '.',
  (2, 11): '.',
  (3, 11): '.',
  (4, 11): '.',
  (5, 11): '.',
  (6, 11): '.',
  (7, 11): '.',
  (8, 11): '.',
  (9, 11): '.',
  (10, 11): '.',
  (11, 11): '.',
  (12, 11): '.',
  (13, 11): '.',
  (14, 11): '.',
  (15, 11): '.',
  (16, 11): '.',
  (17, 11): '.',
  (18, 11): '.',
  (19, 11): '.',
  (20, 11): '.',
  (21, 11): '.',
  (22, 11): '#',
  (23, 11): '.',
  (24, 11): '.',
  (25, 11): '.',
  (26, 11): '.',
  (27, 11): '.',
  (28, 11): '.',
  (29, 11): '.',
  (30, 11): '.',
  (31, 11): '.',
  (32, 11): '#',
  (33, 11): '.',
  (34, 11): '.',
  (35, 11): '.',
  (36, 11): '.',
  (37, 11): '.',
  (38, 11): '.',
  (39, 11): '.',
  (40, 11): '.',
  (41, 11): '.',
  (42, 11): '#',
  (43, 11): '.',
  (44, 11): '#',
  (45, 11): '.',
  (46, 11): '.',
  (47, 11): '.',
  (48, 11): '.',
  (49, 11): '.',
  (50, 11): '#',
  (0, 12): '.',
  (1, 12): '.',
  (2, 12): '.',
  (3, 12): '.',
  (4, 12): '.',
  (5, 12): '.',
  (6, 12): '.',
  (7, 12): '.',
  (8, 12): '.',
  (9, 12): '.',
  (10, 12): '.',
  (11, 12): '.',
  (12, 12): '.',
  (13, 12): '.',
  (14, 12): '.',
  (15, 12): '.',
  (16, 12): '.',
  (17, 12): '.',
  (18, 12): '.',
  (19, 12): '.',
  (20, 12): '.',
  (21, 12): '.',
  (22, 12): '#',
  (23, 12): '.',
  (24, 12): '.',
  (25, 12): '.',
  (26, 12): '.',
  (27, 12): '.',
  (28, 12): '.',
  (29, 12): '.',
  (30, 12): '.',
  (31, 12): '.',
  (32, 12): '#',
  (33, 12): '.',
  (34, 12): '.',
  (35, 12): '.',
  (36, 12): '.',
  (37, 12): '.',
  (38, 12): '#',
  (39, 12): '#',
  (40, 12): '#',
  (41, 12): '#',
  (42, 12): '#',
  (43, 12): '#',
  (44, 12): '#',
  (45, 12): '.',
  (46, 12): '.',
  (47, 12): '.',
  (48, 12): '.',
  (49, 12): '.',
  (50, 12): '#',
  (0, 13): '.',
  (1, 13): '.',
  (2, 13): '.',
  (3, 13): '.',
  (4, 13): '.',
  (5, 13): '.',
  (6, 13): '.',
  (7, 13): '.',
  (8, 13): '.',
  (9, 13): '.',
  (10, 13): '.',
  (11, 13): '.',
  (12, 13): '.',
  (13, 13): '.',
  (14, 13): '.',
  (15, 13): '.',
  (16, 13): '.',
  (17, 13): '.',
  (18, 13): '.',
  (19, 13): '.',
  (20, 13): '.',
  (21, 13): '.',
  (22, 13): '#',
  (23, 13): '.',
  (24, 13): '.',
  (25, 13): '.',
  (26, 13): '.',
  (27, 13): '.',
  (28, 13): '.',
  (29, 13): '.',
  (30, 13): '.',
  (31, 13): '.',
  (32, 13): '#',
  (33, 13): '.',
  (34, 13): '.',
  (35, 13): '.',
  (36, 13): '.',
  (37, 13): '.',
  (38, 13): '#',
  (39, 13): '.',
  (40, 13): '.',
  (41, 13): '.',
  (42, 13): '#',
  (43, 13): '.',
  (44, 13): '.',
  (45, 13): '.',
  (46, 13): '.',
  (47, 13): '.',
  (48, 13): '.',
  (49, 13): '.',
  (50, 13): '#',
  (0, 14): '.',
  (1, 14): '.',
  (2, 14): '.',
  (3, 14): '.',
  (4, 14): '.',
  (5, 14): '.',
  (6, 14): '.',
  (7, 14): '.',
  (8, 14): '.',
  (9, 14): '.',
  (10, 14): '.',
  (11, 14): '.',
  (12, 14): '.',
  (13, 14): '.',
  (14, 14): '.',
  (15, 14): '.',
  (16, 14): '.',
  (17, 14): '.',
  (18, 14): '.',
  (19, 14): '.',
  (20, 14): '.',
  (21, 14): '.',
  (22, 14): '#',
  (23, 14): '#',
  (24, 14): '#',
  (25, 14): '#',
  (26, 14): '#',
  (27, 14): '#',
  (28, 14): '#',
  (29, 14): '#',
  (30, 14): '#',
  (31, 14): '#',
  (32, 14): '#',
  (33, 14): '#',
  (34, 14): '#',
  (35, 14): '.',
  (36, 14): '.',
  (37, 14): '.',
  (38, 14): '#',
  (39, 14): '.',
  (40, 14): '.',
  (41, 14): '.',
  (42, 14): '#',
  (43, 14): '.',
  (44, 14): '.',
  (45, 14): '.',
  (46, 14): '.',
  (47, 14): '.',
  (48, 14): '.',
  (49, 14): '.',
  (50, 14): '#',
  (0, 15): '.',
  (1, 15): '.',
  (2, 15): '.',
  (3, 15): '.',
  (4, 15): '.',
  (5, 15): '.',
  (6, 15): '.',
  (7, 15): '.',
  (8, 15): '.',
  (9, 15): '.',
  (10, 15): '.',
  (11, 15): '.',
  (12, 15): '.',
  (13, 15): '.',
  (14, 15): '.',
  (15, 15): '.',
  (16, 15): '.',
  (17, 15): '.',
  (18, 15): '.',
  (19, 15): '.',
  (20, 15): '.',
  (21, 15): '.',
  (22, 15): '.',
  (23, 15): '.',
  (24, 15): '.',
  (25, 15): '.',
  (26, 15): '.',
  (27, 15): '.',
  (28, 15): '.',
  (29, 15): '.',
  (30, 15): '.',
  (31, 15): '.',
  (32, 15): '#',
  (33, 15): '.',
  (34, 15): '#',
  (35, 15): '.',
  (36, 15): '.',
  (37, 15): '.',
  (38, 15): '#',
  (39, 15): '.',
  (40, 15): '.',
  (41, 15): '.',
  (42, 15): '#',
  (43, 15): '.',
  (44, 15): '.',
  (45, 15): '.',
  (46, 15): '.',
  (47, 15): '.',
  (48, 15): '.',
  (49, 15): '.',
  (50, 15): '#',
  (0, 16): '#',
  (1, 16): '#',
  (2, 16): '#',
  (3, 16): '#',
  (4, 16): '#',
  (5, 16): '#',
  (6, 16): '#',
  (7, 16): '#',
  (8, 16): '#',
  (9, 16): '#',
  (10, 16): '#',
  (11, 16): '#',
  (12, 16): '^',
  (13, 16): '.',
  (14, 16): '.',
  (15, 16): '.',
  (16, 16): '.',
  (17, 16): '.',
  (18, 16): '.',
  (19, 16): '.',
  (20, 16): '.',
  (21, 16): '.',
  (22, 16): '.',
  (23, 16): '.',
  (24, 16): '.',
  (25, 16): '.',
  (26, 16): '.',
  (27, 16): '.',
  (28, 16): '.',
  (29, 16): '.',
  (30, 16): '.',
  (31, 16): '.',
  (32, 16): '#',
  (33, 16): '#',
  (34, 16): '#',
  (35, 16): '#',
  (36, 16): '#',
  (37, 16): '#',
  (38, 16): '#',
  (39, 16): '#',
  (40, 16): '#',
  (41, 16): '.',
  (42, 16): '#',
  (43, 16): '.',
  (44, 16): '.',
  (45, 16): '.',
  (46, 16): '.',
  (47, 16): '.',
  (48, 16): '.',
  (49, 16): '.',
  (50, 16): '#',
  (0, 17): '#',
  (1, 17): '.',
  (2, 17): '.',
  (3, 17): '.',
  (4, 17): '.',
  (5, 17): '.',
  (6, 17): '.',
  (7, 17): '.',
  (8, 17): '.',
  (9, 17): '.',
  (10, 17): '.',
  (11, 17): '.',
  (12, 17): '.',
  (13, 17): '.',
  (14, 17): '.',
  (15, 17): '.',
  (16, 17): '.',
  (17, 17): '.',
  (18, 17): '.',
  (19, 17): '.',
  (20, 17): '.',
  (21, 17): '.',
  (22, 17): '.',
  (23, 17): '.',
  (24, 17): '.',
  (25, 17): '.',
  (26, 17): '.',
  (27, 17): '.',
  (28, 17): '.',
  (29, 17): '.',
  (30, 17): '.',
  (31, 17): '.',
  (32, 17): '.',
  (33, 17): '.',
  (34, 17): '#',
  (35, 17): '.',
  (36, 17): '.',
  (37, 17): '.',
  (38, 17): '#',
  (39, 17): '.',
  (40, 17): '#',
  (41, 17): '.',
  (42, 17): '#',
  (43, 17): '.',
  (44, 17): '.',
  (45, 17): '.',
  (46, 17): '.',
  (47, 17): '.',
  (48, 17): '.',
  (49, 17): '.',
  (50, 17): '#',
  (0, 18): '#',
  (1, 18): '.',
  (2, 18): '.',
  (3, 18): '.',
  (4, 18): '.',
  (5, 18): '.',
  (6, 18): '.',
  (7, 18): '.',
  (8, 18): '.',
  (9, 18): '.',
  (10, 18): '.',
  (11, 18): '.',
  (12, 18): '.',
  (13, 18): '.',
  (14, 18): '.',
  (15, 18): '.',
  (16, 18): '.',
  (17, 18): '.',
  (18, 18): '#',
  (19, 18): '#',
  (20, 18): '#',
  (21, 18): '#',
  (22, 18): '#',
  (23, 18): '#',
  (24, 18): '#',
  (25, 18): '.',
  (26, 18): '.',
  (27, 18): '.',
  (28, 18): '.',
  (29, 18): '.',
  (30, 18): '.',
  (31, 18): '.',
  (32, 18): '.',
  (33, 18): '.',
  (34, 18): '#',
  (35, 18): '.',
  (36, 18): '.',
  (37, 18): '.',
  (38, 18): '#',
  (39, 18): '#',
  (40, 18): '#',
  (41, 18): '#',
  (42, 18): '#',
  (43, 18): '.',
  (44, 18): '#',
  (45, 18): '#',
  (46, 18): '#',
  (47, 18): '#',
  (48, 18): '#',
  (49, 18): '#',
  (50, 18): '#',
  (0, 19): '#',
  (1, 19): '.',
  (2, 19): '.',
  (3, 19): '.',
  (4, 19): '.',
  (5, 19): '.',
  (6, 19): '.',
  (7, 19): '.',
  (8, 19): '.',
  (9, 19): '.',
  (10, 19): '.',
  (11, 19): '.',
  (12, 19): '.',
  (13, 19): '.',
  (14, 19): '.',
  (15, 19): '.',
  (16, 19): '.',
  (17, 19): '.',
  (18, 19): '#',
  (19, 19): '.',
  (20, 19): '.',
  (21, 19): '.',
  (22, 19): '.',
  (23, 19): '.',
  (24, 19): '#',
  (25, 19): '.',
  (26, 19): '.',
  (27, 19): '.',
  (28, 19): '.',
  (29, 19): '.',
  (30, 19): '.',
  ...})
In [64]:
testinput="""..#..........
..#..........
#######...###
#.#...#...#.#
#############
..#...#...#..
..#####...^.."""

grid = {}
x = 0
y = 0
for char in testinput:
    grid[(x, y)] = char
    if char == '\n':
        y += 1
        x = 0
    else:
        x += 1

total = 0

for (x, y), c in grid.items():

    if c == '#' and grid.get((x + 1, y)) == '#' and grid.get((x - 1, y)) == '#' and grid.get((x, y + 1)) == '#' and grid.get((x, y - 1)) == '#':
        total += x * y
        print(f" {x}, {y} o ", end='')
    else:
        print(f" {x}, {y} {c} ", end = '')

print()
print(total)
 0, 0 .  1, 0 .  2, 0 #  3, 0 .  4, 0 .  5, 0 .  6, 0 .  7, 0 .  8, 0 .  9, 0 .  10, 0 .  11, 0 .  12, 0 .  13, 0 
  0, 1 .  1, 1 .  2, 1 #  3, 1 .  4, 1 .  5, 1 .  6, 1 .  7, 1 .  8, 1 .  9, 1 .  10, 1 .  11, 1 .  12, 1 .  13, 1 
  0, 2 #  1, 2 #  2, 2 o  3, 2 #  4, 2 #  5, 2 #  6, 2 #  7, 2 .  8, 2 .  9, 2 .  10, 2 #  11, 2 #  12, 2 #  13, 2 
  0, 3 #  1, 3 .  2, 3 #  3, 3 .  4, 3 .  5, 3 .  6, 3 #  7, 3 .  8, 3 .  9, 3 .  10, 3 #  11, 3 .  12, 3 #  13, 3 
  0, 4 #  1, 4 #  2, 4 o  3, 4 #  4, 4 #  5, 4 #  6, 4 o  7, 4 #  8, 4 #  9, 4 #  10, 4 o  11, 4 #  12, 4 #  13, 4 
  0, 5 .  1, 5 .  2, 5 #  3, 5 .  4, 5 .  5, 5 .  6, 5 #  7, 5 .  8, 5 .  9, 5 .  10, 5 #  11, 5 .  12, 5 .  13, 5 
  0, 6 .  1, 6 .  2, 6 #  3, 6 #  4, 6 #  5, 6 #  6, 6 #  7, 6 .  8, 6 .  9, 6 .  10, 6 ^  11, 6 .  12, 6 . 
76
In [123]:
grid = soln()[1]
......................................#######......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
..............#########.........#######.....#......
......................#.........#...........#......
......................#.........#.........##o######
......................#.........#.........#.#.....#
......................#.........#.....####o##.....#
......................#.........#.....#...#.......#
......................##########o##...#...#.......#
................................#.#...#...#.......#
############^...................##o###o##.#.......#
#.................................#...#.#.#.......#
#.................#######.........#...##o##.#######
#.................#.....#.........#.....#...#......
#...............##o##...#.........#######...#......
#...............#.#.#...#...................#......
#########.......#.##o###o##.................#......
........#.......#...#...#.#.................#......
........#.......#...#...##o##########.......#......
........#.......#...#.....#.........#.......#......
........#.....##o####.....#.........#.......#......
........#.....#.#.........#.........#.......#......
........######o##.........#.........#.......#......
..............#...........#.........#.......#......
..............#.....#######.........#########......
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#######..............................
[(44, 10), (42, 12), (32, 14), (34, 16), (38, 16), (40, 18), (18, 20), (20, 22), (24, 22), (26, 24), (16, 26), (14, 28)] [440, 504, 448, 544, 608, 720, 360, 440, 528, 624, 416, 392] 6024
In [145]:
bot = None
for (x, y), ch in grid.items():
    if ch != '.' and ch != '#':
        bot = (x, y)
        d = ch
        break


dirs = {'^': (0, -1), '<': (-1, 0), 'v': (0, 1), '>': (1, 0)}
inv = { '^': 'v', 'v': '^', '<': '>', '>': '<' }

turns = {
    ('^', '>'): 'R',
    ('^', '<'): 'L',
    ('v', '<'): 'R',
    ('v', '>'): 'L',
    ('>', 'v'): 'R',
    ('>', '^'): 'L',
    ('<', '^'): 'R',
    ('<', 'v'): 'L',
}

def dsum(a, b):
    return a[0] + b[0], a[1] + b[1]
    
path = []
current = 0
while True:
    if grid.get(dsum(bot, dirs[d])) != '#':
        for dd in dirs:
            if d != dd and d != inv[dd] and grid.get(dsum(bot, dirs[dd])) == '#':
                path.append(str(current))
                current = 0
                path.append(turns.get((d, dd)))
                d = dd
                break
        if grid.get(dsum(bot, dirs[d])) != '#':
            path.append(str(current))
            break
    else:
        current += 1
        bot = dsum(bot, dirs[d])

" ".join(path)
Out[145]:
'0 L 12 L 6 L 8 R 6 L 8 L 8 R 4 R 6 R 6 L 12 L 6 L 8 R 6 L 8 L 8 R 4 R 6 R 6 L 12 R 6 L 8 L 12 R 6 L 8 L 8 L 8 R 4 R 6 R 6 L 12 L 6 L 8 R 6 L 8 L 8 R 4 R 6 R 6 L 12 R 6 L 8'
In [152]:
def part2():
    listing = process(readfile("AoC/input17.txt").strip())
    listing[0] = 2
    program = compute(listing)

    while (ch := next(program)):
        print(chr(ch), end='')

    inputs = [
        "A,B,A,B,C,C,B,A,B,C",
        "L,6,6,L,6,L,8,R,6",
        "L,8,L,8,R,4,R,6,R,6",
        "L,6,6,R,6,L,8",
        "n",
    ]

    for i in inputs:
        for ch in i:
            print(f"> {ch}: {ord(ch)}")
            r = program.send(ord(ch))
            if r:
                print(f"Received '{chr(r)}'")

        print(chr(program.send(ord('\n'))), end='')
        while (ch := next(program)):
            if ch < 128:
                print(chr(ch), end='')
            else:
                print(ch)

path = """
L 12 L 6 L 8 R 6   L 8 L 8 R 4 R 6 R 6 
L 12 L 6 L 8 R 6   L 8 L 8 R 4 R 6 R 6 
L 12 R 6 L 8 
L 12 R 6 L 8       L 8 L 8 R 4 R 6 R 6 
L 12 L 6 L 8 R 6   L 8 L 8 R 4 R 6 R 6 
L 12 R 6 L 8"""

part2()
......................................#######......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
..............#########.........#######.....#......
......................#.........#...........#......
......................#.........#.........#########
......................#.........#.........#.#.....#
......................#.........#.....#######.....#
......................#.........#.....#...#.......#
......................#############...#...#.......#
................................#.#...#...#.......#
############^...................#########.#.......#
#.................................#...#.#.#.......#
#.................#######.........#...#####.#######
#.................#.....#.........#.....#...#......
#...............#####...#.........#######...#......
#...............#.#.#...#...................#......
#########.......#.#########.................#......
........#.......#...#...#.#.................#......
........#.......#...#...#############.......#......
........#.......#...#.....#.........#.......#......
........#.....#######.....#.........#.......#......
........#.....#.#.........#.........#.......#......
........#########.........#.........#.......#......
..............#...........#.........#.......#......
..............#.....#######.........#########......
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#######..............................

Main:
> A: 65
> ,: 44
> B: 66
> ,: 44
> A: 65
> ,: 44
> B: 66
> ,: 44
> C: 67
> ,: 44
> C: 67
> ,: 44
> B: 66
> ,: 44
> A: 65
> ,: 44
> B: 66
> ,: 44
> C: 67
Function A:
> L: 76
> ,: 44
> 6: 54
> ,: 44
> 6: 54
> ,: 44
> L: 76
> ,: 44
> 6: 54
> ,: 44
> L: 76
> ,: 44
> 8: 56
> ,: 44
> R: 82
> ,: 44
> 6: 54
Function B:
> L: 76
> ,: 44
> 8: 56
> ,: 44
> L: 76
> ,: 44
> 8: 56
> ,: 44
> R: 82
> ,: 44
> 4: 52
> ,: 44
> R: 82
> ,: 44
> 6: 54
> ,: 44
> R: 82
> ,: 44
> 6: 54
Function C:
> L: 76
> ,: 44
> 6: 54
> ,: 44
> 6: 54
> ,: 44
> R: 82
> ,: 44
> 6: 54
> ,: 44
> L: 76
> ,: 44
> 8: 56
Continuous video feed?
> n: 110

......................................#######......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
......................................#.....#......
..............<########.........#######.....#......
......................#.........#...........#......
......................#.........#.........#########
......................#.........#.........#.#.....#
......................#.........#.....#######.....#
......................#.........#.....#...#.......#
......................#############...#...#.......#
................................#.#...#...#.......#
#############...................#########.#.......#
#.................................#...#.#.#.......#
#.................#######.........#...#####.#######
#.................#.....#.........#.....#...#......
#...............#####...#.........#######...#......
#...............#.#.#...#...................#......
#########.......#.#########.................#......
........#.......#...#...#.#.................#......
........#.......#...#...#############.......#......
........#.......#...#.....#.........#.......#......
........#.....#######.....#.........#.......#......
........#.....#.#.........#.........#.......#......
........#########.........#.........#.......#......
..............#...........#.........#.......#......
..............#.....#######.........#########......
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#.....#..............................
..............#######..............................

897344

StopIterationTraceback (most recent call last)
<ipython-input-152-a25944a051ba> in <module>
     45 L 12 R 6 L 8"""
     46 
---> 47 part2()

<ipython-input-152-a25944a051ba> in part2()
     23 
     24         print(chr(program.send(ord('\n'))), end='')
---> 25         while (ch := next(program)):
     26             if ch < 128:
     27                 print(chr(ch), end='')

StopIteration: 
In [ ]: