Skip to content

Commit f5a12a1

Browse files
Merge pull request #31 from marcelblijleven/solution-2021-day-16
Solution 2021 day 16
2 parents 206056f + 207ec6a commit f5a12a1

File tree

73 files changed

+872
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+872
-1
lines changed

.coveragerc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ exclude_lines =
1111
pragma: no cover
1212
raise NotImplementedError
1313
if __name__ == .__main__.:
14+
if not answer:
15+
if answer is None:
1416
ignore_errors = True
1517
omit =
1618
tests/*
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
9319927879926693924289292981328319987931316578169277696988783869228544279445229463567277999867998995
2+
6782137819885688871167116696955987679771519589461881979722694422956389229653389717969915178729293921
3+
4196967349617789911994968389594625922499998784199978769463894298119929998523419691416468995851998897
4+
9939549347377981757829782892395742812959699849785339689589677539252217513971891798498155499956285578
5+
8916384499968378766894352151499199372662869587792187795389453511569982396133971939872465668916878211
6+
7993189556577598975327195382852888888747792768463951799884962661649859719796639872196115821997898244
7+
9131929289774264856998314699854392321299669718664871399915973382646977184981914313583631322769869496
8+
1294639965894198182949974183682936196887518297837684919982691938595779447911996988397175118988698494
9+
4782786949417398178157656111741924726913693999847397789298648194156399186949891721929928386518973189
10+
3977739884126799578896222995845591999757881477816959899697596196263475499959768799776948991584478795
11+
8889637962317919682519681791117593699886146499419897361184928352899298889849151996897316148994198392
12+
5498578218111924989898699181879979946886186695782915336129858857719697498544698119449189891762579543
13+
9783338778987224568666117389627992429787741296997599911865194389848889958925553889979799897423777945
14+
6931291694638181873998892726219973827969749895586381652183578821916888499612146683158297997879317147
15+
8877777991334789218226394711996426411378849596468946891472988131199845489394842963873899198487952998
16+
3539459956998578833759978911968552861677548942139916198879278837961654399499565972991281941498188981
17+
2972974825176113221951922999797475194219955668779238484932662379576969959641999963536596939992938319
18+
8999189987189581934744189464966714191889822969397189484166461782992252158687829572854497939177954812
19+
9178313428786795664136631935649179965178693798648811682669769586398699789681919199495871399999741929
20+
5119378487588899959148634498888174447189235477691334622982392398958554285539978999892599293177578576
21+
9194483992663776979699993923694591699361753399149992817692189238678351118559919281227659784293411968
22+
8298491567898149947916937816986611967598198918469919859981942948999997292151359196586691966622364798
23+
8967617989988598499288583929989879191183693417868427758699995173816914799393159367299299491212938739
24+
9615576413392678732537787848969513319795339442847871984399994395831159168113997819525821779895951131
25+
9517289315991471929899873729491238115986618382898622168953411697612883479692345639948932996812479348
26+
8868645925877716499872291994429779247194997924964482919991898596573118991853614924288837913727386759
27+
9999987737841999942399299639889457399818186751988275896989726181786896522987749911978759955938769911
28+
9965171374918978159589929157213992892387677844962317641171898612329184591217617189742176575229297129
29+
9767929185659816969889468699589589797348131494599948496991519365572468799397762291871989292635299117
30+
8819848216367515398912936929983168368989131886688955177399395931776416252412983329172927847866995999
31+
6299771172636199774384692992389988965934984977999979941449596464194783797413497969982717932271631937
32+
9867919388999249988179181792282919692511593818939811199697519413819695481976294984943596869931783348
33+
5217498999894999148325963118872789879319591769287491854919259276994581865449967987987831114686948989
34+
1276711298478928267591998981197998766572918373116177929646918799773629369715999986696257274486917991
35+
9677549397288943147522629679772837189955155394128389753657889165799871691584372149499497899552724698
36+
3161879596475993681859998589986219969799998994825365956811818594879884919881929971976965899599474911
37+
5978899751278729229937326671598189282789189956298939976972992419825567591984699791288651863712449289
38+
5785843757274446168989662865888761284786699589863846917179969997389799678757213693881899399798283381
39+
9378752974919831848182681851896386931157578417822957982158836367995975749867969189559339898318939296
40+
4993955952819489991949423696319923289965838263329551295268729531941959698478122857749736791389739479
41+
9979913149995894544486789219787199998891969561998591837158798358549919571928399321959581987183951698
42+
4923374226279899729129788946919681194779851147917197889998718126991737982769352816642519928221816197
43+
9429415178891728919769972827548994887898916124219867258118175562995498488988811913466666225834984817
44+
1997187992489979189979738887118749979626651839497889793969749472548747897714399891669799699455896479
45+
9624951339616573939279944717971788599447979873899985998736591429797938969286363498288449419568929497
46+
4681938983828953998696612418773812199371222792989931316197447299912596989997939419196126265222491439
47+
8282969925999179875889569231987788869719997982677696288989132989789147471889661396777872998193215828
48+
9117176216511922775467499987675919339161918275351989597766786989398687478371889678848583957918391983
49+
4497298388369915739296852828574512774696251343567794471621183177947698845776887888485895669987332919
50+
8997686994952766178877812668977742157188969917219861817661572949919915899219234859989915189987975197
51+
4118913999874589615989952873718475897828658681851486595176248687417644198975924996249597864279743829
52+
4579679958921889385239821828857289993449937186914896984992996922484999289511952583999869183918452997
53+
8917999927997994429392299437994891687289495897798495953442112848382963474984728969983994991783149799
54+
3199648699943299557924998832866891178693798554719699899858296272745997987479892662757759122991519658
55+
3914491579265932577578942964548459979268999694999526126213913278751869812666985179899997189599921181
56+
1269972955191548488671189591192374899912929828132891677889925885888738571982935925999913169515229987
57+
8615958688829298177988481927419139187787699635996766899698917751758119585876873124761389897198819885
58+
2167497889941835338936978346275288693895992191919697774591999928333652585539982922569942243597599213
59+
9472668281589151358931112811958629285577878128176692715915826998919398155789165594481997993263959196
60+
9966289385979919968957998245754327958389629627493188196716997492179981999971934979959984817392438989
61+
9145599971993842923971121326227736817867637718119198819933963982629959218237898899655888386991289596
62+
7393759917659977589146245871559799585218399497997751917777999862217868959999822795991196969818211621
63+
9792927889945519672991946543936698168957938218225912882981935387993831231216179615298972181984319228
64+
7743761899817767783667672977139983269215199199699918314639989519981393115896593389898441874874699776
65+
1824497653995798679698799297229749897834797833294197979814281923987255598585839497197117839729571369
66+
8577958882861526317942215717331978988685919519168957591892925161883496938686898898453673315687998843
67+
4191972768117591321987488967786668869999853979339817579176251791521892919919468212444128984415671319
68+
5576891999599798816879657775669991198999224343989577163882862748989953362179892918179279281387216996
69+
9373769111497348825797289843198858611491499267469678187893869937361891692919973885768188384887596189
70+
9859171731132988682195848386695958714996489139645578586441948885317994929358881751899912625863299552
71+
4934928593958897783799983963793921184111597692919959479588985597988338527769967199293539699294774194
72+
1698538489641947137846923886699274821953365783198463959357989161489817229999617499141136156969131969
73+
3296989219983977948718421976373911944179536478972924859298568896972641886161529175995818483911543128
74+
6278913998199519318855192181581196429992429817619397917141979691623919571874589999254329218897887994
75+
9992985668416932999926168816176973997758599186957888288395128484987529129929975441231472862839421695
76+
1362464815499699192596287679432743239657996999693751969711918999687129296564511897258489745988288167
77+
5977189297674799199628985972999971494272992187915199889419992439287859927924778577194577929695457627
78+
3438223999111997512849575289859985859972752399978987619891559997998554511569914599149678154711126639
79+
2979126974919321983991789499388668896928879799646162171851776714127962589986998574331968997456544868
80+
6216795749356515966718898985918565959499628961815279546198979459849845989371831992292699311375776865
81+
8352715528197149369799519852288989699978992875598296779931298654369979999696915593247113843923599538
82+
8962455899599497871221926339396845158947259529895993695544959768976848859779899991114641786957296531
83+
2943869391171944962257474296498957919597467978896784699673793995229658928919598979738119899319383986
84+
9983898169912296799289397793294213546919953477555577429149749497766981349668499994878593194997879275
85+
8889882959291771612692377879435986414239649936776842748579798617821961983999949994989282378389947399
86+
3199997769523581787587969916892769968184616564892139471917169316971672979973375871988172842996584895
87+
8354689792844394798623128972146939743314292658383663832514698996697367378299886829789191826999773961
88+
9893836276828919186673649859239999393698982985775768195847989769239991637411793618869888191917472289
89+
5928583917498121999886377795189961317788981897688629942879519515624767918988389411193999247789868141
90+
1429679799293989912693479848974118958998299151271395998911989696518192397472871957999765285698267313
91+
9239695319699999988488829959759316161477147119979518383759198179368174993997996698566986314498599789
92+
2582659929929648199398128693359499693417769482859853897799284585655687921188318975834353991389972842
93+
8596473468199158355917977999874111821781368897658914981889824514189229862189929872193481817956976884
94+
9685977168754199641189321131863836338914891329759695897928358898995849678196968239981171745482329928
95+
9935621827798812799762166788756959219299892726731815999185647229991757173887841999993427325891658191
96+
1778263118969552899197794341699979459118691212755668996749377169926884394172497294118899699853739749
97+
2787591999446691168197517967271411843279629429417196194996811596363987299412785812633871145227949115
98+
6796987473692958899138914468653236383857234899879631271399676719319916464278159525996129786399815963
99+
5819878197925797859196414992974686679674969364619688199911487117949926999488799995986788649369962889
100+
1611181455799765871782419643336499989899999864957323699781212598968286442487972619699128531368991998
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
E20D72805F354AE298E2FCC5339218F90FE5F3A388BA60095005C3352CF7FBF27CD4B3DFEFC95354723006C401C8FD1A23280021D1763CC791006E25C198A6C01254BAECDED7A5A99CCD30C01499CFB948F857002BB9FCD68B3296AF23DD6BE4C600A4D3ED006AA200C4128E10FC0010C8A90462442A5006A7EB2429F8C502675D13700BE37CF623EB3449CAE732249279EFDED801E898A47BE8D23FBAC0805527F99849C57A5270C064C3ECF577F4940016A269007D3299D34E004DF298EC71ACE8DA7B77371003A76531F20020E5C4CC01192B3FE80293B7CD23ED55AA76F9A47DAAB6900503367D240522313ACB26B8801B64CDB1FB683A6E50E0049BE4F6588804459984E98F28D80253798DFDAF4FE712D679816401594EAA580232B19F20D92E7F3740D1003880C1B002DA1400B6028BD400F0023A9C00F50035C00C5002CC0096015B0C00B30025400D000C398025E2006BD800FC9197767C4026D78022000874298850C4401884F0E21EC9D256592007A2C013967C967B8C32BCBD558C013E005F27F53EB1CE25447700967EBB2D95BFAE8135A229AE4FFBB7F6BC6009D006A2200FC3387D128001088E91121F4DED58C025952E92549C3792730013ACC0198D709E349002171060DC613006E14C7789E4006C4139B7194609DE63FEEB78004DF299AD086777ECF2F311200FB7802919FACB38BAFCFD659C5D6E5766C40244E8024200EC618E11780010B83B09E1BCFC488C017E0036A184D0A4BB5CDD0127351F56F12530046C01784B3FF9C6DFB964EE793F5A703360055A4F71F12C70000EC67E74ED65DE44AA7338FC275649D7D40041E4DDA794C80265D00525D2E5D3E6F3F26300426B89D40094CCB448C8F0C017C00CC0401E82D1023E0803719E2342D9FB4E5A01300665C6A5502457C8037A93C63F6B4C8B40129DF7AC353EF2401CC6003932919B1CEE3F1089AB763D4B986E1008A7354936413916B9B080

src/adventofcode/scripts/add_day.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def add_day():
2222
write_solution_template(solution_file, year, day)
2323

2424
# Test file
25-
test_module_path = os.path.abspath(os.path.join(ROOT_DIR, '../../tests', f'year_{year}'))
25+
test_module_path = os.path.abspath(os.path.join(ROOT_DIR, '../../tests/adventofcode', f'year_{year}'))
2626
test_file = os.path.join(test_module_path, f'test_day_{day:02}_{year}.py')
2727
create_module_dir(test_module_path)
2828
write_test_template(test_file, year, day)

src/adventofcode/util/helpers.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,23 @@ def memoized_func(*args):
113113
return result
114114

115115
return memoized_func
116+
117+
118+
def manhattan_distance(start: tuple[int, int], end: tuple[int, int]):
119+
x1, y1 = start
120+
x2, y2 = end
121+
return abs(x1 - x2) + abs(y1 - y2)
122+
123+
124+
def grid_to_string(grid: dict[tuple[int, int], Any]) -> str:
125+
lines: list[str] = []
126+
max_x, max_y = max(grid.keys())
127+
128+
for y in range(max_y + 1):
129+
line = ''
130+
for x in range(max_x + 1):
131+
line += str(grid[(x, y)])
132+
133+
lines.append(line)
134+
135+
return '\n'.join(lines)
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import heapq
2+
from typing import List
3+
4+
from adventofcode.util.exceptions import SolutionNotFoundException
5+
from adventofcode.util.helpers import solution_timer, manhattan_distance
6+
from adventofcode.util.input_helpers import get_input_for_day
7+
8+
Position = tuple[int, int]
9+
Grid = dict[Position, int]
10+
11+
12+
def parse_input(input_list: list[str]) -> Grid:
13+
grid: Grid = {}
14+
15+
for y, line in enumerate(input_list):
16+
for x, value in enumerate(line):
17+
grid[(x, y)] = int(value)
18+
19+
return grid
20+
21+
22+
def get_possible_routes_for_position(position: Position, grid: Grid) -> list[Position]:
23+
x, y = position
24+
possible_routes: list[Position] = []
25+
routes = [(1, 0), (-1, 0), (0, 1), (0, -1)]
26+
27+
for route in routes:
28+
possible_route = x + route[0], y + route[1]
29+
30+
if possible_route in grid:
31+
possible_routes.append(possible_route)
32+
33+
return possible_routes
34+
35+
36+
def find_route(grid: Grid):
37+
start = (0, 0)
38+
end = max(grid.keys())
39+
heap: list[tuple[int, Position]] = []
40+
heapq.heappush(heap, (0, start))
41+
visited: dict[Position, int] = {start: 0}
42+
43+
while len(heap) > 0:
44+
# https://docs.python.org/3/library/heapq.html#module-heapq
45+
# retrieve the smallest item from the heap
46+
# use [0] to retrieve it without popping
47+
#
48+
# Could also use PriorityQueue, which is thread safe and heapq is not,
49+
# but for this solution it doesn't matter
50+
position = heapq.heappop(heap)[1]
51+
52+
if position == end:
53+
break
54+
55+
for route in get_possible_routes_for_position(position, grid):
56+
risk = visited[position] + grid[route]
57+
58+
if route not in visited or risk < visited[route]:
59+
visited[route] = risk
60+
cost = manhattan_distance(route, end) + risk
61+
heapq.heappush(heap, (cost, route))
62+
print(heap)
63+
return visited[end]
64+
65+
66+
def increment_value(value: int) -> int:
67+
new_value = value + 1
68+
69+
if new_value > 9:
70+
new_value = new_value % 9
71+
72+
return new_value
73+
74+
75+
def enlarge_grid(grid: Grid, factor: int = 5) -> Grid:
76+
max_x, max_y = max(grid.keys())
77+
new_grid: Grid = {}
78+
79+
# Horizontal first
80+
for y in range(max_y + 1):
81+
for x in range((max_x + 1) * factor):
82+
position = x, y
83+
if position in grid:
84+
new_grid[position] = grid[position]
85+
else:
86+
target_x = x - (max_x + 1)
87+
new_grid[position] = increment_value(new_grid[(target_x, y)])
88+
89+
# Calculate vertical last
90+
for y in range(max_y + 1, (max_y + 1) * factor):
91+
for x in range((max_x + 1) * factor):
92+
position = x, y
93+
target_y = y - (max_y + 1)
94+
new_grid[position] = increment_value(new_grid[(x, target_y)])
95+
96+
return new_grid
97+
98+
99+
@solution_timer(2021, 15, 1)
100+
def part_one(input_data: List[str]):
101+
answer = find_route(parse_input(input_data))
102+
103+
if not answer:
104+
raise SolutionNotFoundException(2021, 15, 1)
105+
106+
return answer
107+
108+
109+
@solution_timer(2021, 15, 2)
110+
def part_two(input_data: List[str]):
111+
grid = parse_input(input_data)
112+
answer = find_route(enlarge_grid(grid))
113+
114+
if not answer:
115+
raise SolutionNotFoundException(2021, 15, 2)
116+
117+
return answer
118+
119+
120+
if __name__ == '__main__':
121+
data = get_input_for_day(2021, 15)
122+
part_one(data)
123+
part_two(data)

0 commit comments

Comments
 (0)