diff --git a/2019/17/script.py b/2019/17/script.py new file mode 100644 index 0000000..0653a67 --- /dev/null +++ b/2019/17/script.py @@ -0,0 +1,103 @@ +from GhostyUtils import aoc +from GhostyUtils.intcode.cpu import IntCode +from GhostyUtils.grid import Grid +from GhostyUtils.vec2 import Vec2, Dir +import math + + +class Video: + def __init__(self): + self.str_frame = [] + self.frame = None + + def input(self, v: int): + # part 2 we get a large value when the robot stops + if v > 255: + print('p2:', v) + + self.str_frame.append(chr(v)) + if self.str_frame[-2:] == ['\n', '\n']: + # skipping the final \n\n with the [:-2] + frame = ''.join(px for px in self.str_frame[:-2]) + self.frame = Grid(frame.split('\n')) + # print(self.frame) + + +def build_path(grid: Grid): + start = grid.find('^') + path = [(start, Dir.UP)] + while True: + cur_pos, move_dir = path[-1] + cur_pos = Vec2(cur_pos) + + # try forward first + next_pos = tuple(cur_pos + move_dir) + if grid.in_bounds(next_pos) and grid[next_pos] == '#': + path.append((next_pos, move_dir)) + continue + + # try left + next_pos = tuple(cur_pos + move_dir.turn_left()) + if grid.in_bounds(next_pos) and grid[next_pos] == '#': + path.append((next_pos, move_dir.turn_left())) + continue + + # try right + next_pos = tuple(cur_pos + move_dir.turn_right()) + if grid.in_bounds(next_pos) and grid[next_pos] == '#': + path.append((next_pos, move_dir.turn_right())) + continue + + # no more valid moves, we've reached the end + moves = [] + for first, second in zip(path, path[1:]): + if first[1].turn_left() == second[1]: + moves.append('L') + if first[1].turn_right() == second[1]: + moves.append('R') + if type(moves[-1]) is int: + moves[-1] += 1 + else: + moves.append(1) + return ','.join(str(m) for m in moves) + + +class Controls: + def __init__(self, grid: Grid): + # path = build_path(grid) + # print(path) + # R,12,L,6,R,12,L,8,L,6,L,10,R,12,L,6,R,12,R,12,L,10,L,6,R,10,L,8,L,6,L,10,R,12,L,10,L,6,R,10,L,8,L,6,L,10,R,12,L,10,L,6,R,10,R,12,L,6,R,12,R,12,L,10,L,6,R,10 + + # controls created by vim's / pattern highlighting of above! + self.controls = ( + 'A,B,A,C,B,C,B,C,A,C\n' + 'R,12,L,6,R,12\n' + 'L,8,L,6,L,10\n' + 'R,12,L,10,L,6,R,10\n' + 'n\n' + ) + self.iter = iter(self.controls) + + def __call__(self): + return ord(next(self.iter)) + + +def main(): + video = Video() + cpu = IntCode(aoc.read(), output=video.input) + cpu.process() + + scaffolds = video.frame.find_all('#') + alignment_sum = 0 + for scaf in scaffolds: + if all(video.frame[n] == '#' for n in video.frame.neighbours(scaf, diagonal=False)): + alignment_sum += math.prod(scaf) + print('p1:', alignment_sum) + + cpu = IntCode(aoc.read(), input=Controls(video.frame), output=video.input) + cpu.memory[0] = 2 + cpu.process() + + +if __name__ == "__main__": + main() diff --git a/utils/GhostyUtils/vec2.py b/utils/GhostyUtils/vec2.py index 472a661..5c21877 100644 --- a/utils/GhostyUtils/vec2.py +++ b/utils/GhostyUtils/vec2.py @@ -1,6 +1,7 @@ from enum import Enum from typing import Union, Sequence import math +from itertools import cycle VecDataType = Union[int, float] VecTupleType = Union['_Vec', tuple] @@ -253,6 +254,14 @@ def as_vec2(self) -> Vec2: def as_tuple(self) -> tuple: return self.value + def turn_left(self) -> 'Dir': + turns = Dir.map_udlr([Dir.RIGHT, Dir.LEFT, Dir.UP, Dir.DOWN]) + return turns[self] + + def turn_right(self) -> 'Dir': + turns = Dir.map_udlr([Dir.LEFT, Dir.RIGHT, Dir.DOWN, Dir.UP]) + return turns[self] + def manhattan_distance(start: VecTupleType, end: VecTupleType) -> int: return Vec2.manhattan_distance(start, end) diff --git a/utils/tests/test_vec2.py b/utils/tests/test_vec2.py index 1c4ab79..8ce5ee8 100644 --- a/utils/tests/test_vec2.py +++ b/utils/tests/test_vec2.py @@ -70,10 +70,13 @@ def test_unit(): assert abs(Vec2(98, -34).unit()) == 1.0 -def test_dir(): +def test_dir_values(): assert Dir.UP is Dir.NORTH and Dir.UP == Dir.NORTH assert Dir.UP is not Dir.SOUTH assert Dir.NORTH.value == (0, -1) == Vec2(0, -1) == Vec2(Dir.NORTH) + + +def test_dir_map(): assert Dir.map_udlr('^v<>') == { '^': Dir.UP, 'v': Dir.DOWN, @@ -86,10 +89,18 @@ def test_dir(): 'W': Dir.WEST, 'E': Dir.EAST, } + + +def test_dir_flip(): assert Dir.UP.flipped() == Dir.DOWN == Dir.SOUTH assert Dir.LEFT.flipped() == Dir.RIGHT == Dir.EAST +def test_dir_turn(): + assert Dir.UP.turn_left() == Dir.LEFT == Dir.WEST + assert Dir.UP.turn_right() == Dir.RIGHT == Dir.EAST + + def test_dir_vec2(): assert Vec2(10, 10) + Dir.UP == Vec2(10, 9) assert Vec2(10, 10) - Dir.UP == Vec2(10, 11)