Day 19 solution

Cribbed heavily from https://www.reddit.com/r/adventofcode/comments/rjpf7f/comment/hp5k554/?utm_source=share&utm_medium=web2x&context=3 because this problem breaks my brain in so many ways. I understand the approach, but I got twisted up in my own head trying to write down the solution, so instead I started from a working copy and optimized it (a little bit) to make sure I understood what it was doing.
This commit is contained in:
2021-12-20 15:37:41 -06:00
parent e818c949ef
commit 60d61584c8
4 changed files with 1036 additions and 0 deletions

View File

@ -72,6 +72,9 @@
<None Update="inputs\18.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="inputs\19.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="inputs\20.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

856
inputs/19.txt Normal file
View File

@ -0,0 +1,856 @@
--- scanner 0 ---
536,703,543
-132,-41,-64
-429,350,-809
-477,567,455
-369,-732,-732
-806,-680,810
502,729,469
-417,400,-831
497,-739,-564
-545,-726,-743
271,357,-605
13,-26,94
508,-654,-647
-581,-685,774
396,-908,355
-481,568,418
-634,-665,910
306,410,-668
540,739,539
465,-656,-423
-474,-628,-795
-463,568,426
254,306,-662
358,-788,353
-396,313,-691
251,-873,452
--- scanner 1 ---
405,377,-919
-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

176
src/19.cs Normal file
View File

@ -0,0 +1,176 @@
namespace aoc2021;
internal class Day19 : Day
{
internal override void Go()
{
var lines = Util.ReadAllLines("inputs/19.txt");
var scanners = new List<HashSet<Vector3>>();
foreach (var line in lines)
{
if (line.StartsWith("--"))
{
scanners.Add(new());
}
else if (string.IsNullOrEmpty(line))
{
continue;
}
else
{
var points = line.Split(',');
scanners[^1].Add((Convert.ToInt32(points[0]), Convert.ToInt32(points[1]), Convert.ToInt32(points[2])));
}
}
var result = Part1(scanners);
Part2(result);
}
record struct Vector3(int X, int Y, int Z)
{
public static implicit operator Vector3((int x, int y, int z) value) => new(value.x, value.y, value.z);
public static Vector3 operator+(Vector3 p, Vector3 v) => (p.X + v.X, p.Y + v.Y, p.Z + v.Z);
public static Vector3 operator-(Vector3 p1, Vector3 p2) => (p1.X - p2.X, p1.Y - p2.Y, p1.Z - p2.Z);
public int DistanceTo(Vector3 other) => (int)(Math.Pow(other.X - X, 2) + Math.Pow(other.Y - Y, 2) + Math.Pow(other.Z - Z, 2));
public int ManhattanDistanceTo(Vector3 other)
{
var (dx, dy, dz) = this - other;
return Math.Abs(dx) + Math.Abs(dy) + Math.Abs(dz);
}
public Vector3 Transform(Vector3 up, int rotation)
{
Vector3 reoriented = up switch
{
(0, +1, 0) => (X, Y, Z),
(0, -1, 0) => (X, -Y, -Z),
(+1, 0, 0) => (Y, X, -Z),
(-1, 0, 0) => (Y, -X, Z),
(0, 0, +1) => (Y, Z, X),
(0, 0, -1) => (Y, -Z, -X),
_ => throw new Exception("Invalid up vector")
};
return rotation switch
{
0 => reoriented,
1 => (reoriented.Z, reoriented.Y, -reoriented.X),
2 => (-reoriented.X, reoriented.Y, -reoriented.Z),
3 => (-reoriented.Z, reoriented.Y, reoriented.X),
_ => throw new Exception("Invalid rotation")
};
}
}
private static readonly (int, int, int)[] Axes = new[]
{
( 0, +1, 0),
( 0, -1, 0),
(+1, 0, 0),
(-1, 0, 0),
( 0, 0, +1),
( 0, 0, -1)
};
private static (IEnumerable<Vector3> alignedBeacons, Vector3 translation, Vector3 up, int rotation)? Align(ICollection<Vector3> beacons1, ICollection<Vector3> beacons2)
{
// Fix beacons1, rotate beacons2
for (int axis = 0; axis < Axes.Length; axis++)
{
for (int rotation = 0; rotation < 4; rotation++)
{
var rotatedBeacons2 = new HashSet<Vector3>(beacons2.Select(b => b.Transform(Axes[axis], rotation)));
foreach (var b1 in beacons1)
{
// Assume b1 matches some b2
foreach (var matchingB1InB2 in rotatedBeacons2)
{
// Move all b2 so matchingB1InB2 matches b1, in scanner 1 coordinates
var delta = b1 - matchingB1InB2;
var transformedBeacons2 = rotatedBeacons2.Select(b => b + delta);
// How many overlaps did we get?
var intersection = new HashSet<Vector3>(transformedBeacons2);
intersection.IntersectWith(beacons1);
if (intersection.Count >= 12)
{
// Found the right orientation
return (transformedBeacons2, delta, Axes[axis], rotation);
}
}
}
}
}
return null;
}
private static (IEnumerable<HashSet<Vector3>> scans, IEnumerable<HashSet<Vector3>> scanners) Reduce(IEnumerable<HashSet<Vector3>> scans, IEnumerable<HashSet<Vector3>> scanners)
{
var toRemove = new HashSet<int>();
for (int i = 0; i < scans.Count() - 1; i++)
{
for (int j = i + 1; j < scans.Count(); j++)
{
if (toRemove.Contains(j))
{
// Already merged
continue;
}
var alignment = Align(scans.ElementAt(i), scans.ElementAt(j));
if (alignment != null)
{
// Convert all scanners from j coordinates to i coordinates
foreach (var s in scanners.ElementAt(j))
{
var scanner = alignment.Value.translation + s.Transform(alignment.Value.up, alignment.Value.rotation);
scanners.ElementAt(i).Add(scanner);
}
// Merge the scan sets
scans.ElementAt(i).UnionWith(alignment.Value.alignedBeacons);
toRemove.Add(j);
}
}
}
// Skip all scans and scanners that were merged
return (scans.Where((_, i) => !toRemove.Contains(i)), scanners.Where((_, i) => !toRemove.Contains(i)));
}
private static ICollection<Vector3> Part1(List<HashSet<Vector3>> input)
{
using var t = new Timer();
IEnumerable<HashSet<Vector3>> scans = input;
IEnumerable<HashSet<Vector3>> scanners = input.Select((_) => new HashSet<Vector3> { (0, 0, 0) }).ToList();
while (scans.Count() > 1)
{
// Note that this will loop forever if there is no alignment
(scans, scanners) = Reduce(scans, scanners);
}
var allBeacons = scans.ElementAt(0);
t.Stop();
Logger.Log($"<+black>> part1: <+white>{allBeacons.Count}<r>");
return scanners.ElementAt(0);
}
private static void Part2(ICollection<Vector3> scanners)
{
using var t = new Timer();
var scannerList = scanners.ToList();
var farthest =
Enumerable.Range(0, scannerList.Count - 1)
.SelectMany(i => Enumerable.Range(i + 1, scannerList.Count - i - 1).Select(j => (i, j)))
.Max(pair => scannerList[pair.i].ManhattanDistanceTo(scannerList[pair.j]));
t.Stop();
Logger.Log($"<+black>> part2: <+white>{farthest}<r>");
}
}

View File

@ -37,6 +37,7 @@ else
"16" => new Day16(),
"17"=> new Day17(),
"18" => new Day18(),
"19" => new Day19(),
_ => new Day20(),
};
day.Go();