Suuper slow day 19 in Rust

This commit is contained in:
Smaug123
2021-12-19 14:07:08 +00:00
parent 274394f931
commit a5d94e1c79
8 changed files with 1464 additions and 0 deletions

7
Cargo.lock generated
View File

@@ -234,6 +234,13 @@ dependencies = [
"criterion",
]
[[package]]
name = "day_19"
version = "0.1.0"
dependencies = [
"criterion",
]
[[package]]
name = "day_2"
version = "0.1.0"

View File

@@ -17,4 +17,5 @@ members = [
"day_16",
"day_17",
"day_18",
"day_19",
]

15
day_19/Cargo.toml Normal file
View File

@@ -0,0 +1,15 @@
[package]
name = "day_19"
version = "0.1.0"
authors = ["Smaug123 <patrick+github@patrickstevens.co.uk>"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[dev-dependencies]
criterion = "0.3"
[[bench]]
name = "bench"
harness = false

19
day_19/benches/bench.rs Normal file
View File

@@ -0,0 +1,19 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use day_19::day_19::{input, part_1, part_2};
fn criterion_benchmark(c: &mut Criterion) {
let input = input();
c.bench_function("day 19 part 1", |b| {
b.iter(|| {
black_box(part_1(&input));
})
});
c.bench_function("day 19 part 2", |b| {
b.iter(|| {
black_box(part_2(&input));
})
});
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);

34
day_19/day19.m Normal file
View File

@@ -0,0 +1,34 @@
(* ::Package:: *)
nums=With[{chars=Characters@StringTrim@ReadString[StringJoin[NotebookDirectory[], "/input.txt"]]},Flatten[IntegerDigits[FromDigits[#,16],2,4]&/@chars]];
consumePacket[{}]={};
consumePacket[{v1_,v2_,v3_,t1_,t2_,t3_,otherBits___}]:=With[{packetVersion=Sow@FromDigits[{v1,v2,v3},2],typeId=FromDigits[{t1,t2,t3},2], rest={otherBits}},
Switch[typeId,
4,With[{thisPacket=TakeWhile[Partition[rest,UpTo@5],#[[1]]==1&]},
{FromDigits[Flatten[Join[Rest/@thisPacket,rest[[5 Length@thisPacket+2;;5 Length@thisPacket+5]]]],2],rest[[5 Length@thisPacket+6;;]]}
],
_,
With[{operator=
Switch[typeId,0,Plus,1,Times,2,Min,3,Max,5,Boole@*Greater,6,Boole@*Less,7,Boole@*Equal]
},
Switch[rest[[1]],
0,With[{subPacketLen=FromDigits[rest[[2;;16]],2]},
{operator@@consumePackets[rest[[17;;16+subPacketLen]]],rest[[17+subPacketLen;;]]}
],
1,With[{subPackets=FromDigits[rest[[2;;12]],2]},
With[{result=Nest[With[{c=consumePacket[#[[2]]]},{Join[#[[1]],{c[[1]]}],c[[2]]}]&,{{},rest[[13;;]]},subPackets]},
{operator@@result[[1]],result[[2]]}
]
]
]
]
]]
consumePackets[l_]:=First@NestWhile[With[{c=consumePacket[#[[2]]]},{Join[#[[1]],{c[[1]]}],c[[2]]}]&,{{},l},Not@AllTrue[#[[2]],#==0&]&]
MapAt[Total@*Flatten,Reap@consumePackets[nums],{2}]

868
day_19/input.txt Normal file
View File

@@ -0,0 +1,868 @@
--- scanner 0 ---
-383,494,-722
416,680,-782
702,-466,-370
-497,489,-749
393,371,887
346,-812,668
-331,-537,-634
449,549,858
-694,757,676
437,492,926
-449,-615,-701
32,70,131
-588,-759,491
-386,-503,-743
652,-482,-490
390,-826,736
430,721,-642
285,-788,616
-468,470,-620
-613,-685,381
-660,-625,438
-630,787,857
-557,827,723
863,-442,-469
-28,-51,-26
408,557,-671
--- scanner 1 ---
677,636,670
656,-350,616
-728,663,-297
-32,3,107
841,-531,-758
-580,681,526
459,754,-538
-553,719,488
-782,-365,-466
-606,-593,510
-649,-711,555
670,-414,-760
600,620,815
-729,-408,-463
557,763,718
-706,534,-323
-599,589,-299
352,693,-536
-528,-692,530
742,-264,668
383,795,-651
-558,700,724
-733,-555,-430
729,-403,-704
629,-304,760
--- scanner 2 ---
845,-525,424
-297,-724,-404
705,475,441
-528,746,327
-492,-491,586
947,-315,-543
-461,981,-665
791,897,-789
3,172,-165
874,-473,313
620,428,554
832,-294,-425
975,-455,373
-441,924,-720
-324,782,279
702,845,-727
-359,747,386
-520,983,-860
725,-283,-536
-352,-703,-475
-225,-758,-558
-520,-616,579
147,56,-44
741,756,-805
-495,-606,635
596,442,457
--- scanner 3 ---
622,-463,380
-743,811,559
-553,-625,-725
-712,-775,791
-606,741,606
308,825,-732
559,396,526
-116,97,136
391,880,-859
693,-861,-564
724,-486,471
804,-521,414
237,846,-787
553,-802,-643
-3,62,-58
498,-859,-623
-746,738,-564
-802,728,-589
-640,-641,844
-753,613,-592
-670,771,425
583,406,434
486,438,391
-446,-660,-760
-687,-701,901
-494,-624,-556
--- scanner 4 ---
567,-413,291
37,98,16
-800,-787,481
526,657,578
477,542,575
-470,737,-438
-431,-442,-685
785,-491,-858
-684,-728,597
673,529,-620
815,-484,-858
-639,695,814
-451,-451,-797
533,532,550
-432,-316,-808
-458,794,-370
-831,-821,647
-79,12,-95
732,-440,275
-414,915,-409
616,-441,274
-638,738,727
781,-444,-808
536,459,-573
609,499,-439
-561,620,712
--- scanner 5 ---
-140,-57,-54
425,-555,-443
310,409,-652
-517,-532,-583
572,-681,406
396,402,737
-609,570,-783
-529,449,793
-473,499,737
-811,550,-772
-801,-733,410
591,-703,604
567,408,750
-474,-479,-586
351,534,-724
-702,-655,390
610,-708,368
480,-662,-419
406,436,710
363,489,-606
-729,494,-777
-388,408,788
-664,-528,-550
554,-533,-417
-820,-612,435
--- scanner 6 ---
-616,792,-391
782,634,-497
502,520,554
-321,668,572
-562,-519,481
694,-617,472
464,493,516
-32,76,-91
-609,792,-421
-347,646,701
-660,-341,-474
726,731,-470
646,-737,599
558,-608,-547
615,-553,-532
-656,742,-425
-560,-412,542
28,-105,80
502,-626,-642
791,-660,615
791,611,-361
-659,-340,-590
700,498,535
-323,539,646
-687,-357,-639
-675,-443,440
161,-73,-77
--- scanner 7 ---
-109,-33,-138
-446,-451,-456
620,685,-876
598,908,-874
519,424,832
-433,-622,-462
-777,-627,627
-395,333,-462
670,-664,-450
-446,418,-553
-390,474,-503
376,380,825
-30,102,33
431,512,825
-815,-665,654
-473,-461,-490
-579,-646,649
-748,765,558
526,-619,-524
601,-645,-659
500,-484,650
626,863,-810
82,-87,20
-793,647,601
-773,746,679
459,-435,585
462,-323,552
--- scanner 8 ---
618,-575,-405
-381,637,514
491,606,-350
562,358,799
-451,500,561
616,-514,-512
519,557,-333
-421,564,380
569,388,799
-454,640,-609
-312,-497,-904
-786,-689,389
-367,-414,-777
522,392,749
-754,-592,346
518,441,-334
503,-473,-436
855,-679,546
-796,-665,481
857,-605,675
-346,-343,-832
831,-734,653
-41,-90,6
-579,647,-637
109,51,-42
-464,696,-634
--- scanner 9 ---
-314,556,-748
-267,471,-635
686,696,-765
-645,-822,801
7,-157,-17
616,826,-816
614,-405,562
571,-492,561
689,-507,484
891,372,738
-317,645,635
-585,-677,-862
-621,-473,-910
634,725,-876
767,-644,-554
861,513,736
652,-641,-603
777,-669,-610
-312,560,656
943,354,759
145,-57,-102
-446,592,673
-281,447,-732
-524,-869,808
-586,-508,-803
-600,-860,658
--- scanner 10 ---
-988,-745,421
-980,-744,-811
-665,492,-838
-542,366,-837
492,695,687
530,683,606
-954,-791,561
588,-515,-818
586,-670,669
-553,501,-818
-912,-687,-799
-116,-67,-160
350,448,-681
538,647,514
-905,-659,547
728,-556,-832
-78,92,-55
454,466,-522
617,-679,-840
-595,824,551
-941,-865,-855
555,497,-680
-585,760,507
630,-709,574
-599,694,575
447,-716,575
--- scanner 11 ---
-711,-575,-794
-156,149,-57
-743,741,442
-458,462,-501
-868,-585,847
729,801,780
-604,-630,-770
360,-745,-561
-508,496,-461
-458,492,-508
-776,-561,857
-696,604,512
435,687,-637
440,-692,-607
485,-704,-489
702,915,775
401,652,-520
714,-335,660
600,830,799
793,-255,639
-911,-488,815
-582,-501,-796
332,649,-669
739,-314,471
34,49,76
-877,668,482
--- scanner 12 ---
-838,565,701
-546,-597,465
-740,412,-705
-108,-126,-79
560,-903,832
-727,442,709
-629,-889,-525
488,-523,-674
-696,451,-800
-525,-557,254
-397,-903,-512
-585,-928,-532
-557,405,-706
870,377,680
844,330,-692
448,-573,-796
878,376,-552
38,11,-147
795,462,-678
612,-927,771
802,434,668
-426,-581,415
831,256,724
405,-519,-855
680,-941,727
-698,606,687
--- scanner 13 ---
587,-791,-805
-809,359,-688
804,480,332
663,835,-671
790,548,288
-139,-63,-131
-570,-807,559
22,15,-23
646,-477,799
622,-826,-912
-688,-792,482
-776,-630,-612
-766,-655,-556
766,600,227
601,-439,656
-849,493,-615
-393,329,335
-613,-894,560
-571,358,391
-779,540,-752
-514,290,379
737,725,-646
525,-430,806
586,-622,-864
-651,-658,-605
603,778,-718
--- scanner 14 ---
777,-631,-530
404,638,-524
-355,-863,668
-342,372,-583
-324,-897,502
-516,619,335
418,679,-439
-594,544,437
-340,342,-442
495,-488,720
654,571,716
-562,-473,-754
404,670,-474
535,-507,799
-319,290,-424
-471,-804,552
935,-755,-518
-651,-409,-634
734,633,703
812,-740,-434
507,-601,636
745,545,618
-517,662,422
-599,-478,-698
58,-27,-84
--- scanner 15 ---
-419,-744,-730
315,366,792
401,-845,-723
336,391,603
331,-885,845
582,345,-350
-525,-726,-681
-966,491,-543
-468,-630,898
-556,-680,911
618,491,-413
646,489,-360
-533,-660,-814
-431,-739,840
-911,382,-509
256,312,624
336,-902,616
-848,424,-621
-102,17,130
-829,505,464
472,-754,-723
354,-914,713
-166,-96,-55
-914,403,488
574,-860,-793
-800,376,483
--- scanner 16 ---
492,867,644
-590,684,-533
594,898,529
617,-476,-857
541,-359,-848
-422,969,629
596,-320,-953
-538,970,628
107,80,-148
-809,-707,-763
-415,-598,524
-578,-746,-743
818,-651,584
-441,-733,513
-480,757,-646
655,-683,527
-587,953,656
-600,-626,-766
-45,118,-24
-508,-693,464
524,693,-725
746,-605,412
651,573,-677
-495,702,-589
533,791,531
667,650,-822
--- scanner 17 ---
-622,-716,-525
640,427,420
9,33,65
-729,-671,-517
886,473,-533
604,573,483
-321,880,679
891,-803,-775
-568,-638,-457
868,-832,-643
-395,858,651
-385,906,587
-544,895,-607
-492,892,-694
-476,919,-493
576,571,430
179,-49,119
103,144,-33
821,-763,793
-491,-309,453
907,448,-722
-453,-372,499
-511,-339,461
886,-820,-546
966,394,-554
648,-778,863
750,-672,793
--- scanner 18 ---
865,-600,535
376,624,313
-691,-811,-859
-638,-448,652
493,-761,-450
366,-678,-395
834,-702,420
-503,513,-828
758,-661,533
-716,-539,537
688,630,-470
-596,795,771
547,507,311
488,496,367
92,90,-142
658,517,-488
-29,-25,-50
-542,499,-626
831,572,-510
-569,405,-789
-579,856,677
-806,-693,-838
-584,-700,-870
438,-832,-429
-684,-376,480
-549,693,709
--- scanner 19 ---
675,-900,-912
576,258,461
-899,-562,-885
455,437,-847
402,308,-809
-944,-505,641
-926,-448,649
-682,-563,-880
-857,-416,731
693,-952,-933
-162,-132,-84
-677,486,-526
534,-870,-910
487,303,-830
351,-695,591
221,-625,642
600,272,558
-675,381,-672
-606,303,477
-772,-583,-734
491,305,574
-29,-7,-148
-803,353,513
-817,299,557
-729,412,-553
322,-643,702
--- scanner 20 ---
-613,561,508
-100,88,2
340,478,-606
-853,596,-397
539,926,512
-804,618,-339
778,-305,-582
374,-449,416
-598,-568,835
642,809,433
-740,-602,772
-735,-611,732
-817,-723,-368
328,-416,462
7,-51,101
-843,743,-319
-497,516,601
613,726,532
698,-450,-647
260,619,-552
359,-510,505
-851,-705,-456
329,556,-657
-568,618,535
743,-393,-475
-826,-788,-374
--- scanner 21 ---
375,419,-292
674,-791,526
391,714,549
-817,441,446
-787,582,448
386,629,528
-869,423,425
598,-800,376
-615,-438,700
536,491,-321
-489,473,-298
-526,-704,-628
-540,-336,622
-33,90,152
819,-619,-675
863,-590,-709
-480,438,-312
520,661,511
-588,-717,-548
-521,523,-298
860,-747,-757
-497,-423,623
-614,-619,-639
719,-753,383
84,-46,-4
394,426,-413
--- scanner 22 ---
-642,-484,-438
-402,772,487
-436,614,-512
601,-445,511
783,-655,-548
715,606,791
862,-639,-392
-362,569,-656
673,798,-445
-767,-340,-444
640,910,-448
504,-418,567
-374,611,447
742,568,829
737,587,593
-376,-647,582
-368,782,460
624,-309,502
-338,-708,581
-571,588,-587
-33,-8,-3
-548,-398,-462
134,-52,125
839,-612,-550
109,106,-60
-337,-640,744
738,749,-486
--- scanner 23 ---
635,-783,-873
675,453,-812
-765,-843,-692
686,-730,260
339,802,466
398,686,582
-700,-734,-812
-532,-657,527
-647,599,374
685,-614,259
-587,661,-647
642,-813,-873
-756,-707,-715
-567,556,-786
-694,550,423
-476,-562,545
810,434,-823
-14,-82,-128
-666,557,-677
682,-779,-823
305,833,632
713,-565,276
-790,463,379
-589,-672,472
684,433,-700
--- scanner 24 ---
-392,386,774
801,578,-529
795,458,-453
-775,658,-408
-695,-515,475
481,-728,-398
-372,485,696
601,670,573
44,12,93
496,-789,-309
-613,-627,-625
450,-822,-355
900,-933,689
865,-845,582
568,523,569
-729,-533,563
-618,-636,-665
-704,-450,481
604,713,520
820,-788,754
790,376,-509
-476,-670,-728
-719,714,-458
-770,799,-367
-417,367,653
--- scanner 25 ---
-422,723,-670
-270,-861,454
908,-516,-528
789,426,539
-231,-790,395
-569,724,716
723,355,437
862,-470,-495
552,598,-681
-516,-733,-761
-630,-734,-906
-402,646,-597
-590,-802,-814
-464,682,738
792,-755,647
-578,621,690
126,-69,31
-22,-130,-131
891,-784,730
-335,619,-755
816,471,482
-261,-763,486
592,593,-690
489,456,-647
812,-681,847
819,-501,-589
--- scanner 26 ---
808,541,-518
-571,511,-513
861,587,-438
617,352,504
580,-669,674
-533,479,-410
-654,-680,-439
765,-775,-465
-316,-760,561
109,-91,-38
-380,687,430
604,-815,-437
-452,-751,538
-346,647,380
-715,-681,-401
-647,-518,-400
-56,3,-86
775,-802,-431
-425,-695,441
62,63,74
746,378,526
599,-471,652
561,-433,679
820,659,-563
-536,628,-479
691,354,633
-376,640,380
--- scanner 27 ---
431,368,347
508,-632,432
-18,-140,-167
439,615,379
913,-774,-641
-466,-506,-752
-709,486,769
877,788,-560
-267,703,-717
932,724,-481
-280,709,-511
-391,-754,822
-662,407,691
-540,455,807
-369,777,-653
-427,-601,-796
840,844,-476
504,-451,349
874,-781,-685
-420,-600,-613
558,-510,392
-345,-614,788
888,-794,-453
-477,-628,739
38,-45,21
424,444,395
--- scanner 28 ---
-112,40,77
513,-741,-476
64,-38,169
-738,576,870
366,442,769
-560,-628,610
-863,821,-269
75,100,2
-615,-685,625
-796,375,863
555,495,-668
-667,-452,-537
491,-543,-457
-877,799,-375
-633,-741,720
-758,480,737
-744,-597,-521
724,-517,548
389,600,742
588,498,-780
604,-452,439
490,536,-619
445,598,785
486,-779,-438
-624,-549,-394
627,-461,575
-778,827,-282
--- scanner 29 ---
722,-392,-617
-814,-432,-624
837,504,801
-760,437,-585
810,509,915
-803,469,-488
708,485,830
-668,427,-561
722,-522,967
-769,802,668
-723,-455,-726
868,-329,-581
901,645,-255
-403,-744,710
847,813,-314
-293,-670,685
831,-488,912
-635,842,741
-588,772,604
-780,-490,-806
96,8,173
724,-339,-645
789,-600,849
15,128,70
822,624,-335
-350,-610,638
--- scanner 30 ---
813,401,806
740,-455,648
-654,-721,505
-751,433,-565
-153,37,-24
733,-608,-632
-858,494,-567
-827,392,-452
-629,-777,515
-930,-638,-468
691,718,-512
-66,-64,95
638,-515,-572
698,283,827
-486,333,418
-359,416,363
-913,-687,-440
-626,-728,630
773,-541,-583
-929,-522,-467
645,646,-684
591,394,838
-431,262,397
841,-515,666
711,-566,596
723,555,-569

513
day_19/src/lib.rs Normal file
View File

@@ -0,0 +1,513 @@
pub mod day_19 {
use std::cmp::max;
use std::collections::HashSet;
use std::fmt::{Debug, Display};
#[derive(Clone, Hash, PartialEq, Eq)]
pub struct Coord {
x: i32,
y: i32,
z: i32,
}
impl Coord {
pub(crate) fn make(x: i32, y: i32, z: i32) -> Coord {
Coord { x, y, z }
}
}
impl Display for Coord {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "({}, {}, {})", self.x, self.y, self.z)
}
}
impl Debug for Coord {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "({}, {}, {})", self.x, self.y, self.z)
}
}
#[derive(Clone)]
pub struct Scanner {
pub(crate) coords: Vec<Coord>,
pub(crate) index: u8,
}
fn parse_vector(s: &str) -> Option<Coord> {
if s.len() == 0 {
return None;
}
let mut coords = s.split(',').map(|s| str::parse::<i32>(s).unwrap());
let x = coords.next().unwrap();
let y = coords.next().unwrap();
let z = coords.next().unwrap();
match coords.next() {
None => {}
Some(c) => {
panic!("Expected last coord, got {:?}", c);
}
}
Some(Coord { x, y, z })
}
pub(crate) fn parse(s: &str) -> Vec<Scanner> {
let mut answer = Vec::new();
// skip the first, empty, element
for scanner in s.split("--- scanner ").skip(1) {
let mut v = Vec::new();
let mut lines = scanner.split('\n');
let first_line = lines.next().unwrap();
for line in lines {
match parse_vector(line) {
None => {}
Some(vec) => {
v.push(vec);
}
}
}
let index = str::parse::<u8>(first_line.split(' ').next().unwrap()).unwrap();
answer.push(Scanner { coords: v, index });
}
answer
}
#[derive(PartialEq, Eq, Debug)]
enum Axis {
X,
Y,
Z,
}
pub(crate) struct ScannerOrientationIter<'a> {
original: &'a Scanner,
yield_next: Scanner,
rotation_count: u8,
up_axis: Axis,
sense: bool,
ended: bool,
}
impl<'a> std::fmt::Debug for ScannerOrientationIter<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Original {}, rotated {}, up is {:?}, sense {}",
self.original.index, self.rotation_count, self.up_axis, self.sense
)
}
}
fn rotate(scanner: &mut Scanner, around: &Axis) {
match around {
Axis::X => {
// X-axis stays the same; swap y/z and negate first
for row in scanner.coords.iter_mut() {
std::mem::swap(&mut row.y, &mut row.z);
row.y *= -1;
}
}
Axis::Y => {
for row in scanner.coords.iter_mut() {
std::mem::swap(&mut row.z, &mut row.x);
row.z *= -1;
}
}
Axis::Z => {
for row in scanner.coords.iter_mut() {
std::mem::swap(&mut row.x, &mut row.y);
row.x *= -1;
}
}
}
}
fn flip(scanner: &mut Scanner, up_direction: &Axis) {
match up_direction {
Axis::X => {
for row in scanner.coords.iter_mut() {
row.x *= -1;
row.y *= -1;
}
}
Axis::Y => {
for row in scanner.coords.iter_mut() {
row.y *= -1;
row.z *= -1;
}
}
Axis::Z => {
for row in scanner.coords.iter_mut() {
row.z *= -1;
row.x *= -1;
}
}
}
}
fn new_axis(axis: &Axis) -> Axis {
match axis {
Axis::X => Axis::Y,
Axis::Y => Axis::Z,
Axis::Z => Axis::X,
}
}
fn move_to_axis(existing: &Scanner, output: &mut Scanner, axis: &Axis) {
// (1,2,3) with X up, to Y up, makes (2, -1, 3)
match axis {
Axis::Y => {
for (index, value) in existing.coords.iter().enumerate() {
output.coords[index] = Coord {
x: value.y,
y: value.z,
z: value.x,
};
}
}
Axis::Z => {
for (index, value) in existing.coords.iter().enumerate() {
output.coords[index] = Coord {
x: value.z,
y: value.x,
z: value.y,
};
}
}
Axis::X => {
for (index, value) in existing.coords.iter().enumerate() {
output.coords[index] = value.clone();
}
}
}
}
impl<'a> Iterator for ScannerOrientationIter<'a> {
type Item = Scanner;
fn next(&mut self) -> Option<Self::Item> {
if self.ended {
return None;
}
let to_ret = self.yield_next.clone();
if self.rotation_count < 3 {
self.rotation_count += 1;
rotate(&mut self.yield_next, &Axis::X);
return Some(to_ret);
}
self.rotation_count = 0;
rotate(&mut self.yield_next, &Axis::X);
if !self.sense {
self.sense = true;
flip(&mut self.yield_next, &Axis::X);
return Some(to_ret);
}
self.sense = false;
self.up_axis = new_axis(&self.up_axis);
if self.up_axis == Axis::X {
self.ended = true;
}
move_to_axis(self.original, &mut self.yield_next, &self.up_axis);
Some(to_ret)
}
}
pub(crate) fn all_orientations<'a>(s: &'a Scanner) -> ScannerOrientationIter<'a> {
ScannerOrientationIter {
original: s,
rotation_count: 0,
up_axis: Axis::X,
sense: false,
yield_next: s.clone(),
ended: false,
}
}
pub fn input() -> Vec<Scanner> {
parse(include_str!("../input.txt"))
}
const fn subtract(c1: &Coord, c2: &Coord) -> Coord {
Coord {
x: c1.x - c2.x,
y: c1.y - c2.y,
z: c1.z - c2.z,
}
}
const fn add(c1: &Coord, c2: &Coord) -> Coord {
Coord {
x: c1.x + c2.x,
y: c1.y + c2.y,
z: c1.z + c2.z,
}
}
/// Return what we need to add to each of scanner_2 to get us translated to scanner_1.
pub(crate) fn align(scanner_1: &Scanner, scanner_2: &Scanner) -> Option<Coord> {
for point in scanner_1.coords.iter() {
for target_index in 0..scanner_2.coords.len() {
// Translate target to equal point
let translation = subtract(&point, &scanner_2.coords[target_index]);
let alignments = scanner_2
.coords
.iter()
.map(|p| add(p, &translation))
.filter(|p| scanner_1.coords.contains(p))
.take(12)
.collect::<Vec<_>>();
if alignments.len() == 12 {
return Some(translation);
}
}
}
None
}
pub(crate) fn stitch(scanners: &[Scanner]) -> Vec<(Coord, Scanner)> {
let mut placed: Vec<Option<(Coord, Scanner)>> =
std::iter::repeat(None).take(scanners.len()).collect();
placed[0] = Some((Coord { x: 0, y: 0, z: 0 }, scanners[0].clone()));
let mut placed_count = 1;
while placed_count < placed.len() {
for match_scanner_index in 0..scanners.len() {
match placed[match_scanner_index].clone() {
None => {
// We can't denote positions relative to this one, so skip it
}
Some((base_offset, base_rotation)) => {
for (i, scanner) in scanners.iter().enumerate() {
if placed[i].is_none() && match_scanner_index != i {
for rotation in all_orientations(&scanner) {
match align(&base_rotation, &rotation) {
None => {}
Some(alignment) => {
placed[i] =
Some((add(&alignment, &base_offset), rotation));
placed_count += 1;
break;
}
}
}
}
}
}
}
}
}
placed
.iter()
.map(|i| i.as_ref().unwrap())
.cloned()
.collect()
}
pub fn part_1(data: &[Scanner]) -> usize {
let placed = stitch(data);
placed
.iter()
.flat_map(|(offset, rotated)| {
rotated.coords.iter().map(move |probe| add(&offset, &probe))
})
.collect::<HashSet<_>>()
.len()
}
const fn abs(x: i32) -> u32 {
if x < 0 {
(-x) as u32
} else {
x as u32
}
}
const fn manhattan(c1: &Coord, c2: &Coord) -> u32 {
let subtracted = subtract(c1, c2);
abs(subtracted.x) + abs(subtracted.y) + abs(subtracted.z)
}
pub fn part_2(data: &[Scanner]) -> u32 {
let placed: Vec<Coord> = stitch(data)
.iter()
.map(|(location, _)| location)
.cloned()
.collect();
let mut m = 0;
for (i, c1) in placed.iter().enumerate() {
for j in i + 1..placed.len() {
m = max(manhattan(c1, &placed[j]), m);
}
}
m
}
}
#[cfg(test)]
mod tests {
use super::day_19::*;
static TEST_INPUT: &str = "--- scanner 0 ---
404,-588,-901
528,-643,409
-838,591,734
390,-675,-793
-537,-823,-458
-485,-357,347
-345,-311,381
-661,-816,-575
-876,649,763
-618,-824,-621
553,345,-567
474,580,667
-447,-329,318
-584,868,-557
544,-627,-890
564,392,-477
455,729,728
-892,524,684
-689,845,-530
423,-701,434
7,-33,-71
630,319,-379
443,580,662
-789,900,-551
459,-707,401
--- scanner 1 ---
686,422,578
605,423,415
515,917,-361
-336,658,858
95,138,22
-476,619,847
-340,-569,-846
567,-361,727
-460,603,-452
669,-402,600
729,430,532
-500,-761,534
-322,571,750
-466,-666,-811
-429,-592,574
-355,545,-477
703,-491,-529
-328,-685,520
413,935,-424
-391,539,-444
586,-435,557
-364,-763,-893
807,-499,-711
755,-354,-619
553,889,-390
--- scanner 2 ---
649,640,665
682,-795,504
-784,533,-524
-644,584,-595
-588,-843,648
-30,6,44
-674,560,763
500,723,-460
609,671,-379
-555,-800,653
-675,-892,-343
697,-426,-610
578,704,681
493,664,-388
-671,-858,530
-667,343,800
571,-461,-707
-138,-166,112
-889,563,-600
646,-828,498
640,759,510
-630,509,768
-681,-892,-333
673,-379,-804
-742,-814,-386
577,-820,562
--- scanner 3 ---
-589,542,597
605,-692,669
-500,565,-823
-660,373,557
-458,-679,-417
-488,449,543
-626,468,-788
338,-750,-386
528,-832,-391
562,-778,733
-938,-730,414
543,643,-506
-524,371,-870
407,773,750
-104,29,83
378,-903,-323
-778,-728,485
426,699,580
-438,-605,-362
-469,-447,-387
509,732,623
647,635,-688
-868,-804,481
614,-800,639
595,780,-596
--- scanner 4 ---
727,592,562
-293,-554,779
441,611,-461
-714,465,-776
-743,427,-804
-660,-479,-426
832,-632,460
927,-485,-438
408,393,-506
466,436,-512
110,16,151
-258,-428,682
-393,719,612
-211,-452,876
808,-476,-593
-575,615,604
-485,667,467
-680,325,-822
-627,-443,-432
872,-547,-609
833,512,582
807,604,487
839,-516,451
891,-625,532
-652,-548,-490
30,-46,-14";
#[test]
fn part1_known() {
let data = parse(&TEST_INPUT);
assert_eq!(part_1(&data), 79);
}
#[test]
fn part2_known() {
let data = parse(&TEST_INPUT);
assert_eq!(part_2(&data), 3621);
}
#[test]
fn test_day_19() {
let input = input();
assert_eq!(part_1(&input), 372);
assert_eq!(part_2(&input), 12241);
}
}

7
day_19/src/main.rs Normal file
View File

@@ -0,0 +1,7 @@
use day_19::day_19::{input, part_1, part_2};
fn main() {
let input = input();
println!("part 1 => {}", part_1(&input));
println!("part 2 => {}", part_2(&input));
}