mirror of
https://github.com/cupcakearmy/advent-of-code.git
synced 2024-12-21 23:56:30 +00:00
11
This commit is contained in:
parent
595f29703f
commit
5b297b00ef
12
solutions/11/README.md
Normal file
12
solutions/11/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
# 11
|
||||
|
||||
Today: Game of life, but a bit different :)
|
||||
I lost so much time because I missed that in the second part we now require 5 instead of 4 occupied seats 😩
|
||||
|
||||
<details>
|
||||
<summary>Solutions</summary>
|
||||
<ol>
|
||||
<li>2296</li>
|
||||
<li>2089</li>
|
||||
</ol>
|
||||
</details>
|
99
solutions/11/python/main.py
Normal file
99
solutions/11/python/main.py
Normal file
@ -0,0 +1,99 @@
|
||||
from os.path import join, dirname
|
||||
from typing import List, Optional
|
||||
from itertools import product
|
||||
from copy import deepcopy
|
||||
|
||||
TSeats = List[List[Optional[bool]]]
|
||||
|
||||
mapping = {
|
||||
'.': None,
|
||||
'#': True,
|
||||
'L': False
|
||||
}
|
||||
inv = {v: k for k, v in mapping.items()}
|
||||
|
||||
|
||||
class Seats:
|
||||
p = [-1, 0, 1]
|
||||
|
||||
def __init__(self, plan: str, alt: bool = False) -> None:
|
||||
self.seats: TSeats = [
|
||||
[
|
||||
mapping[seat]
|
||||
for seat in row
|
||||
]
|
||||
for row in plan.strip().split('\n')
|
||||
]
|
||||
self.max_x = len(self.seats[0])
|
||||
self.max_y = len(self.seats)
|
||||
self.alt = alt
|
||||
|
||||
def __str__(self) -> str:
|
||||
return '\n'.join([
|
||||
''.join([inv[seat] for seat in row])
|
||||
for row in self.seats
|
||||
])
|
||||
|
||||
def find_next_in_direction(self, y: int, x: int, dy: int, dx: int) -> Optional[bool]:
|
||||
y += dy
|
||||
x += dx
|
||||
while 0 <= x < self.max_x and 0 <= y < self.max_y:
|
||||
cur = self.seats[y][x]
|
||||
if cur is not None:
|
||||
return cur
|
||||
y += dy
|
||||
x += dx
|
||||
return None
|
||||
|
||||
def get_occupied(self, y: int, x: int,) -> int:
|
||||
occupied = 0
|
||||
for dx, dy in product(self.p, self.p):
|
||||
if dx == 0 and dy == 0:
|
||||
continue
|
||||
if self.alt and self.find_next_in_direction(y, x, dy, dx) == True:
|
||||
occupied += 1
|
||||
else:
|
||||
dx += x
|
||||
dy += y
|
||||
if 0 <= dx < self.max_x and 0 <= dy < self.max_y and self.seats[dy][dx]:
|
||||
occupied += 1
|
||||
return occupied
|
||||
|
||||
def iteration(self) -> int:
|
||||
changed = 0
|
||||
future: TSeats = deepcopy(self.seats)
|
||||
required_to_leave = 4 if self.alt else 3
|
||||
for y, x in product(range(self.max_y), range(self.max_x)):
|
||||
current = self.seats[y][x]
|
||||
if current == None:
|
||||
continue
|
||||
occupied = self.get_occupied(y, x)
|
||||
if (current == True and occupied > required_to_leave) or (current == False and occupied == 0):
|
||||
future[y][x] = not current
|
||||
changed += 1
|
||||
self.seats = future
|
||||
return changed
|
||||
|
||||
def count_occupied(self) -> int:
|
||||
return sum([
|
||||
sum([
|
||||
1 if seat == True else 0
|
||||
for seat in row
|
||||
])
|
||||
for row in self.seats
|
||||
])
|
||||
|
||||
def find_equilibrium(self) -> int:
|
||||
while self.iteration() > 0:
|
||||
pass
|
||||
return self.count_occupied()
|
||||
|
||||
|
||||
data = join(dirname(__file__), '../data.txt')
|
||||
with open(data) as f:
|
||||
txt = f.read()
|
||||
seats = Seats(txt)
|
||||
print(seats.find_equilibrium())
|
||||
|
||||
seats = Seats(txt, True)
|
||||
print(seats.find_equilibrium())
|
Loading…
Reference in New Issue
Block a user