88from aoc import my_aocd
99from aoc .common import InputData
1010from aoc .common import SolutionBase
11- from aoc .common import aoc_samples , log
11+ from aoc .common import aoc_samples
1212from aoc .geometry import Direction
13- from aoc .grid import CharGrid
1413from aoc .grid import Cell
14+ from aoc .grid import CharGrid
1515
1616Input = tuple [CharGrid , list [Direction ]]
1717Output1 = int
5656
5757
5858class Solution (SolutionBase [Input , Output1 , Output2 ]):
59- def print_grid (self , grid : CharGrid ) -> None :
60- for line in grid .get_rows_as_strings ():
61- log (line )
62-
6359 def parse_input (self , input_data : InputData ) -> Input :
6460 blocks = my_aocd .to_blocks (input_data )
6561 grid = CharGrid .from_strings (blocks [0 ])
@@ -68,6 +64,13 @@ def parse_input(self, input_data: InputData) -> Input:
6864 dirs .extend ([Direction .from_str (ch ) for ch in line ])
6965 return grid , dirs
7066
67+ def get_gps (self , grid : CharGrid ) -> int :
68+ return sum (
69+ cell .row * 100 + cell .col
70+ for cell in grid .get_cells ()
71+ if grid .get_value (cell ) in {"O" , "[" }
72+ )
73+
7174 def part_1 (self , input : Input ) -> Output1 :
7275 def move (line : list [str ], r : int ) -> list [str ]:
7376 def swap (line : list [str ], idx1 : int , idx2 : int ) -> list [str ]:
@@ -101,15 +104,18 @@ def to_str(a: list[str]) -> str:
101104 return "" .join (a )
102105
103106 assert to_str (move (to_array ("#..@#" ), 3 )) == "#..@#"
104- assert to_str (
move (
to_array (
"#[email protected] ....#" ),
5 ))
== "#.....@O....#" # noqa E501 105- assert to_str (move (to_array ("#.....@O....#" ), 6 )) == "#......@O...#" # noqa E501
107+ assert (
108+ to_str (
move (
to_array (
"#[email protected] ....#" ),
5 ))
== "#.....@O....#" 109+ ) # noqa E501
110+ assert (
111+ to_str (move (to_array ("#.....@O....#" ), 6 )) == "#......@O...#"
112+ ) # noqa E501
106113 assert to_str (move (to_array ("#..@O#" ), 3 )) == "#..@O#" # noqa E501
107114 assert to_str (
move (
to_array (
"#[email protected] .#" ),
2 ))
== "#..@OO.#" # noqa E501 108115 assert to_str (move (to_array ("#.#@O..#" ), 3 )) == "#.#.@O.#" # noqa E501
109116 assert to_str (move (to_array ("#.@O#..#" ), 2 )) == "#.@O#..#" # noqa E501
110117 grid , dirs = input
111- # self.print_grid(grid)
112- # log(dirs)
118+ grid = CharGrid .from_strings (["" .join (row ) for row in grid .values ])
113119 robot = next (grid .get_all_equal_to ("@" ))
114120 for dir in dirs :
115121 match dir :
@@ -137,20 +143,69 @@ def to_str(a: list[str]) -> str:
137143 tmp .reverse ()
138144 grid .replace_col (robot .col , tmp )
139145 robot = Cell (tmp .index ("@" ), robot .col )
140- # self.print_grid(grid)
141- ans = 0
142- for cell in grid .get_all_equal_to ("O" ):
143- ans += cell .row * 100 + cell .col
144- return ans
146+ return self .get_gps (grid )
145147
146148 def part_2 (self , input : Input ) -> Output2 :
147- return 0
149+ grid_in , dirs = input
150+ grid = []
151+ for row in grid_in .get_rows_as_strings ():
152+ line = list [str ]()
153+ for ch in row :
154+ match ch :
155+ case "#" :
156+ line .extend (["#" , "#" ])
157+ case "O" :
158+ line .extend (["[" , "]" ])
159+ case "." :
160+ line .extend (["." , "." ])
161+ case "@" :
162+ line .extend (["@" , "." ])
163+ grid .append (line )
164+ for r in range (len (grid )):
165+ for c in range (len (grid [r ])):
166+ if grid [r ][c ] == "@" :
167+ robot = Cell (r , c )
168+ break
169+ else :
170+ continue
171+ break
172+ for dir in dirs :
173+ to_move = [robot ]
174+ for cell in to_move :
175+ nxt = cell .at (dir )
176+ if nxt in to_move :
177+ continue
178+ match grid [nxt .row ][nxt .col ]:
179+ case "#" :
180+ to_move = []
181+ break
182+ case "[" :
183+ to_move .append (nxt )
184+ to_move .append (nxt .at (Direction .RIGHT ))
185+ case "]" :
186+ to_move .append (nxt )
187+ to_move .append (nxt .at (Direction .LEFT ))
188+ if len (to_move ) == 0 :
189+ continue
190+ to_move .pop (0 )
191+ vals = [list (row ) for row in grid ]
192+ grid [robot .row ][robot .col ] = "."
193+ nxt_robot = robot .at (dir )
194+ grid [nxt_robot .row ][nxt_robot .col ] = "@"
195+ robot = nxt_robot
196+ for cell in to_move :
197+ grid [cell .row ][cell .col ] = "."
198+ for cell in to_move :
199+ nxt = cell .at (dir )
200+ grid [nxt .row ][nxt .col ] = vals [cell .row ][cell .col ]
201+ tmp = CharGrid .from_strings (["" .join (row ) for row in grid ])
202+ return self .get_gps (tmp )
148203
149204 @aoc_samples (
150205 (
151206 ("part_1" , TEST1 , 2028 ),
152207 ("part_1" , TEST2 , 10092 ),
153- # ("part_2", TEST1, "TODO" ),
208+ ("part_2" , TEST2 , 9021 ),
154209 )
155210 )
156211 def samples (self ) -> None :
0 commit comments