# Advent of Code 2020 - Day 11: Seating System

Dec 12th, 2020
710
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. #!/usr/bin/env python3
2. # -*- coding: utf-8 -*-
3.
4. """
5. Advent of Code 2020 - Day 11: Seating System
7.
9. :author: Olivier Pirson --- http://www.opimedia.be/
10. :version: December 11, 2020
11. """
12.
13. import sys
14.
15. from typing import List, Tuple
16.
17.
18. def nb_place(grid: List[str], x: int, y: int, place: str) -> int:
19.     height = len(grid)
20.     width = len(grid[0])
21.
22.     assert 0 <= x < width
23.     assert 0 <= y < height
24.     assert place in '.#L'
25.
26.     nb = 0
27.
28.     for y_offset in (-1, 0, 1):
29.         y_new = y + y_offset
30.         if 0 <= y_new < height:
31.             row = grid[y_new]
32.             for x_offset in (-1, 0, 1):
33.                 if (x_offset != 0) or (y_offset != 0):
34.                     x_new = x + x_offset
35.                     if (0 <= x_new < width) and (row[x_new] == place):
36.                         nb += 1
37.
38.     return nb
39.
40.
41. def nb_visible(grid: List[str], x: int, y: int, place: str) -> int:
42.     height = len(grid)
43.     width = len(grid[0])
44.
45.     assert 0 <= x < width
46.     assert 0 <= y < height
47.     assert place in '.#L'
48.
49.     nb = 0
50.
51.     for y_offset in (-1, 0, 1):
52.         for x_offset in (-1, 0, 1):
53.             if (x_offset != 0) or (y_offset != 0):
54.                 x_new = x + x_offset
55.                 y_new = y + y_offset
56.                 while ((0 <= x_new < width) and (0 <= y_new < height)
57.                        and (grid[y_new][x_new] == '.')):
58.                     x_new += x_offset
59.                     y_new += y_offset
60.                 if ((0 <= x_new < width) and (0 <= y_new < height)
61.                         and (grid[y_new][x_new] == place)):
62.                     nb += 1
63.
64.     return nb
65.
66.
67. def update1(grid: List[str]) -> Tuple[List[str], bool]:
68.     new_grid = []
69.     is_modified = False
70.
71.     for y, row in enumerate(grid):
72.         new_row = []
73.         for x, place in enumerate(row):
74.             if place == 'L':
75.                 nb = nb_place(grid, x, y, '#')
76.                 if nb == 0:
77.                     is_modified = True
78.                     place = '#'
79.             elif place == '#':
80.                 nb = nb_place(grid, x, y, '#')
81.                 if nb >= 4:
82.                     is_modified = True
83.                     place = 'L'
84.             new_row.append(place)
85.
86.         new_grid.append(''.join(new_row))
87.
88.     return new_grid, is_modified
89.
90.
91. def update2(grid: List[str]) -> Tuple[List[str], bool]:
92.     new_grid = []
93.     is_modified = False
94.
95.     for y, row in enumerate(grid):
96.         new_row = []
97.         for x, place in enumerate(row):
98.             if place == 'L':
99.                 nb = nb_visible(grid, x, y, '#')
100.                 if nb == 0:
101.                     is_modified = True
102.                     place = '#'
103.             elif place == '#':
104.                 nb = nb_visible(grid, x, y, '#')
105.                 if nb >= 5:
106.                     is_modified = True
107.                     place = 'L'
108.             else:
109.                 nb = 0
110.             new_row.append(place)
111.
112.         new_grid.append(''.join(new_row))
113.
114.     return new_grid, is_modified
115.
116.
117. def main() -> None:
118.     grid = []
119.     for line in sys.stdin:
120.         grid.append(line.rstrip())
121.
122.     # Part 1
123.     new_grid = grid
124.
125.     is_modified = True
126.     while is_modified:
127.         is_modified = False
128.         new_grid, is_modified = update1(new_grid)
129.
130.     nb = sum(row.count('#') for row in new_grid)
131.     print(nb)
132.
133.     # Part 2
134.     new_grid = grid
135.
136.     is_modified = True
137.     while is_modified:
138.         is_modified = False
139.         new_grid, is_modified = update2(new_grid)
140.         nb = sum(row.count('#') for row in new_grid)
141.
142.     nb = sum(row.count('#') for row in new_grid)
143.     print(nb)
144.
145.
146. if __name__ == '__main__':
147.     main()
148.
RAW Paste Data