2023 - Day 24

This commit is contained in:
Dreaded_X 2023-12-24 23:50:48 +01:00
parent 72e4c18b31
commit fbd9e84f5f
Signed by: Dreaded_X
GPG Key ID: 5A0CBFE3C3377FAA
4 changed files with 527 additions and 0 deletions

View File

@ -8,6 +8,7 @@ edition = "2021"
[dependencies]
anyhow = "1.0.75"
lazy_static = "1.4.0"
nalgebra = "0.32.3"
regex = "1.10.2"
[features]

300
2023/input/24/input Normal file
View File

@ -0,0 +1,300 @@
225004689740965, 150875733412640, 116049940893518 @ 275, 389, 375
338282582546422, 191340608518886, 340003210160681 @ -162, 84, -46
276063330011297, 506267063607948, 451688278442130 @ -9, -360, -275
184895220833040, 346432574551322, 295370687370609 @ 190, -100, -32
191652244794317, 228752744289266, 232281189081226 @ -31, 21, 81
243836903069805, 200950090690864, 278486291904150 @ -28, 88, 22
99537538414359, 156839976263080, 330139497485318 @ 130, 130, -37
326389764039501, 504331313318919, 418345965619340 @ -131, -307, -163
148876210640065, 290152398181516, 301374612836089 @ 33, -38, 6
142515087922560, 255308120704690, 257170878718743 @ 68, 8, 52
295642841582982, 242101259588587, 104022418418097 @ -64, 55, 272
212300793229561, 261391853816696, 365490993544222 @ 18, 12, -93
165229346379582, 248276965460071, 161312784455361 @ 228, 79, 212
146531979069180, 97089275376773, 332003690930340 @ 22, 161, -23
120800899092132, 184913721524842, 473900231780358 @ 46, 68, -169
245193974976343, 210971062189687, 268026939360343 @ -33, 73, 36
442753793796843, 328612846899973, 283609914942486 @ -197, 51, -361
386255632768587, 458845472549101, 186183322563756 @ -53, -509, 253
31284818403777, 378560063574625, 130525938014247 @ 121, -131, 182
215792555249349, 255251601506749, 291132823173402 @ 53, 35, -5
440576428992381, 341794624061173, 283489603116870 @ -195, -71, -297
406821058032927, 358552748013016, 243495622599474 @ -84, -158, 37
333985935471117, 348387381803596, 196037336476056 @ 173, -110, 229
194315236713487, 480470439040782, 378290083309208 @ 51, -280, -115
423624567819357, 338961555301801, 243582531901236 @ 61, -23, -31
94275761968037, 416415875088596, 405203801734006 @ 101, -177, -111
182423650573104, 175953021338356, 485228050020492 @ 54, 122, -247
132946860128942, 343413209165262, 326300668034478 @ 36, -96, -17
372535536228591, 339775824243596, 291460134306860 @ -5, -78, -127
234895872588063, 62247228662200, 328601789968998 @ -48, 226, -29
219739080638176, 286527796435798, 280981600608968 @ 12, -20, 17
189527420319587, 44893660278076, 188459541975566 @ 71, 322, 143
380267121502632, 171933783462296, 62327709907551 @ -50, 486, 658
147002248372043, 129217307469322, 20610734515794 @ 72, 163, 337
378116309343993, 323069130988612, 248918730482046 @ 12, -7, 19
319333653031698, 278859269969079, 223866268814703 @ 52, 75, 106
236992756588085, 304463145397792, 340194522655246 @ -12, -44, -61
361033750565555, 283496102799226, 443655113595562 @ -186, -23, -175
235897203512717, 294114281232674, 253551760349992 @ -39, -37, 56
408102536955573, 333380318039952, 224743862672053 @ 133, 14, 168
293102890051939, 344678920502642, 319027665541226 @ -52, -97, -51
314560583563263, 247853680623604, 53638099642518 @ 168, 228, 683
358957968197762, 345732142415154, 247473914297280 @ 176, -100, 13
97749293379345, 58712595993126, 391620120825632 @ 43, 177, -72
322867629724035, 340590948643122, 203289896708124 @ 172, -81, 190
80125950337563, 291162150272609, 183137679036856 @ 67, -45, 129
258374458616771, 177916772961046, 144952832827550 @ -106, 67, 167
278357116203837, 305712540709126, 313477667351106 @ 25, -25, -67
264809045616867, 264739862065576, 262895162556366 @ 124, 82, 15
336748098976080, 273218710413310, 322060564461324 @ 30, 104, -167
429928385950838, 314414397421203, 244915322264740 @ -58, 209, -27
372274398572112, 231105491529412, 287140067936409 @ -124, 146, -34
300041946642210, 361805878294414, 348779219055194 @ 94, -140, -213
82333630198830, 239193100253797, 257911560955197 @ 188, 41, 48
226279166994495, 154940662484512, 108839076271560 @ -50, 110, 216
236988945746136, 219126354714877, 501245149354293 @ -46, 49, -232
290809399876260, 49865784333280, 261940365787665 @ 108, 638, 10
192479192269869, 89960784106480, 410601225475806 @ 72, 264, -171
154572048488187, 298722566659266, 216167781614996 @ 16, -49, 98
61402524224229, 314643942049666, 423478145912151 @ 85, -68, -106
358766524042277, 346694443835744, 276844061172806 @ -19, -102, -46
256397938412229, 266514037892864, 308510441425550 @ -38, 6, -19
111247170663991, 233159373163332, 468697849329816 @ 74, 24, -176
344810608922213, 303615399145216, 281518317463374 @ -63, -8, -23
362788311911379, 251466951828550, 193750060069434 @ -150, 55, 145
399463771643109, 390830800397568, 348214912693582 @ -56, -300, -427
410955878203009, 271492271760398, 451677568130560 @ -193, 83, -454
295197906839637, 437418987102341, 193165330189036 @ -59, -237, 141
154537540976799, 195927505433626, 181308919987650 @ 52, 77, 141
325985149258473, 250194915217672, 334102012662690 @ 108, 204, -238
124543315501773, 231620946800590, 338561758249206 @ 17, 11, -21
335269288780847, 561799450130906, 273598366143466 @ -160, -351, 33
406349536830357, 371696898098416, 244982099083326 @ -5, -260, 13
429820668866290, 271277644477337, 428343413274584 @ -246, 63, -343
285494082255787, 310483982523226, 238112394898756 @ 6, -35, 72
427654917316453, 283119550914376, 289816166586310 @ -171, 202, -189
183305780754531, 169697372808382, 507117795342356 @ -26, 79, -196
297993284172727, 148019247408016, 478413943821759 @ -109, 142, -218
448790421243093, 337156090194256, 245685544768734 @ -213, 32, -103
148786447967448, 318009921450292, 479155605119109 @ 14, -70, -172
179096144122083, 244536042632162, 235756205266522 @ 64, 35, 77
244534188760433, 150524896619640, 152520925860732 @ -45, 138, 178
292496348928869, 340309322862336, 330659178034254 @ -138, -93, -17
238428943280004, 398422698354598, 128738013198711 @ 18, -176, 234
313779278881410, 287246060199107, 290633760886106 @ -50, 5, -21
343288891378891, 429120523686379, 473870061316574 @ -25, -305, -513
446216226005587, 312289649316651, 248176797177231 @ -177, 407, -134
163307384848257, 225448720602800, 322389319780406 @ 31, 38, -21
311268063816389, 463933000929952, 394657123402262 @ -111, -254, -132
399765834273075, 254798002778062, 319132923186840 @ -106, 223, -222
349356303383841, 65751874037920, 238304141643426 @ 88, 934, 64
426197942876982, 275075125500838, 175524119141824 @ -134, 316, 425
244846911821769, 323674066198300, 382631479290586 @ -38, -71, -106
385903898932938, 293744669483637, 303997079396164 @ 28, 149, -255
122406691475152, 265274118970726, 228903355635336 @ 74, -8, 85
428147883934287, 336265506735295, 236428743456129 @ -49, -11, 58
155366097136407, 212516717519496, 138064536136086 @ 223, 134, 247
290272064856077, 53447685751876, 200629668873066 @ -21, 397, 136
289398699960341, 335225479948172, 258338577180554 @ -87, -85, 48
246644560074906, 346069755754627, 184752533814789 @ -18, -99, 146
325161489522083, 312478142191119, 272239125652590 @ 27, -15, -17
302526838060353, 250137788997644, 293451658437046 @ 34, 111, -51
381454405428627, 309591627716605, 247524198319020 @ -69, 15, 37
126242659748529, 415333404708478, 502742367002526 @ 43, -171, -201
391122049921137, 340901601859651, 268790805641181 @ 57, -73, -116
408757147462249, 380607987804743, 399264436774194 @ -223, -157, -197
447450951270780, 284852883292954, 255232938787050 @ -218, 628, -173
406627106978321, 345331129547776, 278775433455838 @ -252, -98, 35
102526860990768, 109719841541566, 426220057678866 @ 104, 172, -141
271417363832745, 226632607078180, 157778251273146 @ -48, 65, 184
380523128506570, 154723202351541, 260313283860234 @ 74, 867, -53
238921206316929, 132829025707360, 47904689664486 @ 244, 438, 549
307266763229071, 270719901259624, 186135881961708 @ 150, 130, 226
230319046492045, 395641124538336, 193363618743976 @ 57, -178, 144
392920766921985, 250496505188886, 306460703608653 @ -215, 32, -20
175231757780249, 44786823183916, 276624943135376 @ 63, 292, 24
313832948811675, 318445186003239, 306518285955873 @ 103, -21, -128
306551125497277, 524521381609762, 241622859608944 @ -79, -365, 68
400554436289624, 347460919638512, 297202409231189 @ 104, -114, -394
389736340819305, 335315093086228, 265059063401646 @ -48, -59, -41
59503995507231, 201984360420538, 424714963719588 @ 103, 48, -115
297143002633785, 96825557449276, 268699929004798 @ -62, 277, 27
390931858919397, 287914464138976, 302923821502446 @ -7, 167, -238
214729565570253, 278072872648670, 319237187952896 @ 25, -7, -36
96351544542113, 114755362054564, 394569159543638 @ 134, 181, -115
253200235356037, 258399369622746, 348809514314886 @ 101, 75, -149
382994713688163, 275642293727644, 356448448140994 @ -158, 40, -163
148649354883135, 340481142733222, 248790450117468 @ 142, -91, 58
134854692785701, 187209426614464, 175332404267278 @ 113, 106, 155
382031589203352, 338688148083646, 244506915572916 @ -60, -76, 45
369770189029605, 317508155457520, 250790362193010 @ 53, 18, 10
372683763999567, 414017337323254, 290899929550854 @ 6, -355, -133
147854567396103, 296200494966013, 360438786344609 @ 19, -47, -52
176792353279606, 312467680727934, 476850067726169 @ -12, -64, -172
302158177857665, 261529363847256, 256986683221090 @ -45, 42, 41
249078363310055, 282217233889320, 271610559471576 @ -52, -22, 34
221596566426841, 219861193819496, 360675578753842 @ -58, 32, -52
179819260650432, 199340653470439, 329496686830650 @ -34, 43, -13
276958462187159, 486380812406192, 159075856045308 @ -108, -250, 160
144557079593697, 131195974673911, 166883422178271 @ 9, 115, 146
490712615276709, 481688438412223, 460171428210714 @ -363, -337, -317
284673415638495, 320722646046907, 349991504659375 @ -113, -71, -48
184676509506952, 270068378274990, 290179021025201 @ -34, -24, 24
345990299479461, 297990031232524, 222968799598746 @ -107, -14, 99
233819171964981, 152061935722588, 108309431253774 @ -47, 123, 223
285477411975405, 291008044172421, 261721579922515 @ -35, -13, 36
407602868256117, 224700153604072, 183502997645982 @ -119, 368, 275
291327574782249, 286013931920310, 431294230944710 @ -137, -39, -117
443300983193571, 324683157114472, 251351540903257 @ -185, 118, -100
189572883657070, 462200497610916, 280153455698611 @ 18, -238, 24
308690692200416, 333877160265007, 236361595096541 @ 44, -71, 74
418654017001235, 348182837861720, 229046306673408 @ 50, -126, 130
378681238387569, 296901565820215, 156807910380587 @ -23, 79, 362
409371660135117, 326653269520726, 231465493326930 @ 121, 77, 105
426752119836365, 343370672093228, 244558686803006 @ -33, -79, -21
375852403443021, 293233964850016, 265899535913214 @ 92, 162, -79
326707607783589, 316318773568392, 309836065113046 @ 13, -27, -106
142911217221157, 261672665797202, 40658695646315 @ 21, -12, 278
244255603614037, 327276038377380, 279588160520382 @ 201, -55, -29
365680112763191, 94848689754348, 298094328264472 @ 24, 816, -154
330900038715639, 333095401980622, 263888598778833 @ -37, -72, 16
233128904088757, 257737506484816, 140807291739982 @ -34, 7, 191
296148164930181, 562101587574141, 250704068764416 @ -11, -493, 49
194944987544711, 293883929666758, 290731532680414 @ -42, -47, 23
322305098222037, 370061146918651, 477144215849956 @ -59, -143, -363
182728803240756, 281103277585801, 285622771243386 @ 18, -23, 19
383519700815905, 345082260451353, 403471475241446 @ -15, -97, -601
321303031096657, 382801663317526, 207761312476516 @ -33, -173, 132
82652246408061, 397368423356176, 12561618050022 @ 58, -148, 292
386132571381159, 290050051464719, 201828131188626 @ 79, 209, 259
179334089326071, 197614868629114, 332406359271651 @ -5, 60, -26
262093968892863, 107075329722362, 414807233851420 @ 34, 315, -234
229016437887321, 253800281514190, 442412418387360 @ -21, 15, -178
435464268415533, 304740242014684, 308396918820801 @ -83, 370, -776
434507208806365, 509232372383340, 444474239318010 @ -265, -381, -284
268752689610051, 291591481519324, 295468449312780 @ 122, 24, -60
388988596465428, 462487948867582, 429870272877633 @ -122, -416, -452
66784011152624, 361184408854064, 406644902129688 @ 92, -114, -95
417437370920109, 239344427883568, 200940613813092 @ 9, 790, 358
258122981051685, 455818141956768, 500343012517998 @ -47, -240, -263
428885056879621, 395958064188608, 336285404809233 @ -267, -162, -50
371904496065333, 505347295365256, 482265546690900 @ -83, -518, -572
268921212718412, 421249637667076, 105902059281656 @ -94, -182, 221
245666370615068, 296820628562753, 359611784427307 @ 32, -21, -120
266636285971089, 251550010433302, 261367259665596 @ -57, 23, 44
381991540551663, 283471564116926, 250211504748680 @ 22, 177, 8
107026635297788, 445380665254476, 456350458942680 @ 48, -198, -143
436947285540239, 350951442595312, 282325390191614 @ -78, -170, -537
145398660803727, 195609983658656, 242158434889096 @ 130, 110, 68
297475449394982, 131750381092515, 165719703479968 @ -84, 195, 173
382981082215082, 318082716962228, 217519872859947 @ -184, -54, 106
274508569926281, 337480597564942, 249069272308048 @ 113, -80, 45
409006873082037, 404306234256766, 306773089718196 @ 101, -620, -563
304326995325327, 252632813540085, 317502450159756 @ -29, 69, -71
335336102392062, 349032727458751, 147869871751056 @ -10, -107, 289
224490789327707, 138112263823786, 214964316118086 @ -13, 160, 103
257483144012212, 310616650691101, 220817557849225 @ 126, -23, 108
378616249658565, 487631090875856, 211845741661518 @ -137, -403, 127
256962996060820, 363038059754788, 382290100571323 @ 102, -134, -222
376113767407764, 419697564588036, 503311772819474 @ -68, -318, -717
411690063697784, 334901544443134, 250358939380980 @ -30, -32, -23
378730592174173, 292937924939892, 216595109883586 @ -21, 95, 144
386233907852537, 102017803023726, 148605073075956 @ -49, 797, 394
401023678402335, 326392143373252, 250508593182692 @ -80, -20, 12
187386788876757, 222440010076216, 5544716539566 @ 107, 89, 427
211506671096437, 295843684641176, 394227297865006 @ 59, -25, -157
170237159382989, 228511580730636, 335783635953320 @ 17, 32, -34
293589456751485, 294178241627518, 249641359155174 @ -7, -5, 51
439854842455119, 383935112515580, 293031876578902 @ -218, -316, -253
295518506383932, 200374788948199, 229951840543641 @ -114, 71, 84
394189872421409, 331448531001974, 256407864771135 @ -31, -36, -20
311925984995885, 332357949681136, 293917117060350 @ 30, -68, -59
389447608973881, 380513707763144, 244720406589022 @ -126, -192, 51
366016540138437, 277293281705376, 413687743953006 @ 130, 233, -794
298178291530224, 268217681216719, 304180593974067 @ -38, 31, -38
308018243676123, 296892693397840, 274894177156788 @ -130, -42, 32
60232254901961, 170686288518732, 262671045190162 @ 89, 74, 51
124745624448567, 151652758178730, 163358199121217 @ 31, 96, 150
321860786503481, 302448169248892, 261445808573098 @ -12, -5, 20
205692521446297, 89407037159596, 410049214010034 @ 36, 247, -158
239982788772333, 137286217774368, 174295345603502 @ -56, 138, 147
86731844681439, 259688488792764, 210340217835198 @ 70, -12, 103
170808423768189, 228588666791260, 293948466808818 @ 19, 33, 12
441057939686395, 343398690648711, 549228030221401 @ -265, -93, -736
302443946246812, 240143840858176, 379420862083931 @ -22, 94, -186
345088720716403, 315552253051151, 268545755397918 @ 159, 27, -65
423724795313077, 308659354107536, 180782338151766 @ -63, 186, 493
406798864217260, 293663253737166, 320278735045387 @ -88, 132, -304
195154781190237, 364862205409626, 254799516896806 @ -47, -117, 59
178932977335797, 251708835992206, 247843728908376 @ 45, 19, 62
253349271834117, 283691186580304, 303498852558606 @ -9, -9, -21
376761673051257, 285602705599686, 270257629743006 @ -41, 101, -41
300882491178039, 290243550583162, 189772203039720 @ -68, -15, 146
235369194657157, 421562658281976, 408227743490686 @ -55, -183, -115
188646633711105, 318918710332479, 369157982422215 @ 73, -61, -110
395512774201357, 315616825750976, 285497663723286 @ 96, 102, -266
421677117457729, 302462002478370, 260176983480688 @ -57, 221, -114
177175197731565, 341281080915196, 331441656855726 @ 43, -93, -41
325478665927397, 441871023252256, 224988749860460 @ 21, -338, 102
402136003642932, 333799366036756, 296817265196841 @ 8, -30, -290
182104997730129, 336028786762480, 74550271859558 @ 52, -86, 285
292043981673693, 259010054670568, 310880696340486 @ -98, 9, -16
327463887597202, 275386444030262, 281725872502210 @ 96, 120, -69
180350572694521, 204046517624548, 270869833505754 @ 15, 64, 37
261796476524925, 143723242270984, 124690998413814 @ -90, 121, 198
382022380467301, 363084132643328, 342504705272910 @ -51, -159, -293
359686755049611, 309851948068594, 254216163279732 @ 18, 21, 12
432383902550757, 325288945907500, 237103658765274 @ -139, 49, 58
199141995287962, 12205123960005, 135322914113123 @ 276, 653, 302
388209037680334, 326840502219633, 280212599819923 @ 90, 11, -192
398309490013959, 467459019065502, 435027019897864 @ -245, -216, -115
438077885264229, 338437435266016, 251421696960654 @ -147, -33, -83
142623030672997, 313922309635776, 172051026248046 @ 197, -48, 178
211793103082053, 258637524078497, 413519499042315 @ -11, 5, -134
316227539793914, 330807868031342, 320059762270916 @ -90, -76, -51
363745515105897, 308033947226491, 241876133298636 @ 9, 29, 53
229073101043463, 182441744874760, 375616182031518 @ -6, 114, -105
311663766702322, 293169473612442, 266993157354132 @ -64, -12, 25
165743821901955, 245775966807730, 293803407552466 @ 40, 19, 9
349142785799508, 280261145006550, 287389255673128 @ 124, 164, -135
299220074031339, 172470550513459, 207086145840829 @ -65, 163, 120
51599932704531, 110067755093612, 120750763264579 @ 187, 186, 216
362339688007455, 128526862135900, 213561367782111 @ 123, 898, 174
318235966547318, 236743583502987, 172190463362498 @ -150, 21, 147
243218064862137, 146112647037076, 312898709705706 @ -12, 173, -28
248532762868587, 127913038997386, 306713186523936 @ -89, 124, 5
356833591049452, 288318963368346, 175747488009196 @ -36, 56, 237
429258217460035, 281264286545936, 199918966637106 @ -81, 462, 379
288595615758281, 286112367984743, 301320148789454 @ 17, 15, -49
434137829300957, 385164566787576, 251517643175406 @ -90, -513, -101
226684015769909, 393228920796224, 237234101626834 @ 5, -162, 75
277608974085399, 484613028229744, 346163443971816 @ -86, -266, -56
439564663355742, 339477585210058, 360927913554417 @ -264, -84, -224
243540738730971, 359735080690960, 250444934709888 @ -65, -114, 61
414936626664123, 309300663907822, 216629185840824 @ -56, 125, 188
397872703252389, 212898395772056, 240610671804790 @ -131, 297, 60
123154693229737, 203455201989076, 290045021180228 @ 51, 52, 20
268437039198703, 312957758717668, 372983507517126 @ -58, -56, -101
290041101495914, 452525408726809, 261168521158394 @ 18, -305, 27
94022340218020, 214444823962799, 233285115180485 @ 78, 39, 80
187758784146701, 308231925236552, 42842321977264 @ 17, -54, 306
298993330355122, 276052686620461, 298685552862006 @ -10, 31, -41
332169842700025, 298970888104540, 302981537331018 @ -70, -11, -50
194328822595255, 76283873425353, 136668594275728 @ 239, 459, 281
120250832193905, 241032280181964, 229456138785466 @ 50, 11, 84
151422919814977, 301022504515816, 378981998111542 @ 111, -38, -117
96990387183037, 372867516983776, 14714289836806 @ 168, -134, 366
274942199061477, 481640626788556, 14527007819946 @ -11, -317, 432
224838145952262, 313821556817251, 263551720120806 @ 14, -55, 39
403167845873627, 244787413886076, 196299464895806 @ -30, 432, 279
423651938100112, 435225368641841, 336353363207841 @ -264, -201, -38
289166585859768, 74894176976193, 138452721266517 @ 130, 605, 328
431669875459573, 325370084156409, 252462190860946 @ -27, 143, -141
390448274978984, 338265610742420, 231189470189675 @ 98, -54, 98
237855310336712, 79275006966921, 512264534723696 @ -64, 191, -223
430777549022346, 301130642558299, 294289756858713 @ -166, 153, -262
222272412127973, 253877615323776, 267895382908238 @ 18, 27, 33
165432519670262, 95007658128776, 226194378092481 @ 24, 182, 88
281007118242885, 330242484331812, 296563154696266 @ -35, -75, -16
359290360054469, 394969290711776, 300557072988910 @ -60, -223, -88

5
2023/input/24/test-1 Normal file
View File

@ -0,0 +1,5 @@
19, 13, 30 @ -2, 1, -2
18, 19, 22 @ -1, -1, -2
20, 25, 34 @ -2, -2, -4
12, 31, 28 @ -1, -2, -1
20, 19, 15 @ 1, -5, -3

221
2023/src/bin/day24.rs Normal file
View File

@ -0,0 +1,221 @@
#![feature(test)]
extern crate nalgebra as na;
use std::{str::FromStr, convert::Infallible, collections::HashMap};
use anyhow::Result;
use aoc::Solver;
use na::{SMatrix, SVector};
// -- Runners --
fn main() -> Result<()> {
Day::solve()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1_test1() -> Result<()> {
Day::test(Day::part1, "test-1", 2)
}
#[test]
fn part1_solution() -> Result<()> {
Day::test(Day::part1, "input", 13149)
}
#[test]
fn part2_test1() -> Result<()> {
Day::test(Day::part2, "test-1", 47)
}
#[test]
fn part2_solution() -> Result<()> {
Day::test(Day::part2, "input", 1033770143421619)
}
// Benchmarks
extern crate test;
#[bench]
#[ignore]
fn part1_bench(b: &mut test::Bencher) {
Day::benchmark(Day::part1, b)
}
#[bench]
#[ignore]
fn part2_bench(b: &mut test::Bencher) {
Day::benchmark(Day::part2, b)
}
}
#[derive(Debug, Clone, Copy)]
struct Hailstone {
px: f64,
py: f64,
pz: f64,
vx: f64,
vy: f64,
vz: f64
}
impl Hailstone {
fn intersect_2d(&self, other: &Hailstone) -> Option<(f64, f64)> {
let dx = self.px - other.px;
let dy = self.py - other.py;
let d = self.vy * other.vx - self.vx * other.vy;
let t1 = (other.vy*dx - other.vx * dy) / d;
let t2 = (self.vy * dx - self.vx*dy) / d;
if t1.is_sign_negative() || t2.is_sign_negative() {
// Intersection is in the past
return None;
}
let x = self.px + self.vx * t1;
let y = self.py + self.vy * t1;
if x.is_infinite() || y.is_infinite() {
// Paths are parallel
return None;
}
Some((x, y))
}
}
impl FromStr for Hailstone {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts: Vec<f64> = s.split([',', '@']).map(|part| part.trim().parse().unwrap()).collect();
Ok(Hailstone {
px: parts[0],
py: parts[1],
pz: parts[2],
vx: parts[3],
vy: parts[4],
vz: parts[5],
})
}
}
fn mode(numbers: &[usize]) -> usize {
let mut occurrences = HashMap::<_, usize>::new();
for &value in numbers {
*occurrences.entry(value).or_insert(0) += 1;
}
println!("{occurrences:?}");
occurrences.into_iter().max_by_key(|&(_, count)| count).map(|(value, _)| value).unwrap()
}
// -- Solution --
pub struct Day;
impl aoc::Solver for Day {
type Output1 = usize;
type Output2 = usize;
fn day() -> u8 {
24
}
fn part1(input: &str) -> Self::Output1 {
let hailstones: Vec<_> = input.lines().flat_map(Hailstone::from_str).collect();
let range = if hailstones.len() == 5 {
7.0..=27.0
} else {
200000000000000.0..=400000000000000.0
};
hailstones.iter().enumerate().flat_map(|(index_a, a)| {
hailstones.iter().enumerate().filter(|(index_b, _)| index_b < &index_a).filter_map(|(_, b)| {
a.intersect_2d(b)
}).collect::<Vec<_>>()
}).filter(|&(x, y)| range.contains(&x) && range.contains(&y)).count()
}
fn part2(input: &str) -> Self::Output2 {
let h: Vec<_> = input.lines().flat_map(Hailstone::from_str).collect();
// Key insight for part 2 is
// p_rock + v_rock * t_i = p_i + v_i * t_i
// for every hailstone i
//
// This can be rewritten as
// p_rock - p_i = t_i * (v_i - v_rock)
// and since t_i is a scalar this means that
// (p_rock - p_i) is parallel to (v_i - v_rock)
// and therefore
// c_i = (p_rock - p_i) x (v_i - v_rock) = 0
// This holds true for every hailstone i, so
// c_i = c_j
// c_i = c_k
// with i != j != k
// Writing out these equations leads to a set of six linear equations
// And can therefore be written in matrix form
// A * solution = constant
// And the solution can now be found using
// solution = A^-1 * constant
let i = 0;
let j = 1;
// Due to numerical instability we run this with several different options for the third
// hailstone
let solutions: Vec<_> = (2..h.len()).map(|k| {
// Constant in the matrix
let c1 = h[i].vz - h[j].vz;
let c2 = h[i].py - h[j].py;
let c3 = h[j].vy - h[i].vy;
let c4 = h[j].pz - h[i].pz;
let c5 = h[i].vx - h[j].vx;
let c6 = h[j].px - h[i].px;
let c7 = h[i].vz - h[k].vz;
let c8 = h[i].py - h[k].py;
let c9 = h[k].vy - h[i].vy;
let c10 = h[k].pz - h[i].pz;
let c11 = h[i].vx - h[k].vx;
let c12 = h[k].px - h[i].px;
// Setup the matrix
let matrix = SMatrix::<f64, 6, 6>::new(
0.0, c1, c3, 0.0, c4, c2,
-c1, 0.0, c5, -c4, 0.0, c6,
-c3, -c5, 0.0, -c2, -c6, 0.0,
0.0, c7, c9, 0.0, c10, c8,
-c7, 0.0, c11, -c10, 0.0, c12,
-c9, -c11, 0.0, -c8, -c12, 0.0
);
// Get the inverse of the matrix
let inverse = matrix.try_inverse().unwrap();
// Constant on the rhs
let k1 = h[i].py*h[i].vz - h[j].py*h[j].vz + h[j].pz*h[j].vy - h[i].pz*h[i].vy;
let k2 = h[i].pz*h[i].vx - h[j].pz*h[j].vx + h[j].px*h[j].vz - h[i].px*h[i].vz;
let k3 = h[i].px*h[i].vy - h[j].px*h[j].vy + h[j].py*h[j].vx - h[i].py*h[i].vx;
let k4 = h[i].py*h[i].vz - h[k].py*h[k].vz + h[k].pz*h[k].vy - h[i].pz*h[i].vy;
let k5 = h[i].pz*h[i].vx - h[k].pz*h[k].vx + h[k].px*h[k].vz - h[i].px*h[i].vz;
let k6 = h[i].px*h[i].vy - h[k].px*h[k].vy + h[k].py*h[k].vx - h[i].py*h[i].vx;
// Put them into a vector
let k = SVector::<f64, 6>::new(k1, k2, k3, k4, k5, k6);
// Calclate the solution
let solution = inverse * k;
// The sum of all elements of the starting position is the answer
(solution[0] + solution[1] + solution[2]).round() as usize
}).collect();
// The most common solution is the actual solution
mode(&solutions)
}
}