Compare commits

..

3 commits

Author SHA1 Message Date
935a7679ee Oh well 2025-12-10 18:18:52 -08:00
0991eeea53 Fuck. 2025-12-09 21:48:19 -08:00
7410fe2a66 Working on day 09. 2025-12-09 00:57:57 -06:00
5 changed files with 832 additions and 1 deletions

3
.gitignore vendored
View file

@ -4,4 +4,5 @@
*/main */main
**/*.o **/*.o
.vscode .vscode
.mypy_cache .mypy_cache
**/.venv/**

174
09/README.md Normal file
View file

@ -0,0 +1,174 @@
# --- Day 9: Movie Theater ---
You slide down the firepole in the corner of the playground and land in the North Pole base movie theater!
The movie theater has a big tile floor with an interesting pattern. Elves here are redecorating the theater by switching out some of the square tiles in the big grid they form. Some of the tiles are red; the Elves would like to find the largest rectangle that uses red tiles for two of its opposite corners. They even have a list of where the red tiles are located in the grid (your puzzle input).
For example:
```txt
7,1
11,1
11,7
9,7
9,5
2,5
2,3
7,3
```
Showing red tiles as # and other tiles as ., the above arrangement of red tiles would look like this:
```txt
..............
.......#...#..
..............
..#....#......
..............
..#......#....
..............
.........#.#..
..............
```
You can choose any two red tiles as the opposite corners of your rectangle; your goal is to find the largest rectangle possible.
For example, you could make a rectangle (shown as O) with an area of 24 between 2,5 and 9,7:
```txt
..............
.......#...#..
..............
..#....#......
..............
..OOOOOOOO....
..OOOOOOOO....
..OOOOOOOO.#..
..............
```
Or, you could make a rectangle with area 35 between 7,1 and 11,7:
```txt
..............
.......OOOOO..
.......OOOOO..
..#....OOOOO..
.......OOOOO..
..#....OOOOO..
.......OOOOO..
.......OOOOO..
..............
```
You could even make a thin rectangle with an area of only 6 between 7,3 and 2,3:
```txt
..............
.......#...#..
..............
..OOOOOO......
..............
..#......#....
..............
.........#.#..
..............
```
Ultimately, the largest rectangle you can make in this example has area 50. One way to do this is between 2,5 and 11,1:
```txt
..............
..OOOOOOOOOO..
..OOOOOOOOOO..
..OOOOOOOOOO..
..OOOOOOOOOO..
..OOOOOOOOOO..
..............
.........#.#..
..............
```
Using two red tiles as opposite corners, what is the largest area of any rectangle you can make?
## --- Part Two ---
The Elves just remembered: they can only switch out tiles that are red or green. So, your rectangle can only include red or green tiles.
In your list, every red tile is connected to the red tile before and after it by a straight line of green tiles. The list wraps, so the first red tile is also connected to the last red tile. Tiles that are adjacent in your list will always be on either the same row or the same column.
Using the same example as before, the tiles marked X would be green:
```txt
..............
.......#XXX#..
.......X...X..
..#XXXX#...X..
..X........X..
..#XXXXXX#.X..
.........X.X..
.........#X#..
..............
```
In addition, all of the tiles inside this loop of red and green tiles are also green. So, in this example, these are the green tiles:
```txt
..............
.......#XXX#..
.......XXXXX..
..#XXXX#XXXX..
..XXXXXXXXXX..
..#XXXXXX#XX..
.........XXX..
.........#X#..
..............
```
The remaining tiles are never red nor green.
The rectangle you choose still must have red tiles in opposite corners, but any other tiles it includes must now be red or green. This significantly limits your options.
For example, you could make a rectangle out of red and green tiles with an area of 15 between 7,3 and 11,1:
```txt
..............
.......OOOOO..
.......OOOOO..
..#XXXXOOOOO..
..XXXXXXXXXX..
..#XXXXXX#XX..
.........XXX..
.........#X#..
..............
```
Or, you could make a thin rectangle with an area of 3 between 9,7 and 9,5:
```txt
..............
.......#XXX#..
.......XXXXX..
..#XXXX#XXXX..
..XXXXXXXXXX..
..#XXXXXXOXX..
.........OXX..
.........OX#..
..............
```
The largest rectangle you can make in this example using only red and green tiles has area 24. One way to do this is between 9,5 and 2,3:
```txt
..............
.......#XXX#..
.......XXXXX..
..OOOOOOOOXX..
..OOOOOOOOXX..
..OOOOOOOOXX..
.........XXX..
.........#X#..
..............
```
Using two red tiles as opposite corners, what is the largest area of any rectangle you can make using only red and green tiles?

497
09/input/tiles.txt Normal file
View file

@ -0,0 +1,497 @@
98104,50456
98104,51682
98312,51682
98312,52884
97889,52884
97889,54111
97979,54111
97979,55268
97347,55268
97347,56539
97728,56539
97728,57760
97634,57760
97634,58855
96847,58855
96847,60054
96679,60054
96679,61317
96751,61317
96751,62586
96779,62586
96779,63752
96395,63752
96395,64679
95280,64679
95280,65794
94816,65794
94816,66941
94445,66941
94445,68200
94338,68200
94338,69277
93771,69277
93771,70433
93383,70433
93383,71649
93097,71649
93097,72514
92124,72514
92124,73908
92128,73908
92128,74881
91366,74881
91366,75816
90556,75816
90556,77045
90201,77045
90201,78002
89430,78002
89430,78599
88182,78599
88182,79520
87399,79520
87399,80559
86761,80559
86761,81707
86234,81707
86234,82852
85677,82852
85677,83216
84286,83216
84286,84523
83875,84523
83875,85175
82807,85175
82807,86225
82109,86225
82109,86455
80700,86455
80700,87396
79907,87396
79907,88523
79239,88523
79239,88608
77791,88608
77791,90057
77320,90057
77320,90614
76218,90614
76218,90938
74981,90938
74981,91390
73839,91390
73839,92492
73061,92492
73061,92728
71806,92728
71806,93192
70681,93192
70681,93612
69540,93612
69540,93869
68335,93869
68335,94860
67428,94860
67428,95450
66344,95450
66344,95561
65092,95561
65092,96190
64012,96190
64012,96557
62845,96557
62845,96354
61534,96354
61534,96724
60376,96724
60376,97292
59252,97292
59252,97350
58024,97350
58024,97559
56825,97559
56825,97603
55604,97603
55604,97509
54376,97509
54376,98061
53202,98061
53202,97581
51961,97581
51961,97707
50756,97707
50756,98026
49544,98026
49544,98380
48314,98380
48314,98227
47095,98227
47095,97618
45919,97618
45919,98128
44644,98128
44644,97803
43450,97803
43450,97621
42241,97621
42241,97087
41098,97087
41098,96683
39944,96683
39944,96469
38751,96469
38751,96632
37453,96632
37453,96378
36252,96378
36252,95483
35254,95483
35254,94954
34156,94954
34156,94404
33073,94404
33073,94546
31714,94546
31714,93978
30631,93978
30631,93390
29563,93390
29563,93229
28284,93229
28284,92645
27206,92645
27206,91900
26221,91900
26221,91253
25185,91253
25185,90811
24021,90811
24021,89872
23176,89872
23176,89512
21938,89512
21938,88719
20998,88719
20998,87815
20150,87815
20150,86963
19272,86963
19272,86165
18352,86165
18352,85528
17284,85528
17284,84748
16335,84748
16335,83931
15419,83931
15419,82569
15079,82569
15079,81665
14276,81665
14276,80794
13433,80794
13433,80179
12263,80179
12263,79292
11406,79292
11406,77937
11188,77937
11188,76824
10670,76824
10670,76099
9568,76099
9568,75261
8602,75261
8602,74150
8069,74150
8069,72946
7719,72946
7719,71739
7402,71739
7402,70773
6615,70773
6615,69626
6195,69626
6195,68452
5849,68452
5849,67455
5069,67455
5069,66396
4405,66396
4405,64993
4738,64993
4738,63872
4270,63872
4270,62863
3376,62863
3376,61577
3472,61577
3472,60301
3613,60301
3613,59225
2845,59225
2845,57979
2910,57979
2910,56874
2093,56874
2093,55591
2510,55591
2510,54423
1976,54423
1976,53197
2014,53197
2014,51986
1803,51986
1803,50759
2071,50759
2071,50422
94525,50422
94525,48322
1837,48322
1837,47110
2012,47110
2012,45933
2546,45933
2546,44668
2091,44668
2091,43511
2641,43511
2641,42343
3004,42343
3004,41061
2713,41061
2713,39923
3219,39923
3219,38729
3438,38729
3438,37533
3664,37533
3664,36495
4439,36495
4439,35067
3938,35067
3938,34028
4682,34028
4682,32944
5256,32944
5256,31872
5839,31872
5839,30662
6090,30662
6090,29497
6471,29497
6471,28397
6996,28397
6996,27560
8016,27560
8016,26143
7963,26143
7963,25366
9046,25366
9046,24081
9282,24081
9282,23477
10574,23477
10574,22460
11221,22460
11221,21442
11872,21442
11872,20301
12374,20301
12374,19002
12711,19002
12711,18141
13593,18141
13593,17349
14542,17349
14542,16798
15728,16798
15728,15635
16281,15635
16281,14616
16998,14616
16998,14349
18399,14349
18399,13304
19097,13304
19097,12802
20251,12802
20251,11411
20711,11411
20711,10870
21833,10870
21833,10180
22841,10180
22841,9583
23909,9583
23909,9278
25150,9278
25150,8724
26226,8724
26226,8160
27293,8160
27293,7653
28388,7653
28388,6269
29061,6269
29061,6011
30291,6011
30291,5560
31426,5560
31426,5042
32534,5042
32534,4669
33698,4669
33698,4250
34845,4250
34845,3710
35957,3710
35957,4163
37353,4163
37353,2968
38297,2968
38297,3311
39631,3311
39631,2440
40695,2440
40695,2649
41975,2649
41975,2752
43219,2752
43219,2334
44388,2334
44388,1770
45557,1770
45557,2156
46812,2156
46812,1665
48007,1665
48007,1609
49232,1609
49232,2322
50451,2322
50451,1588
51686,1588
51686,2110
52884,2110
52884,2326
54085,2326
54085,2081
55332,2081
55332,2310
56533,2310
56533,3058
57647,3058
57647,2889
58905,2889
58905,2878
60150,2878
60150,3003
61376,3003
61376,3870
62411,3870
62411,3587
63757,3587
63757,4734
64674,4734
64674,5098
65824,5098
65824,4729
67256,4729
67256,5928
68090,5928
68090,6312
69240,6312
69240,6998
70253,6998
70253,6842
71679,6842
71679,7263
72841,7263
72841,8635
73474,8635
73474,8610
74895,8610
74895,9542
75753,9542
75753,10470
76592,10470
76592,10518
78039,10518
78039,11937
78509,11937
78509,12228
79814,12228
79814,12727
80984,12727
80984,14142
81377,14142
81377,14893
82327,14893
82327,15718
83211,15718
83211,16536
84104,16536
84104,17442
84907,17442
84907,18193
85883,18193
85883,18883
86949,18883
86949,19848
87702,19848
87702,20806
88463,20806
88463,21791
89188,21791
89188,23169
89338,23169
89338,24145
90050,24145
90050,24900
91131,24900
91131,26138
91428,26138
91428,27054
92280,27054
92280,28082
92946,28082
92946,29467
92882,29467
92882,30176
94244,30176
94244,31575
94082,31575
94082,32608
94765,32608
94765,33872
94845,33872
94845,34814
95843,34814
95843,36002
96141,36002
96141,37205
96373,37205
96373,38398
96625,38398
96625,39626
96707,39626
96707,40765
97200,40765
97200,41993
97248,41993
97248,43119
97943,43119
97943,44422
97371,44422
97371,45577
98010,45577
98010,46825
97641,46825
97641,48005
98387,48005
98387,49236
98179,49236
98179,50456

157
09/main.py Executable file
View file

@ -0,0 +1,157 @@
#!/usr/bin/env python3
from logging import debug, DEBUG, basicConfig
from sys import argv
from shapely.geometry.polygon import Polygon
def parse_input(input_filepath: str) -> list[tuple[int, int]]:
with open(file=input_filepath, mode="r") as input_file:
input_data: list[str] = input_file.readlines()
debug(f"\n\nRAW INPUT: {input_data}\n\n")
return [
(int(line.strip().split(",")[0]), int(line.strip().split(",")[1]))
for line in input_data
if line.strip()
]
def find_areas(
coordinate_pairs: list[tuple[int, int]],
) -> list[tuple[int, int, int]]:
areas: list[tuple[int, int, int]] = []
for c in range(len(coordinate_pairs)):
for d in range(c + 1, len(coordinate_pairs)):
areas.append(
(
(abs((coordinate_pairs[c][0] - coordinate_pairs[d][0])) + 1)
* (abs(coordinate_pairs[c][1] - coordinate_pairs[d][1]) + 1),
c,
d,
)
)
return areas
# def find_within_bounds(
# rectangles: list[tuple[int, int, int]], vertices: list[tuple[int, int]]
# ) -> tuple[int, int, int]:
# for r in rectangles:
# outside_bounds = False
# min_x = min(vertices[r[1]][0], vertices[r[2]][0])
# max_x = max(vertices[r[1]][0], vertices[r[2]][0])
# min_y = min(vertices[r[1]][1], vertices[r[2]][1])
# max_y = max(vertices[r[1]][1], vertices[r[2]][1])
# debug(f"{r[0]}, {vertices[r[1]]}, {vertices[r[2]]}")
# left_intersects = -1
# right_intersects = -1
# down_intersects = -1
# up_intersects = -1
# for v in range(len(vertices[1:])):
# is_horizontal_line = vertices[v - 1][1] == vertices[v][1]
# is_vertical_line = vertices[v - 1][0] == vertices[v][0]
# is_in_y_bounds = vertices[v][1] > min_y and vertices[v][1] < max_y
# is_in_x_bounds = vertices[v][0] > min_x and vertices[v][0] < max_x
# line_intersects_left = (
# min(vertices[v - 1][0], vertices[v][0]) < min_x
# and max(vertices[v - 1][0], vertices[v][0]) > min_x
# )
# line_intersects_right = (
# min(vertices[v - 1][0], vertices[v][0]) < max_x
# and max(vertices[v - 1][0], vertices[v][0]) > max_x
# )
# line_intersects_down = (
# min(vertices[v - 1][1], vertices[v][1]) < min_y
# and max(vertices[v - 1][1], vertices[v][1]) > min_y
# )
# line_intersects_up = (
# min(vertices[v - 1][1], vertices[v][1]) < max_y
# and max(vertices[v - 1][1], vertices[v][1]) > max_y
# )
# if is_horizontal_line:
# if line_intersects_left or line_intersects_right:
# if is_in_y_bounds:
# debug(f"{vertices[v-1]}, {vertices[v]}")
# outside_bounds = True
# break
# if line_intersects_left:
# left_intersects += 1
# if line_intersects_right:
# right_intersects += 1
# if is_vertical_line:
# if line_intersects_down or line_intersects_up:
# if is_in_x_bounds:
# debug(f"{vertices[v-1]}, {vertices[v]}")
# outside_bounds = True
# break
# if line_intersects_down:
# down_intersects += 1
# if line_intersects_up:
# up_intersects += 1
# if (
# outside_bounds
# or (
# left_intersects < 0
# or right_intersects < 0
# or down_intersects < 0
# or up_intersects < 0
# )
# or (
# left_intersects % 2 == 1
# or right_intersects % 2 == 1
# or down_intersects % 2 == 1
# or up_intersects % 2 == 1
# )
# ):
# continue
# return r
# return (0, 0, 0)
def find_within_bounds(
rectangles: list[tuple[int, int, int]], vertices: list[tuple[int, int]]
) -> tuple[int, int, int]:
tile_shape = Polygon(vertices)
for r in rectangles:
area = Polygon(
[
vertices[r[1]],
(vertices[r[1]][0], vertices[r[2]][1]),
vertices[r[2]],
(vertices[r[2]][0], vertices[r[1]][1]),
]
)
if tile_shape.contains(area):
return r
return (0, 0, 0)
def main() -> None:
input_filepath = "input/tiles.txt"
input_tiles = parse_input(input_filepath)
areas = find_areas(input_tiles)
debug(areas)
areas.sort(key=lambda x: x[0], reverse=True)
debug(areas)
print(f"The largest area you can make is: {areas[0][0]}")
print(
f"The largest area you can make within bounds: {find_within_bounds(areas, input_tiles)[0]}"
)
return
if __name__ == "__main__":
if "-d" in argv or "--debug" in argv:
basicConfig(filename="debug.log", level=DEBUG)
main()
exit(0)

2
09/requirements.txt Normal file
View file

@ -0,0 +1,2 @@
numpy==2.3.5
shapely==2.1.2