day 05
This commit is contained in:
parent
920b21dbab
commit
f88c8db711
|
@ -2,6 +2,51 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day-01"
|
||||
version = "0.1.0"
|
||||
|
@ -23,12 +68,45 @@ dependencies = [
|
|||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day-05"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"ranges",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
|
@ -44,3 +122,35 @@ dependencies = [
|
|||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ranges"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f781d391cd4838df77e09fd26e33a87e0ac9bf2edf6ff770cfc65f83d50e3948"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
|
|
@ -3,8 +3,11 @@ resolver = "2"
|
|||
members = [
|
||||
"day-01",
|
||||
"day-02",
|
||||
"day-03"
|
||||
"day-03",
|
||||
"day-05"
|
||||
]
|
||||
|
||||
[workspace.dependencies]
|
||||
itertools = "0.12.0"
|
||||
nom = "7.1.3"
|
||||
rayon = "1.8.0"
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "day-05"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
itertools.workspace = true
|
||||
ranges = "0.3.3"
|
||||
rayon.workspace = true
|
|
@ -0,0 +1,245 @@
|
|||
seeds: 3037945983 743948277 2623786093 391282324 195281306 62641412 769611781 377903357 2392990228 144218002 1179463071 45174621 2129467491 226193957 1994898626 92402726 1555863421 340215202 426882817 207194644
|
||||
|
||||
seed-to-soil map:
|
||||
3078006360 2182201339 30483272
|
||||
803630304 624445326 165226844
|
||||
2393736333 2745251526 281120946
|
||||
717936870 789672170 85693434
|
||||
598717319 410599330 27984688
|
||||
3999095007 2024628810 157572529
|
||||
3605588191 3026372472 22322803
|
||||
3555659576 2678166775 3396919
|
||||
968857148 438584018 1780307
|
||||
3216227818 2212684611 87459567
|
||||
2302084376 4122083708 91651957
|
||||
970637455 0 188112122
|
||||
507182228 299146916 40412346
|
||||
1372302034 1689624457 202945009
|
||||
1370123632 191483770 2178402
|
||||
324787204 193662172 105484744
|
||||
3116425470 2671328191 6838584
|
||||
626702007 875365604 82756204
|
||||
1575247043 978774853 317322423
|
||||
3134996187 4213735665 81231631
|
||||
2024628810 2681563694 63687832
|
||||
714565222 188112122 3371648
|
||||
547594574 1620884480 51122745
|
||||
3529388087 3374604163 26271489
|
||||
709458211 973428243 5107011
|
||||
2713008276 3985570976 98361735
|
||||
2088316642 3048695275 213767734
|
||||
3627910994 2300144178 371184013
|
||||
2674857279 4083932711 38150997
|
||||
1229789645 958121808 15306435
|
||||
4156667536 3328662676 45941487
|
||||
0 1296097276 324787204
|
||||
3108489632 3320726838 7935838
|
||||
4202609023 3667512001 92358273
|
||||
1352266801 978535254 239599
|
||||
1352506400 1672007225 17617232
|
||||
1245096080 440364325 107170721
|
||||
2811370011 3400875652 266636349
|
||||
430271948 547535046 76910280
|
||||
1158749577 339559262 71040068
|
||||
3559056495 3262463009 46531696
|
||||
3123264054 3308994705 11732133
|
||||
3303687385 3759870274 225700702
|
||||
|
||||
soil-to-fertilizer map:
|
||||
2937874770 2957653952 339980892
|
||||
1886469734 2145122669 192293654
|
||||
3277855662 822424488 19779182
|
||||
2622882196 2393077006 314992574
|
||||
3449876679 3769116301 525850995
|
||||
583550735 842203670 1302918999
|
||||
2145755543 345297835 477126653
|
||||
2078763388 2890661797 66992155
|
||||
2650514 2708069580 182592217
|
||||
0 2337416323 2650514
|
||||
530540566 2340066837 53010169
|
||||
185242731 0 345297835
|
||||
3975727674 3449876679 319239622
|
||||
|
||||
fertilizer-to-water map:
|
||||
861477134 5168332 68211907
|
||||
136969509 2229711837 29094441
|
||||
2823248929 1150509810 118368045
|
||||
3678888284 3073610919 53498438
|
||||
3948051821 3682691325 96234592
|
||||
1302827191 2387840795 504257794
|
||||
1198743248 1926818347 104083943
|
||||
1807084985 1104177008 46332802
|
||||
2143096098 619653304 259805223
|
||||
2063436946 2385211148 2629647
|
||||
2066066593 445026117 35759449
|
||||
358008423 537865723 81787581
|
||||
621204445 0 5168332
|
||||
2724438904 1861632296 65186051
|
||||
1853417787 2258806278 126404870
|
||||
3933311080 4141091197 14740741
|
||||
851739278 2892098589 9737856
|
||||
4044286413 3029323079 44287840
|
||||
1979822657 1778018007 83614289
|
||||
2101826042 2084781230 3070511
|
||||
4088574253 4268409625 26557671
|
||||
929689041 111346117 211974050
|
||||
3566310597 4155831938 112577687
|
||||
439796004 2030902290 53878940
|
||||
166063950 1490707297 191944473
|
||||
8760514 888219041 128208995
|
||||
3794695843 3778925917 57203243
|
||||
3029323079 3127109357 409045756
|
||||
2792635116 77722143 30613813
|
||||
3438368835 4013149435 127941762
|
||||
3732386722 3620382204 62309121
|
||||
2402901321 1682651770 95366237
|
||||
0 879458527 8760514
|
||||
493674944 2901836445 39780529
|
||||
3851899086 3536155113 81411994
|
||||
2498267558 1268877855 221829442
|
||||
4117947021 3836129160 177020275
|
||||
2789624955 108335956 3010161
|
||||
1141663091 480785566 57080157
|
||||
2104896553 406826572 38199545
|
||||
533455473 1016428036 87748972
|
||||
626372777 2087851741 141860096
|
||||
2720097000 73380239 4341904
|
||||
4115131924 3617567107 2815097
|
||||
768232873 323320167 83506405
|
||||
|
||||
water-to-light map:
|
||||
3846882465 367033980 98093832
|
||||
1878565977 3292746518 62917983
|
||||
4255729420 661438934 39237876
|
||||
469590509 2191298319 301681796
|
||||
381948234 1999013894 87642275
|
||||
3688496086 199351627 156562666
|
||||
1300818753 2086656169 104642150
|
||||
806539912 2798447654 224466318
|
||||
1265336919 355914293 11119687
|
||||
1405460903 1914042148 28882526
|
||||
2577391070 1942924674 56089220
|
||||
3680239306 4136990116 8256780
|
||||
1941483960 700676810 607954854
|
||||
3845058752 3022913972 1823713
|
||||
4239658038 1308631664 16071382
|
||||
2566162195 4254580741 11228875
|
||||
1671792383 3831845903 10462472
|
||||
3944976297 3842308375 294681741
|
||||
3290662499 3160062910 132683608
|
||||
2549438814 1324703046 16723381
|
||||
3423346107 1341426427 27108304
|
||||
1031006230 3355664501 234330689
|
||||
1276456606 4145246896 24362147
|
||||
3450454411 54538430 144813197
|
||||
1682254855 465127812 196311122
|
||||
54538430 1403802338 272790856
|
||||
2633480290 2492980115 305467539
|
||||
3595267608 4169609043 84971698
|
||||
3242064105 3644614138 48598394
|
||||
3077581200 4265809616 29157680
|
||||
771272305 1368534731 35267607
|
||||
1434343429 1676593194 237448954
|
||||
327329286 3589995190 54618948
|
||||
3106738880 3024737685 135325225
|
||||
2938947829 3693212532 138633371
|
||||
|
||||
light-to-temperature map:
|
||||
2777813298 2971073270 586210802
|
||||
1687968665 0 334152507
|
||||
4159107034 3882460035 135860262
|
||||
0 2095520416 192800212
|
||||
3640671099 3557284072 3145370
|
||||
2455782705 3560429442 322030593
|
||||
2022121172 1272848785 266199456
|
||||
773517036 914869331 357979454
|
||||
1131496490 1539048241 556472175
|
||||
3364024100 4018320297 60669366
|
||||
3643816469 2455782705 515290565
|
||||
192800212 334152507 580716824
|
||||
3424693466 4078989663 215977633
|
||||
|
||||
temperature-to-humidity map:
|
||||
4072523312 605654847 17750681
|
||||
1174610018 540191835 65463012
|
||||
2038455907 3792024734 100202248
|
||||
2539396783 866566556 128459181
|
||||
96342672 2296045868 14715058
|
||||
3827330744 1522255720 106701221
|
||||
3816190028 4081148893 11140716
|
||||
1706101724 3892226982 188921911
|
||||
3780839952 623405528 35350076
|
||||
765616949 1813669629 408993069
|
||||
4225769488 3778728770 13295964
|
||||
2752105545 1645897858 167771771
|
||||
2138658155 1121517092 400738628
|
||||
4239065452 4155853973 55901844
|
||||
3934031965 96342672 35726394
|
||||
3005272654 658755604 22724553
|
||||
3989311833 4211755817 83211479
|
||||
280430452 3186777866 320785315
|
||||
111057730 2310760926 65268270
|
||||
176326000 3659551759 104104452
|
||||
1895023635 1628956941 16940917
|
||||
4093334384 3507563181 132435104
|
||||
3027997207 132069066 179421352
|
||||
1477400307 311490418 228701417
|
||||
2934949875 2225723089 70322779
|
||||
601215767 681480157 100836818
|
||||
2919877316 3763656211 15072559
|
||||
3969758359 3639998285 19553474
|
||||
3207418559 2613356473 573421393
|
||||
4090273993 2222662698 3060391
|
||||
1911964552 995025737 126491355
|
||||
2667855964 782316975 84249581
|
||||
1240073030 2376029196 237327277
|
||||
702052585 4092289609 63564364
|
||||
|
||||
humidity-to-location map:
|
||||
2848734682 2982177676 22285660
|
||||
3380476660 3717224958 24199873
|
||||
3201930685 734568132 100088122
|
||||
764851360 4087339561 71173655
|
||||
188169313 2953711255 28466421
|
||||
3189375901 2832231336 12554784
|
||||
3369909102 47909639 10567558
|
||||
47909639 3741424831 99762378
|
||||
2871020342 58477197 7400020
|
||||
3042878026 3409715295 146497875
|
||||
1196348942 2734551883 97679453
|
||||
3418711171 3387790447 21924848
|
||||
1587973141 573552831 65833150
|
||||
1121006696 889063447 75342246
|
||||
1294028395 567796360 5756471
|
||||
3302018807 499906065 67890295
|
||||
2915035031 2921050411 32660844
|
||||
1982422286 3064299481 301982155
|
||||
704786709 4084864539 2475022
|
||||
299076626 834656254 54407193
|
||||
3623423724 2182055199 207702290
|
||||
388851709 2881400789 39649622
|
||||
147672017 3592293988 40497296
|
||||
2947695875 639385981 95182151
|
||||
707261731 3556213170 36080818
|
||||
2284404441 2389757489 138657919
|
||||
353483819 2146687309 35367890
|
||||
2519626540 441189704 58319568
|
||||
743342549 3366281636 21508811
|
||||
2878420362 2844786120 36614669
|
||||
216635734 4212526404 82440892
|
||||
3440636019 1235194267 182787705
|
||||
2577946108 964405693 270788574
|
||||
1453221956 3877915244 70435137
|
||||
836025015 1861705628 284981681
|
||||
1299784866 499509272 396793
|
||||
1859942766 3948350381 122479520
|
||||
2423062360 3004463336 59836145
|
||||
3404676533 4070829901 14034638
|
||||
1399208768 4158513216 54013188
|
||||
1300181659 342162595 99027109
|
||||
1523657093 3652908910 64316048
|
||||
3851243640 1417981972 443723656
|
||||
3831126014 3632791284 20117626
|
||||
1653806291 2528415408 206136475
|
||||
428501331 65877217 276285378
|
||||
2482898505 3841187209 36728035
|
|
@ -0,0 +1,115 @@
|
|||
use std::str::Lines;
|
||||
|
||||
fn main() {
|
||||
println!("{}", part1(include_str!("./input.txt")));
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct MapEntry {
|
||||
destination: u64,
|
||||
source: u64,
|
||||
range_length: u64,
|
||||
}
|
||||
impl MapEntry {
|
||||
fn new(destination: u64, source: u64, range_length: u64) -> Self {
|
||||
Self {
|
||||
destination,
|
||||
source,
|
||||
range_length,
|
||||
}
|
||||
}
|
||||
fn get(&self, value: u64) -> Option<u64> {
|
||||
if value >= self.source && (self.source..self.source + self.range_length).contains(&value) {
|
||||
Some(value - self.source + self.destination)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn part1(input: &str) -> u64 {
|
||||
let mut seeds = Vec::new();
|
||||
let mut seed_to_soil = Vec::new();
|
||||
let mut soil_to_fertilizer = Vec::new();
|
||||
let mut fertilizer_to_water = Vec::new();
|
||||
let mut water_to_light = Vec::new();
|
||||
let mut light_to_temperature = Vec::new();
|
||||
let mut temperature_to_humidity = Vec::new();
|
||||
let mut humidity_to_location = Vec::new();
|
||||
|
||||
input.split("\n\n").for_each(|part| {
|
||||
let mut lines = part.lines();
|
||||
let mut split = lines.next().unwrap().split(':');
|
||||
let key = split.next().unwrap();
|
||||
match key {
|
||||
"seeds" => split
|
||||
.next()
|
||||
.unwrap()
|
||||
.split_ascii_whitespace()
|
||||
.for_each(|s| {
|
||||
seeds.push(s.parse::<u64>().unwrap());
|
||||
}),
|
||||
"seed-to-soil map" => process_map(lines, &mut seed_to_soil),
|
||||
"soil-to-fertilizer map" => process_map(lines, &mut soil_to_fertilizer),
|
||||
"fertilizer-to-water map" => process_map(lines, &mut fertilizer_to_water),
|
||||
"water-to-light map" => process_map(lines, &mut water_to_light),
|
||||
"light-to-temperature map" => process_map(lines, &mut light_to_temperature),
|
||||
"temperature-to-humidity map" => process_map(lines, &mut temperature_to_humidity),
|
||||
"humidity-to-location map" => process_map(lines, &mut humidity_to_location),
|
||||
key => unreachable!("Invalid key: {}", key),
|
||||
}
|
||||
});
|
||||
|
||||
let maps = [
|
||||
seed_to_soil,
|
||||
soil_to_fertilizer,
|
||||
fertilizer_to_water,
|
||||
water_to_light,
|
||||
light_to_temperature,
|
||||
temperature_to_humidity,
|
||||
humidity_to_location,
|
||||
];
|
||||
|
||||
seeds
|
||||
.into_iter()
|
||||
.map(|s| find_location(s, &maps))
|
||||
.min()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn process_map(lines: Lines, map: &mut Vec<MapEntry>) {
|
||||
lines
|
||||
.map(|l| {
|
||||
let parts = l.split_ascii_whitespace().collect::<Vec<_>>();
|
||||
MapEntry::new(
|
||||
parts[0].parse::<u64>().unwrap(),
|
||||
parts[1].parse::<u64>().unwrap(),
|
||||
parts[2].parse::<u64>().unwrap(),
|
||||
)
|
||||
})
|
||||
.for_each(|entry| {
|
||||
map.push(entry);
|
||||
})
|
||||
}
|
||||
|
||||
fn find_location(seed: u64, maps: &[Vec<MapEntry>; 7]) -> u64 {
|
||||
let mut current = seed;
|
||||
for map in maps.iter() {
|
||||
current = map
|
||||
.iter()
|
||||
.find_map(|entry| entry.get(current))
|
||||
.unwrap_or(current);
|
||||
}
|
||||
current
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
const INPUT: &str = "seeds: 79 14 55 13\n\nseed-to-soil map:\n50 98 2\n52 50 48\n\nsoil-to-fertilizer map:\n0 15 37\n37 52 2\n39 0 15\n\nfertilizer-to-water map:\n49 53 8\n0 11 42\n42 0 7\n57 7 4\n\nwater-to-light map:\n88 18 7\n18 25 70\n\nlight-to-temperature map:\n45 77 23\n81 45 19\n68 64 13\n\ntemperature-to-humidity map:\n0 69 1\n1 0 69\n\nhumidity-to-location map:\n60 56 37\n56 93 4";
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
assert_eq!(part1(INPUT), 35);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
use itertools::Itertools;
|
||||
use ranges::{GenericRange, Ranges};
|
||||
use rayon::prelude::*;
|
||||
use std::{
|
||||
ops::{Bound, Range, RangeBounds},
|
||||
str::Lines,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
println!("{}", part2(include_str!("./input.txt")));
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct MapEntry {
|
||||
destination: u64,
|
||||
source: u64,
|
||||
range_length: u64,
|
||||
}
|
||||
impl MapEntry {
|
||||
fn new(destination: u64, source: u64, range_length: u64) -> Self {
|
||||
Self {
|
||||
destination,
|
||||
source,
|
||||
range_length,
|
||||
}
|
||||
}
|
||||
fn source_range(&self) -> Range<u64> {
|
||||
self.source..(self.source + self.range_length)
|
||||
}
|
||||
fn get_offset(&self) -> i64 {
|
||||
self.destination as i64 - self.source as i64
|
||||
}
|
||||
}
|
||||
|
||||
fn part2(input: &str) -> u64 {
|
||||
let mut seeds = Vec::new();
|
||||
let mut seed_to_soil = Vec::new();
|
||||
let mut soil_to_fertilizer = Vec::new();
|
||||
let mut fertilizer_to_water = Vec::new();
|
||||
let mut water_to_light = Vec::new();
|
||||
let mut light_to_temperature = Vec::new();
|
||||
let mut temperature_to_humidity = Vec::new();
|
||||
let mut humidity_to_location = Vec::new();
|
||||
|
||||
input.split("\n\n").for_each(|part| {
|
||||
let mut lines = part.lines();
|
||||
let mut split = lines.next().unwrap().split(':');
|
||||
let key = split.next().unwrap();
|
||||
match key {
|
||||
"seeds" => split
|
||||
.next()
|
||||
.unwrap()
|
||||
.split_ascii_whitespace()
|
||||
.tuples()
|
||||
.for_each(|(s, l)| {
|
||||
let start = s.parse::<u64>().unwrap();
|
||||
let length = l.parse::<u64>().unwrap();
|
||||
seeds.push(start..(start + length));
|
||||
}),
|
||||
"seed-to-soil map" => process_map(lines, &mut seed_to_soil),
|
||||
"soil-to-fertilizer map" => process_map(lines, &mut soil_to_fertilizer),
|
||||
"fertilizer-to-water map" => process_map(lines, &mut fertilizer_to_water),
|
||||
"water-to-light map" => process_map(lines, &mut water_to_light),
|
||||
"light-to-temperature map" => process_map(lines, &mut light_to_temperature),
|
||||
"temperature-to-humidity map" => process_map(lines, &mut temperature_to_humidity),
|
||||
"humidity-to-location map" => process_map(lines, &mut humidity_to_location),
|
||||
key => unreachable!("Invalid key: {}", key),
|
||||
}
|
||||
});
|
||||
|
||||
let maps = [
|
||||
seed_to_soil,
|
||||
soil_to_fertilizer,
|
||||
fertilizer_to_water,
|
||||
water_to_light,
|
||||
light_to_temperature,
|
||||
temperature_to_humidity,
|
||||
humidity_to_location,
|
||||
];
|
||||
let seeds = seeds.into_iter().fold(Ranges::new(), |acc, r| acc.union(r));
|
||||
|
||||
find_min_location(seeds, &maps)
|
||||
}
|
||||
|
||||
fn process_map(lines: Lines, map: &mut Vec<MapEntry>) {
|
||||
lines
|
||||
.map(|l| {
|
||||
let parts = l.split_ascii_whitespace().collect::<Vec<_>>();
|
||||
MapEntry::new(
|
||||
parts[0].parse::<u64>().unwrap(),
|
||||
parts[1].parse::<u64>().unwrap(),
|
||||
parts[2].parse::<u64>().unwrap(),
|
||||
)
|
||||
})
|
||||
.for_each(|entry| {
|
||||
map.push(entry);
|
||||
})
|
||||
}
|
||||
|
||||
fn find_min_location(seeds: Ranges<u64>, maps: &[Vec<MapEntry>; 7]) -> u64 {
|
||||
let mut new_ranges = seeds;
|
||||
for map in maps {
|
||||
new_ranges = apply_map(new_ranges, map);
|
||||
}
|
||||
|
||||
new_ranges
|
||||
.as_slice()
|
||||
.par_iter()
|
||||
.map(|r| r.into_iter().min().unwrap())
|
||||
.min()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn apply_map(mut seeds: Ranges<u64>, map: &[MapEntry]) -> Ranges<u64> {
|
||||
let mut new_ranges = Ranges::new();
|
||||
for entry in map {
|
||||
let matching_ranges_for_entry = seeds.clone().intersect(Ranges::from(entry.source_range()));
|
||||
seeds = seeds.difference(matching_ranges_for_entry.clone());
|
||||
|
||||
let offset = entry.get_offset();
|
||||
let offset_ranges = offset_ranges(matching_ranges_for_entry, offset);
|
||||
|
||||
new_ranges = new_ranges.union(offset_ranges);
|
||||
}
|
||||
new_ranges.union(seeds)
|
||||
}
|
||||
|
||||
fn offset_ranges(ranges: Ranges<u64>, offset: i64) -> Ranges<u64> {
|
||||
ranges
|
||||
.as_slice()
|
||||
.iter()
|
||||
.map(|r| offset_range(*r, offset))
|
||||
.collect::<Ranges<u64>>()
|
||||
}
|
||||
|
||||
fn offset_range(range: GenericRange<u64>, offset: i64) -> GenericRange<u64> {
|
||||
let range_start = if let Bound::Included(start) = range.start_bound() {
|
||||
*start as i128 + offset as i128
|
||||
} else {
|
||||
panic!("should only be called with included start bound")
|
||||
} as u64;
|
||||
let range_end = if let Bound::Excluded(end) = range.end_bound() {
|
||||
*end as i128 + offset as i128
|
||||
} else {
|
||||
panic!("should only be called with included start bound")
|
||||
} as u64;
|
||||
|
||||
(range_start..range_end).into()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
const INPUT: &str = "seeds: 79 14 55 13\n\nseed-to-soil map:\n50 98 2\n52 50 48\n\nsoil-to-fertilizer map:\n0 15 37\n37 52 2\n39 0 15\n\nfertilizer-to-water map:\n49 53 8\n0 11 42\n42 0 7\n57 7 4\n\nwater-to-light map:\n88 18 7\n18 25 70\n\nlight-to-temperature map:\n45 77 23\n81 45 19\n68 64 13\n\ntemperature-to-humidity map:\n0 69 1\n1 0 69\n\nhumidity-to-location map:\n60 56 37\n56 93 4";
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
assert_eq!(part2(INPUT), 46);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue