Day 19 solution

Cribbed from some posts on the subreddit. I don't know why this one was so difficult for me.
This commit is contained in:
2022-12-21 23:12:50 -06:00
parent aba8631366
commit 5e91487466
4 changed files with 402 additions and 856 deletions

View File

@ -79,6 +79,7 @@
<EmbeddedResource Include="inputs\18b.txt" /> <EmbeddedResource Include="inputs\18b.txt" />
<EmbeddedResource Include="inputs\19.txt" /> <EmbeddedResource Include="inputs\19.txt" />
<None Remove="inputs\20.txt" /> <None Remove="inputs\20.txt" />
<EmbeddedResource Include="inputs\19a.txt" />
<EmbeddedResource Include="inputs\20.txt" /> <EmbeddedResource Include="inputs\20.txt" />
<None Remove="inputs\21.txt" /> <None Remove="inputs\21.txt" />
<EmbeddedResource Include="inputs\20a.txt" /> <EmbeddedResource Include="inputs\20a.txt" />

View File

@ -1,856 +1,30 @@
--- scanner 0 --- Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 11 clay. Each geode robot costs 3 ore and 8 obsidian.
536,703,543 Blueprint 2: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 14 clay. Each geode robot costs 3 ore and 16 obsidian.
-132,-41,-64 Blueprint 3: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 3 ore and 9 obsidian.
-429,350,-809 Blueprint 4: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 15 clay. Each geode robot costs 2 ore and 8 obsidian.
-477,567,455 Blueprint 5: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 8 clay. Each geode robot costs 2 ore and 18 obsidian.
-369,-732,-732 Blueprint 6: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 7 clay. Each geode robot costs 4 ore and 20 obsidian.
-806,-680,810 Blueprint 7: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 6 clay. Each geode robot costs 2 ore and 20 obsidian.
502,729,469 Blueprint 8: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 10 clay. Each geode robot costs 4 ore and 10 obsidian.
-417,400,-831 Blueprint 9: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 15 clay. Each geode robot costs 4 ore and 16 obsidian.
497,-739,-564 Blueprint 10: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 19 clay. Each geode robot costs 4 ore and 12 obsidian.
-545,-726,-743 Blueprint 11: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 3 ore and 17 obsidian.
271,357,-605 Blueprint 12: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 19 clay. Each geode robot costs 2 ore and 12 obsidian.
13,-26,94 Blueprint 13: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 16 clay. Each geode robot costs 4 ore and 17 obsidian.
508,-654,-647 Blueprint 14: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 4 ore and 9 obsidian.
-581,-685,774 Blueprint 15: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 17 clay. Each geode robot costs 3 ore and 7 obsidian.
396,-908,355 Blueprint 16: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 4 ore and 9 obsidian.
-481,568,418 Blueprint 17: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 3 ore and 8 obsidian.
-634,-665,910 Blueprint 18: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 11 clay. Each geode robot costs 2 ore and 7 obsidian.
306,410,-668 Blueprint 19: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 18 clay. Each geode robot costs 2 ore and 19 obsidian.
540,739,539 Blueprint 20: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 4 ore and 8 obsidian.
465,-656,-423 Blueprint 21: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 9 clay. Each geode robot costs 3 ore and 7 obsidian.
-474,-628,-795 Blueprint 22: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 5 clay. Each geode robot costs 3 ore and 12 obsidian.
-463,568,426 Blueprint 23: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 3 ore and 19 obsidian.
254,306,-662 Blueprint 24: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 16 clay. Each geode robot costs 3 ore and 9 obsidian.
358,-788,353 Blueprint 25: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 9 clay. Each geode robot costs 4 ore and 16 obsidian.
-396,313,-691 Blueprint 26: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 12 clay. Each geode robot costs 2 ore and 10 obsidian.
251,-873,452 Blueprint 27: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 8 clay. Each geode robot costs 3 ore and 19 obsidian.
Blueprint 28: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 7 clay. Each geode robot costs 3 ore and 9 obsidian.
--- scanner 1 --- Blueprint 29: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 4 ore and 11 obsidian.
405,377,-919 Blueprint 30: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 2 ore and 20 obsidian.
-471,604,350
479,506,644
495,326,707
-407,-663,-846
618,-537,318
-584,506,-618
-577,-375,640
682,-442,283
-579,-587,598
612,361,-928
-253,-680,-729
512,382,-895
531,379,751
-468,-460,659
-262,-699,-913
974,-376,-550
539,-333,326
917,-437,-630
-422,787,372
48,7,-59
-451,618,404
-697,390,-626
-766,485,-587
971,-556,-663
--- scanner 2 ---
-652,-598,521
680,708,-671
401,-847,-328
-666,588,522
-629,-292,-571
256,-750,-363
-576,-428,-551
-698,690,-828
640,385,384
698,679,-614
-801,-392,-556
490,-475,680
-594,-543,549
27,-15,66
-878,546,524
-703,476,-864
741,661,-790
-793,527,633
506,-675,668
-736,691,-860
-646,-597,737
650,579,455
363,-849,-448
-77,-44,-102
636,387,485
609,-565,657
--- scanner 3 ---
-694,-480,675
-79,48,-39
-713,754,292
329,-686,-566
352,-717,-653
689,385,454
-736,862,-562
-619,615,350
687,515,-478
754,359,540
-741,-551,707
-416,-641,-826
780,-406,714
757,427,547
-766,670,-548
376,-703,-591
-676,-675,645
616,-364,628
-413,-651,-750
-645,601,324
-837,864,-558
618,546,-543
651,-444,702
-438,-700,-839
735,493,-571
--- scanner 4 ---
-530,746,312
786,-443,556
-889,-559,548
707,-625,-700
-597,746,-565
-695,733,324
797,-456,613
521,468,-520
798,-448,530
-820,-811,-882
-905,-712,-989
700,666,439
759,795,432
637,796,456
-877,-533,314
-887,-526,362
671,-621,-704
-575,696,330
-940,-809,-844
-478,699,-504
-654,717,-547
-56,111,-123
529,444,-427
618,407,-518
697,-695,-738
--- scanner 5 ---
-622,-664,638
91,56,-46
-584,-588,503
-597,-542,-844
637,-732,382
541,-389,-695
608,849,773
-824,472,329
-715,664,-901
-807,472,398
696,824,658
-748,513,423
734,-704,553
-603,-571,-996
702,-641,519
-564,648,-902
-546,-560,-802
529,757,-875
-774,670,-893
710,934,780
-633,-647,616
45,186,-187
571,805,-747
469,-300,-758
548,722,-801
470,-365,-800
--- scanner 6 ---
-63,90,49
498,853,-791
578,-569,-624
-655,-638,533
625,-555,-405
612,-558,-546
481,703,-791
472,508,699
-676,-594,581
641,-783,554
689,489,688
-597,648,491
-588,829,-432
447,-795,466
-611,-448,-552
-628,702,-523
517,666,-715
-730,-425,-642
-606,719,-512
-714,-437,-442
-537,611,499
-462,665,425
597,478,703
460,-784,616
-648,-556,677
--- scanner 7 ---
845,881,-301
-501,-349,486
-315,-608,-344
-480,685,-388
718,980,-308
915,979,627
-279,-529,-320
749,-436,411
-508,-323,638
-557,-346,709
744,-481,476
738,-636,412
-431,775,-306
-486,759,-520
378,-599,-409
-575,569,537
538,-579,-380
94,37,37
-656,696,463
931,951,534
931,865,728
448,-570,-525
-739,579,511
-301,-469,-277
782,925,-452
--- scanner 8 ---
-642,587,781
449,768,-502
-541,-248,454
-652,688,-666
-657,-301,345
388,565,306
-711,575,-617
-597,592,716
31,60,-133
-705,-303,534
-728,553,-628
518,471,325
-449,-629,-686
-462,-608,-643
399,395,424
573,-579,-519
-49,145,4
485,-560,410
365,-564,556
408,793,-443
-580,-592,-693
542,-671,-541
408,862,-426
380,-463,470
-442,598,780
580,-773,-513
--- scanner 9 ---
511,-520,557
831,490,487
-549,-659,-680
536,-615,-490
165,-84,33
652,-552,474
-516,602,-544
-439,-556,-691
-267,-451,305
-822,579,548
-571,544,-572
-16,-6,-106
841,452,-616
-517,596,-760
-364,-306,340
584,-594,-534
820,314,481
680,-622,-572
883,419,585
-722,751,533
-639,-540,-703
735,-563,559
947,393,-650
-686,526,528
905,520,-588
-265,-413,425
--- scanner 10 ---
-737,650,-388
799,760,694
-389,-453,768
-667,-803,-543
537,-419,977
573,-564,910
699,461,-254
-644,698,-366
-657,-874,-737
556,-410,793
-672,581,-419
-653,-773,-735
680,814,727
78,-167,23
-376,-475,827
861,-734,-576
649,-736,-534
776,-625,-595
-649,292,813
860,817,614
-624,339,830
50,-20,162
-465,-450,778
-562,315,844
903,382,-262
794,525,-219
--- scanner 11 ---
99,76,34
-676,680,608
-416,-818,449
-383,-733,-582
-278,-673,-485
-263,-587,-586
-297,-719,373
610,574,866
544,-363,576
743,689,-672
-817,391,-552
-607,706,535
601,429,776
-805,494,-602
-779,332,-498
699,-427,570
703,798,-570
759,-798,-323
643,-689,-270
-605,648,465
648,653,-655
-286,-837,543
-21,-98,124
581,458,936
807,-609,-325
744,-362,565
--- scanner 12 ---
-425,-551,749
399,-500,-745
621,-564,617
458,551,789
-771,404,712
-635,-782,-410
141,-60,-11
-407,-500,691
427,311,-461
434,438,-362
-786,391,773
-533,-750,-406
578,374,-417
420,485,830
376,378,782
-602,225,-477
535,-509,559
-733,594,734
652,-499,714
-466,-660,638
375,-461,-524
-501,241,-363
13,-15,-141
392,-416,-592
-585,-935,-464
-408,225,-391
--- scanner 13 ---
-869,-562,284
-626,-660,-761
863,541,-592
-615,-577,-676
594,-454,-831
-713,476,667
915,554,-452
621,-462,713
528,750,450
680,-516,627
-640,407,641
-783,478,609
866,578,-609
-705,797,-876
-875,786,-758
662,-561,828
-658,-801,-678
524,593,486
-852,-619,335
-799,667,-857
-817,-556,388
479,-362,-887
490,705,572
101,-76,-131
-40,-1,16
414,-474,-816
--- scanner 14 ---
441,817,-678
-598,650,753
371,-553,781
-510,-749,-608
9,-9,185
364,-412,661
-698,-767,-537
-695,787,-546
-93,144,106
676,-367,-546
-564,746,-667
478,752,-535
-588,-350,394
565,773,-725
-587,-306,537
-678,698,-692
-773,-762,-605
-393,632,689
597,749,893
827,-282,-517
-490,578,681
380,-405,668
808,-318,-662
578,692,850
579,917,825
-578,-442,497
--- scanner 15 ---
711,434,636
-814,919,616
-367,796,-569
667,-597,612
637,-360,-736
668,-381,618
699,-371,-662
-351,789,-562
591,759,-398
786,439,704
128,62,-70
-793,-527,-586
722,-569,670
-754,-553,694
600,895,-438
601,851,-295
-796,-491,821
-663,834,645
-795,883,761
-690,-470,-654
-728,-676,-612
-690,-525,762
639,-287,-734
-358,648,-682
523,452,707
--- scanner 16 ---
509,-793,667
878,553,565
-582,760,-790
-599,-400,-777
581,-549,-837
-498,-416,-891
-405,-400,-863
-530,575,-848
769,655,525
-8,-11,-79
538,-953,687
90,-139,81
-529,308,461
402,325,-509
-282,-582,524
-347,-587,569
654,-883,658
-718,306,509
-609,253,625
-283,-593,724
-632,607,-844
430,-486,-793
395,241,-662
437,-613,-892
733,638,620
378,286,-730
--- scanner 17 ---
754,602,-677
-722,-580,-369
-439,722,669
-372,731,-647
16,-1,-34
164,118,125
433,-796,-390
474,-459,828
943,619,739
-765,-605,576
-402,923,-633
697,631,-695
873,649,-738
-700,-639,-356
592,-518,899
-756,-789,557
566,-719,-309
475,-540,761
-725,-590,-445
692,-807,-381
-611,-722,593
-550,783,796
911,620,701
-441,764,881
-301,925,-637
947,834,706
--- scanner 18 ---
113,-179,93
-709,565,-575
-585,-728,588
812,527,-496
-496,315,704
-367,364,615
939,-532,762
727,472,-351
701,704,557
-312,-886,-799
944,-633,873
-779,594,-691
-533,-891,548
499,-602,-827
-608,-769,451
-375,-930,-648
-619,574,-720
829,432,-460
460,-823,-851
757,693,547
415,-755,-834
950,-664,733
-439,-985,-792
702,691,743
-341,400,702
--- scanner 19 ---
765,-723,-476
-795,553,792
640,682,-495
138,123,77
648,-491,767
617,736,-578
-556,-542,581
-679,-488,-787
-738,-463,-828
-755,-394,-828
508,578,559
779,-845,-366
-638,-549,725
489,795,570
611,-431,759
665,-356,833
478,703,555
80,10,-59
-594,-570,677
-783,747,704
-705,828,-630
677,-838,-451
-784,566,642
-495,837,-652
598,810,-543
-646,836,-636
--- scanner 20 ---
698,-671,896
-629,-578,570
882,-690,887
633,-486,-344
815,-654,742
862,582,-466
-307,396,-533
-671,-366,572
556,494,383
-327,471,-605
-403,796,727
-526,-508,-812
-690,-451,681
-48,50,4
595,399,452
-741,-541,-816
-435,627,698
-381,613,678
611,-348,-461
-527,-546,-780
587,515,565
887,614,-414
-361,524,-418
552,-419,-343
867,468,-504
--- scanner 21 ---
591,695,-643
-461,-434,378
876,-525,845
447,688,-725
-609,715,615
858,-320,-565
-724,-437,365
752,-379,-599
725,-496,760
816,-447,-627
413,806,524
-598,737,632
-528,629,-524
-660,-471,-643
-649,-505,360
405,746,561
-606,-523,-455
-605,-529,-671
-638,732,-535
339,881,578
-110,154,-71
857,-380,809
38,67,-3
-518,755,742
495,667,-681
-728,613,-512
--- scanner 22 ---
417,869,-670
-390,-523,-643
668,-601,466
-449,460,555
-411,652,-704
757,407,838
-332,-429,-504
-399,817,-717
-14,26,-96
-635,458,588
549,-578,556
-401,470,562
-674,-468,562
-687,-471,703
-364,-497,-657
460,693,-688
508,-376,-588
902,442,741
478,750,-717
518,-305,-394
652,-589,666
109,117,38
-417,772,-667
795,527,840
-640,-457,484
522,-406,-396
--- scanner 23 ---
-800,-816,-415
486,376,-362
-411,496,636
260,419,326
-938,-671,519
1,-24,20
359,-713,278
-930,-835,-509
-611,650,-431
668,-637,-556
429,325,-345
-833,-731,616
423,429,-397
282,369,338
-953,-585,620
400,332,305
296,-609,383
-437,334,532
-919,-717,-339
348,-707,454
527,-720,-588
444,-635,-599
-540,682,-574
-186,11,-59
-399,393,586
-609,708,-501
--- scanner 24 ---
661,560,-615
-838,-878,-425
756,-980,519
-430,-499,528
-840,792,-299
-891,-834,-389
730,337,599
-711,491,690
-613,-477,577
-835,768,-406
-827,499,803
792,592,-663
-711,-771,-373
656,286,631
-856,801,-506
-42,-81,88
841,216,626
-599,-531,557
767,-854,387
754,-461,-726
-732,460,872
859,-869,436
668,-426,-620
626,-548,-657
802,511,-703
--- scanner 25 ---
871,758,-518
-441,-709,335
458,576,380
704,-742,-632
-721,571,786
-803,-452,-835
-752,658,763
-711,565,-686
828,638,-529
-687,377,-660
392,-542,358
-686,530,-584
818,761,-520
-888,-342,-883
480,483,428
-798,-414,-880
324,-535,361
-399,-623,499
-54,-43,48
511,548,497
350,-449,426
807,-776,-756
-738,596,739
81,137,-43
716,-700,-860
-479,-697,464
--- scanner 26 ---
-901,-451,391
-534,-435,-744
-383,810,622
-7,71,53
474,684,458
-861,602,-891
-769,-567,440
-571,-578,-679
-457,735,676
605,-576,840
-920,-596,355
417,-505,822
680,-508,835
384,612,-707
471,-446,-673
462,781,-698
565,644,585
-864,517,-869
554,666,568
-909,737,-873
-658,-388,-700
-449,675,639
585,-421,-625
602,-567,-714
397,746,-782
--- scanner 27 ---
-490,-562,-654
501,516,490
-310,-612,762
560,738,-569
587,-506,-667
-782,970,-551
-729,935,-614
-289,-544,-609
424,433,614
606,-412,-491
-833,987,-608
378,-468,689
-404,-503,-708
391,546,639
487,738,-654
-436,705,597
451,-491,621
-400,701,593
-321,-555,775
567,-397,668
81,40,90
582,667,-630
-410,739,523
-309,-529,770
657,-413,-678
--- scanner 28 ---
69,84,-59
-289,-502,-551
595,-623,583
-456,920,-639
583,-423,567
778,439,713
-576,755,732
714,-491,-517
-307,-690,-480
-693,808,704
879,437,717
739,598,-801
-377,912,-843
-645,786,797
741,640,-589
-544,-542,669
742,-546,-575
-520,955,-734
606,-513,686
526,-545,-569
-671,-633,709
-561,-553,691
-294,-427,-483
808,631,727
630,579,-716
--- scanner 29 ---
554,-452,430
712,317,-664
554,-470,422
-577,514,-619
-735,-733,754
-625,-635,-349
419,547,547
-441,819,564
-504,514,-704
-518,736,440
809,-385,-687
30,-54,-66
722,-406,-827
-599,585,-680
772,-418,-805
-123,-145,56
765,282,-601
-662,-695,652
-660,-788,804
383,551,543
-650,-675,-301
-723,-747,-314
-408,706,589
555,-466,459
393,513,473
-30,28,95
816,265,-658
--- scanner 30 ---
648,439,-720
-883,-704,-653
760,676,623
681,-717,482
288,-461,-535
739,-762,425
752,755,827
-682,-622,380
-665,-711,526
278,-470,-658
-587,838,467
-793,461,-725
588,-655,448
-850,825,464
-702,588,-685
-662,843,535
-870,-779,-787
795,612,718
-796,-670,405
595,556,-748
5,-51,26
235,-459,-538
-131,33,-79
-805,-695,-822
-713,571,-707
626,487,-813

2
inputs/19a.txt Normal file
View File

@ -0,0 +1,2 @@
Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian.
Blueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian.

369
src/19.cs Normal file
View File

@ -0,0 +1,369 @@
using System.Text.RegularExpressions;
namespace aoc2022;
internal partial class Day19 : Day
{
private enum resource
{
ore = 1,
clay = 2,
obsidian = 3,
geode = 4,
}
private class cost
{
public resource type;
public int amount;
public override string ToString() => $"{amount} {type}";
}
private class blueprint
{
public int id;
public Dictionary<resource, List<cost>> robots = new();
public override string ToString() => $"({robots.Count}) {string.Join("; ", robots)}";
}
private class miningSim
{
public miningSim(blueprint bp, int timeLimit = 24)
{
this.bp = bp;
this.timeLimit = timeLimit;
}
public override string ToString() => $"{resources[resource.ore]}r {clayCount}c {obsidianCount}o {geodeCount}g @{timePassed}m with bots {robots[resource.ore]}r {clayRobotCount}c {obsidianRobotCount}o {geodeRobotCount}g";
private int? cachedUpperBound;
public readonly int timeLimit;
public int GetFinalValueUpperBound()
{
cachedUpperBound ??= GetFinalGeodesUpperBound(this);
return cachedUpperBound.Value;
}
private miningSim Clone()
{
var tmp = (miningSim) MemberwiseClone();
tmp.cachedUpperBound = null;
tmp.robots = new Dictionary<resource, int>(tmp.robots);
tmp.resources = new Dictionary<resource, int>(tmp.resources);
tmp.shouldWait = false;
return tmp;
}
public miningSim advance()
{
var copy = Clone();
copy.internalAdvance();
return copy;
}
private void internalAdvance()
{
shouldWait = false;
timePassed++;
foreach (var r in robots)
{
resources[r.Key] += r.Value;
}
}
public miningSim buildRobot(resource type)
{
var copy = Clone();
copy.internalBuildRobot(type);
return copy;
}
private static readonly cost freeCost = new() {type = resource.ore, amount = 0};
private (cost cost1, cost cost2) getCosts(resource r)
{
var robotDef = bp.robots[r];
var cost1 = robotDef.First();
var cost2 = (robotDef.Count() > 1 ? robotDef.Last() : freeCost);
return (cost1, cost2);
}
private void internalBuildRobot(resource r)
{
var (cost1, cost2) = getCosts(r);
resources[cost1.type] -= cost1.amount;
if (resources[cost1.type] < 0)
{
throw new Exception($"sim {cost1.type} amount too low");
}
resources[cost2.type] -= cost2.amount;
if (resources[cost2.type] < 0)
{
throw new Exception($"sim {cost2.type} amount too low");
}
internalAdvance();
robots[r]++;
}
private enum buildStatus
{
cantBuild,
canBuild,
buildableEventually,
}
buildStatus getBuildStatus(resource r)
{
var (cost1, cost2) = getCosts(r);
if (resources[cost1.type] >= cost1.amount && resources[cost2.type] >= cost2.amount)
{
return buildStatus.canBuild;
}
if (robots[cost1.type] > 0 && robots[cost2.type] > 0)
{
return buildStatus.buildableEventually;
}
return buildStatus.cantBuild;
}
private IEnumerable<KeyValuePair<resource, List<cost>>> getBotsRequiring(resource res)
{
return bp.robots.Where(bot => bot.Value.Any(r => r.type == res));
}
public IEnumerable<resource> GetBuildableRobots()
{
foreach (var robot in bp.robots)
{
var status = getBuildStatus(robot.Key);
if (status == buildStatus.canBuild)
{
yield return robot.Key;
}
else if (status == buildStatus.buildableEventually)
{
shouldWait = true;
}
}
}
private readonly blueprint bp;
public int timePassed { get; private set; }
public int geodeCount => resources[resource.geode];
public int geodeRobotCount => robots[resource.geode];
public int obsidianCount => resources[resource.obsidian];
public int obsidianRobotCount => robots[resource.obsidian];
public int geodeRobotObsidianCost => bp.robots[resource.geode][1].amount;
public int clayCount => resources[resource.clay];
public int clayRobotCount => robots[resource.clay];
public int obsidianRobotClayCost => bp.robots[resource.obsidian][1].amount;
public double geodesPerMinute => 1.0 * geodeCount / timePassed;
public bool shouldWait { get; private set; }
private Dictionary<resource, int> robots = new()
{
{resource.ore, 1},
{resource.clay, 0},
{resource.obsidian, 0},
{resource.geode, 0},
};
private Dictionary<resource, int> resources = new()
{
{resource.ore, 0},
{resource.clay, 0},
{resource.obsidian, 0},
{resource.geode, 0},
};
}
private readonly List<blueprint> blueprints = new();
[GeneratedRegex(
"Blueprint (?<num>\\d+): Each (?<robottype1>.+?) robot costs (?<count1>\\d+) (?<costtype1>.+?)\\. Each (?<robottype2>.+?) robot costs (?<count2>\\d+) (?<costtype2>.+?)\\. Each (?<robottype3>.+?) robot costs (?<count3_1>\\d+) (?<costtype3_1>.+?) and (?<count3_2>\\d+) (?<costtype3_2>.+?)\\. Each (?<robottype4>.+?) robot costs (?<count4_1>\\d+) (?<costtype4_1>.+?) and (?<count4_2>\\d+) (?<costtype4_2>.+?)\\.")]
private static partial Regex BlueprintRegex();
internal override void Parse()
{
Regex r = BlueprintRegex();
foreach (var line in Util.Parsing.ReadAllLines("19"))
{
var match = r.Match(line);
cost orecost = new()
{
type = Enum.Parse<resource>(match.Groups["costtype1"].Value),
amount = int.Parse(match.Groups["count1"].Value),
};
cost claycost = new()
{
type = Enum.Parse<resource>(match.Groups["costtype2"].Value),
amount = int.Parse(match.Groups["count2"].Value),
};
cost obsidiancost1 = new()
{
type = Enum.Parse<resource>(match.Groups["costtype3_1"].Value),
amount = int.Parse(match.Groups["count3_1"].Value),
};
cost obsidiancost2 = new()
{
type = Enum.Parse<resource>(match.Groups["costtype3_2"].Value),
amount = int.Parse(match.Groups["count3_2"].Value),
};
cost geodecost1 = new()
{
type = Enum.Parse<resource>(match.Groups["costtype4_1"].Value),
amount = int.Parse(match.Groups["count4_1"].Value),
};
cost geodecost2 = new()
{
type = Enum.Parse<resource>(match.Groups["costtype4_2"].Value),
amount = int.Parse(match.Groups["count4_2"].Value),
};
blueprint bp = new()
{
id = blueprints.Count + 1,
robots = new Dictionary<resource, List<cost>>
{
{resource.ore, new List<cost> {orecost}},
{resource.clay, new List<cost> {claycost}},
{resource.obsidian, new List<cost> {obsidiancost1, obsidiancost2}},
{resource.geode, new List<cost> {geodecost1, geodecost2}},
},
};
blueprints.Add(bp);
}
}
private static int GetFinalGeodesUpperBound(miningSim sim)
{
int geodeRobotCount = sim.geodeRobotCount;
int obsidianRobotCount = sim.obsidianRobotCount;
int clayRobotCount = sim.clayRobotCount;
int obsidianCount = sim.obsidianCount;
int obsidianCost = sim.geodeRobotObsidianCost;
int clayCount = sim.clayCount;
int clayCost = sim.obsidianRobotClayCost;
int geodeCount = sim.geodeCount;
for (int i = sim.timePassed; i < sim.timeLimit; i++)
{
var newClayRobotCount = clayRobotCount;
var newObsidianRobotCount = obsidianRobotCount;
var newGeodeRobotCount = geodeRobotCount;
if (obsidianCount >= obsidianCost)
{
obsidianCount -= obsidianCost;
newGeodeRobotCount++;
}
if (clayCount >= clayCost)
{
clayCount -= clayCost;
newObsidianRobotCount++;
}
newClayRobotCount++;
clayCount += clayRobotCount;
obsidianCount += obsidianRobotCount;
geodeCount += geodeRobotCount;
geodeRobotCount = newGeodeRobotCount;
obsidianRobotCount = newObsidianRobotCount;
clayRobotCount = newClayRobotCount;
}
return geodeCount;
}
private int FindMaxGeodes(miningSim sim)
{
var queue = new PriorityQueue<miningSim,
(double rate, int timePassed, int estimatedFutureValue)>();
queue.Enqueue(sim,
(0.0, 0, 0)
);
int bestGeodes = 0;
while (queue.Count > 0)
{
var state = queue.Dequeue();
if (state.timePassed > state.timeLimit)
{
continue;
}
if (state.geodeCount > bestGeodes)
{
bestGeodes = state.geodeCount;
}
if (state.timePassed == state.timeLimit)
{
continue;
}
var finalGeodesUpperBound = state.GetFinalValueUpperBound();
if (finalGeodesUpperBound <= bestGeodes)
{
continue;
}
foreach (var toBuild in state.GetBuildableRobots())
{
var nextState = state.buildRobot(toBuild);
queue.Enqueue(nextState,
(-nextState.geodesPerMinute, -nextState.timePassed, -nextState.GetFinalValueUpperBound())
);
}
if (state.shouldWait)
{
var nextState = state.advance();
queue.Enqueue(nextState,
(-nextState.geodesPerMinute, -nextState.timePassed, -nextState.GetFinalValueUpperBound())
);
}
}
return bestGeodes;
}
internal override string Part1()
{
var lst = blueprints.Select(sim => (sim.id, maxGeodes: FindMaxGeodes(new miningSim(sim))));
var qualitySum = lst.Select(x => x.id * x.maxGeodes).Sum();
return $"Quality level of all blueprints for 24 minutes: <+white>{qualitySum}";
}
internal override string Part2()
{
var g1 = FindMaxGeodes(new miningSim(blueprints[0], 32));
var g2 = FindMaxGeodes(new miningSim(blueprints[1], 32));
var g3 = FindMaxGeodes(new miningSim(blueprints[2], 32));
return $"Sum of geodes opened by first 3 blueprints after 32 minutes: <+white>{g1*g2*g3}";
}
}