33# Advent of Code 2024 Day 20
44#
55
6+ import multiprocessing
7+ import os
68import sys
79
810from aoc .common import InputData
@@ -39,6 +41,30 @@ def parse_input(self, input_data: InputData) -> Input:
3941 return CharGrid .from_strings (list (input_data ))
4042
4143 def solve (self , grid : CharGrid , cheat_len : int , target : int ) -> int :
44+ ans = multiprocessing .Manager ().dict ()
45+
46+ def count_shortcuts (
47+ id : str ,
48+ cells : list [tuple [int , int ]],
49+ dist : dict [tuple [int , int ], int ],
50+ ) -> None :
51+ count = 0
52+ for r , c in cells :
53+ for md in range (2 , cheat_len + 1 ):
54+ for dr in range (md + 1 ):
55+ dc = md - dr
56+ for rr , cc in {
57+ (r + dr , c + dc ),
58+ (r + dr , c - dc ),
59+ (r - dr , c + dc ),
60+ (r - dr , c - dc ),
61+ }:
62+ if (rr , cc ) not in dist :
63+ continue
64+ if dist [(rr , cc )] - dist [(r , c )] >= target + md :
65+ count += 1
66+ ans [id ] = count
67+
4268 start = next (
4369 cell for cell in grid .get_cells () if grid .get_value (cell ) == "S"
4470 )
@@ -52,22 +78,25 @@ def solve(self, grid: CharGrid, cheat_len: int, target: int) -> int:
5278 ),
5379 )
5480 dist = {(k .row , k .col ): v for k , v in distances .items ()}
55- ans = 0
56- for r , c in dist .keys ():
57- for md in range (2 , cheat_len + 1 ):
58- for dr in range (md + 1 ):
59- dc = md - dr
60- for rr , cc in {
61- (r + dr , c + dc ),
62- (r + dr , c - dc ),
63- (r - dr , c + dc ),
64- (r - dr , c - dc ),
65- }:
66- if (rr , cc ) not in dist :
67- continue
68- if dist [(rr , cc )] - dist [(r , c )] >= target + md :
69- ans += 1
70- return ans
81+ if sys .platform .startswith ("win" ):
82+ count_shortcuts ("main" , [(r , c ) for r , c in dist .keys ()], dist )
83+ else :
84+ n = os .process_cpu_count ()
85+ cells : list [list [tuple [int , int ]]] = [[] for _ in range (n )]
86+ cnt = 0
87+ for r , c in dist .keys ():
88+ cells [cnt % n ].append ((r , c ))
89+ cnt += 1
90+ jobs = []
91+ for i in range (n ):
92+ p = multiprocessing .Process (
93+ target = count_shortcuts , args = (str (i ), cells [i ], dist )
94+ )
95+ jobs .append (p )
96+ p .start ()
97+ for p in jobs :
98+ p .join ()
99+ return sum (ans .values ())
71100
72101 def part_1 (self , grid : Input ) -> Output1 :
73102 return self .solve (grid , 2 , 100 )
0 commit comments