mirror of
https://github.com/cupcakearmy/advent-of-code.git
synced 2024-12-21 15:46:28 +00:00
05
This commit is contained in:
parent
1a4f7a5441
commit
6c517b47d9
11
2021/05/README.md
Normal file
11
2021/05/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# 05
|
||||
|
||||
Description
|
||||
|
||||
<details>
|
||||
<summary>Solutions</summary>
|
||||
<ol>
|
||||
<li>5608</li>
|
||||
<li>20299</li>
|
||||
</ol>
|
||||
</details>
|
141
2021/05/python/main.py
Normal file
141
2021/05/python/main.py
Normal file
@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from os.path import join, dirname
|
||||
from typing import List
|
||||
|
||||
# Day 05
|
||||
|
||||
# Common
|
||||
|
||||
|
||||
def read_input(filename):
|
||||
data = join(dirname(__file__), '..', filename)
|
||||
with open(data) as f:
|
||||
return f.read().strip()
|
||||
|
||||
|
||||
class Point:
|
||||
def __init__(self, x, y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'({self.x},{self.y})'
|
||||
|
||||
@staticmethod
|
||||
def parse(raw: str):
|
||||
x, y = raw.strip().split(',')
|
||||
return Point(int(x), int(y))
|
||||
|
||||
|
||||
class Line:
|
||||
def __init__(self, a: Point, b: Point):
|
||||
self.a = a
|
||||
self.b = b
|
||||
|
||||
def is_straight(self) -> bool:
|
||||
return self.a.x == self.b.x or self.a.y == self.b.y
|
||||
|
||||
def is_diagonal(self) -> bool:
|
||||
return abs(self.a.x - self.b.x) == abs(self.a.y - self.b.y)
|
||||
|
||||
def get_points(self) -> List[Point]:
|
||||
if self.is_straight():
|
||||
if self.a.x == self.b.x:
|
||||
return [
|
||||
Point(self.a.x, y) for y
|
||||
in range(min(self.a.y, self.b.y), max(self.a.y, self.b.y) + 1)
|
||||
]
|
||||
else:
|
||||
return [
|
||||
Point(x, self.a.y) for x
|
||||
in range(min(self.a.x, self.b.x), max(self.a.x, self.b.x) + 1)
|
||||
]
|
||||
else:
|
||||
dx = self.a.x - self.b.x
|
||||
dy = self.a.y - self.b.y
|
||||
sign_x = 1 if dx < 0 else -1
|
||||
sign_y = 1 if dy < 0 else -1
|
||||
return [
|
||||
Point(self.a.x + sign_x * i, self.a.y + sign_y * i)
|
||||
for i in range(abs(dx) + 1)
|
||||
]
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'{self.a} → {self.b}'
|
||||
|
||||
@staticmethod
|
||||
def parse(raw: str):
|
||||
a, b = raw.strip().split('->')
|
||||
return Line(Point.parse(a), Point.parse(b))
|
||||
|
||||
|
||||
class Scan:
|
||||
def __init__(self, lines: List[Line]):
|
||||
self.lines = lines
|
||||
|
||||
def keep_straight(self):
|
||||
self.lines = [line for line in self.lines if line.is_straight()]
|
||||
|
||||
def keep_straight_and_diagonal(self):
|
||||
self.lines = [
|
||||
line for line in self.lines
|
||||
if line.is_straight() or line.is_diagonal()
|
||||
]
|
||||
|
||||
def matrix(self) -> List[List[int]]:
|
||||
x_max = max(max(line.a.x, line.b.x) for line in self.lines)
|
||||
y_max = max(max(line.a.y, line.b.y) for line in self.lines)
|
||||
matrix = [
|
||||
[0 for _ in range(x_max + 1)]
|
||||
for _ in range(y_max + 1)
|
||||
]
|
||||
for line in self.lines:
|
||||
for point in line.get_points():
|
||||
matrix[point.y][point.x] += 1
|
||||
return matrix
|
||||
|
||||
def plot(self) -> str:
|
||||
output = '\n'.join([
|
||||
' '.join(str(x) for x in row)
|
||||
for row in self.matrix()
|
||||
])
|
||||
return output.replace('0', '.')
|
||||
|
||||
def danger(self) -> int:
|
||||
matrix = self.matrix()
|
||||
return sum(
|
||||
sum(1 for x in row if x > 1)
|
||||
for row in matrix
|
||||
)
|
||||
|
||||
@ staticmethod
|
||||
def parse(raw: str):
|
||||
return Scan([Line.parse(line) for line in raw.strip().split('\n')])
|
||||
|
||||
|
||||
test = read_input('test.txt')
|
||||
data = read_input('input.txt')
|
||||
|
||||
# 1
|
||||
print('1.')
|
||||
scan = Scan.parse(test)
|
||||
scan.keep_straight()
|
||||
print(scan.plot())
|
||||
print('Test: ', scan.danger())
|
||||
|
||||
scan = Scan.parse(data)
|
||||
scan.keep_straight()
|
||||
print('Real: ', scan.danger())
|
||||
|
||||
# 2
|
||||
print('\n2.')
|
||||
|
||||
scan = Scan.parse(test)
|
||||
scan.keep_straight_and_diagonal()
|
||||
print(scan.plot())
|
||||
print('Test: ', scan.danger())
|
||||
|
||||
scan = Scan.parse(data)
|
||||
scan.keep_straight_and_diagonal()
|
||||
print('Real: ', scan.danger())
|
Loading…
Reference in New Issue
Block a user