119 lines
2.6 KiB
Python
119 lines
2.6 KiB
Python
from dataclasses import dataclass
|
|
from typing import Optional
|
|
|
|
from cpl_core.console import Console
|
|
from cpl_core.utils import String
|
|
from cpl_query.enumerable import Enumerable
|
|
from cpl_query.extension import List
|
|
from cpl_core.pipes import *
|
|
|
|
from aoc.aoc import get_input
|
|
|
|
# global vars
|
|
day = 9
|
|
aoc_input = get_input(2022, day)
|
|
aoc_input1 = """R 5
|
|
U 8
|
|
L 8
|
|
D 3
|
|
R 17
|
|
D 10
|
|
L 25
|
|
U 20"""
|
|
|
|
|
|
@dataclass
|
|
class Position:
|
|
x: int = 0
|
|
y: int = 0
|
|
|
|
def __repr__(self):
|
|
return f'({self.x}, {self.y})'
|
|
|
|
@property
|
|
def as_tuple(self) -> tuple[int, int]:
|
|
return self.x, self.y
|
|
|
|
|
|
def get_new_tail(head: Position, tail: Position) -> Position:
|
|
diff = Position(head.x - tail.x, head.y - tail.y)
|
|
bias = Position(0 if diff.x == 0 else int(diff.x / abs(diff.x)), 0 if diff.y == 0 else int(diff.y / abs(diff.y)))
|
|
|
|
if abs(diff.x) <= 1 and abs(diff.y) <= 1:
|
|
return tail
|
|
|
|
return Position(tail.x + bias.x, tail.y + bias.y)
|
|
|
|
|
|
def part1():
|
|
head = Position(0, 0)
|
|
tail = Position(0, 0)
|
|
start = Position(0, 0)
|
|
|
|
steps = {tail.as_tuple}
|
|
|
|
for line in aoc_input.splitlines():
|
|
step, width = line.split()
|
|
for i in range(0, int(width)):
|
|
match step:
|
|
case 'R':
|
|
head.x += 1
|
|
|
|
case 'L':
|
|
head.x -= 1
|
|
|
|
case 'U':
|
|
head.y += 1
|
|
|
|
case 'D':
|
|
head.y -= 1
|
|
|
|
tail = get_new_tail(head, tail)
|
|
steps.add(tail.as_tuple)
|
|
|
|
Console.write_line(start, head, tail)
|
|
Console.write_line(len(steps), steps)
|
|
|
|
|
|
def part2():
|
|
head = Position(0, 0)
|
|
tails = List(int).range(0, 9).select(lambda x: Position(0, 0))
|
|
|
|
steps = {tails.last().as_tuple}
|
|
|
|
for line in aoc_input.splitlines():
|
|
step, width = line.split()
|
|
for i in range(0, int(width)):
|
|
match step:
|
|
case 'R':
|
|
head.x += 1
|
|
|
|
case 'L':
|
|
head.x -= 1
|
|
|
|
case 'U':
|
|
head.y += 1
|
|
|
|
case 'D':
|
|
head.y -= 1
|
|
|
|
last_t = head
|
|
new_tails = List(Position)
|
|
for t in tails.to_list():
|
|
new_t = get_new_tail(last_t, t)
|
|
new_tails.add(new_t)
|
|
last_t = new_t
|
|
|
|
tails = new_tails
|
|
steps.add(tails.last().as_tuple)
|
|
|
|
Console.write_line(head, tails.last())
|
|
Console.write_line(len(steps), steps)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
Console.write_line(f'Advent of code day {day}')
|
|
part1()
|
|
part2()
|
|
Console.write_line()
|