2018: d10: ex1: add solution
This commit is contained in:
parent
23a1ec49d2
commit
e2fabb127d
65
2018/d10/ex1/ex1.py
Executable file
65
2018/d10/ex1/ex1.py
Executable file
|
@ -0,0 +1,65 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import itertools
|
||||||
|
import sys
|
||||||
|
from typing import NamedTuple
|
||||||
|
|
||||||
|
|
||||||
|
class Point(NamedTuple):
|
||||||
|
x: int
|
||||||
|
y: int
|
||||||
|
|
||||||
|
|
||||||
|
class Light(NamedTuple):
|
||||||
|
pos: Point
|
||||||
|
vel: Point
|
||||||
|
|
||||||
|
def at(self, time: int) -> Point:
|
||||||
|
return Point(self.pos.x + self.vel.x * time, self.pos.y + self.vel.y * time)
|
||||||
|
|
||||||
|
|
||||||
|
def solve(input: str) -> str:
|
||||||
|
def parse_light(input: str) -> Light:
|
||||||
|
pos, vel = map(lambda s: s.split("=<")[1].removesuffix(">"), input.split("> "))
|
||||||
|
return Light(
|
||||||
|
Point(*map(int, map(str.strip, pos.split(",")))),
|
||||||
|
Point(*map(int, map(str.strip, vel.split(",")))),
|
||||||
|
)
|
||||||
|
|
||||||
|
def parse(input: list[str]) -> list[Light]:
|
||||||
|
return [parse_light(line) for line in input]
|
||||||
|
|
||||||
|
def move_lights(lights: list[Light], time: int) -> set[Point]:
|
||||||
|
return {l.at(time) for l in lights}
|
||||||
|
|
||||||
|
def bbox_size(points: set[Point]) -> int:
|
||||||
|
min_x, max_x = min(p.x for p in points), max(p.x for p in points)
|
||||||
|
min_y, max_y = min(p.y for p in points), max(p.y for p in points)
|
||||||
|
return (max_x - min_x + 1) * (max_y - min_y + 1)
|
||||||
|
|
||||||
|
def write_message(message: set[Point]) -> str:
|
||||||
|
min_x, max_x = min(p.x for p in message), max(p.x for p in message)
|
||||||
|
min_y, max_y = min(p.y for p in message), max(p.y for p in message)
|
||||||
|
|
||||||
|
return "\n".join(
|
||||||
|
"".join(
|
||||||
|
"#" if Point(x, y) in message else "." for x in range(min_x, max_x + 1)
|
||||||
|
)
|
||||||
|
for y in range(min_y, max_y + 1)
|
||||||
|
)
|
||||||
|
|
||||||
|
lights = parse(input.splitlines())
|
||||||
|
max_time = max(
|
||||||
|
map(abs, itertools.chain.from_iterable((l.pos.x, l.pos.y) for l in lights))
|
||||||
|
)
|
||||||
|
message = min((move_lights(lights, t) for t in range(max_time)), key=bbox_size)
|
||||||
|
return write_message(message)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
input = sys.stdin.read()
|
||||||
|
print(solve(input))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in a new issue