From 6ee210cc2fddb93e444a9a5a751776b4d5c23160 Mon Sep 17 00:00:00 2001 From: Luciano Mammino Date: Tue, 5 Dec 2023 16:45:10 +0000 Subject: [PATCH] added y2023/ex05 (unoptimized) --- Cargo.toml | 1 + y2023/ex05/Cargo.toml | 16 ++ y2023/ex05/README.md | 129 +++++++++++++ y2023/ex05/benches/bench_y2023ex05.rs | 11 ++ y2023/ex05/input.txt | 238 +++++++++++++++++++++++ y2023/ex05/src/lib.rs | 264 ++++++++++++++++++++++++++ 6 files changed, 659 insertions(+) create mode 100644 y2023/ex05/Cargo.toml create mode 100644 y2023/ex05/README.md create mode 100644 y2023/ex05/benches/bench_y2023ex05.rs create mode 100644 y2023/ex05/input.txt create mode 100644 y2023/ex05/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 135c1f4..acf89b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,6 +71,7 @@ members = [ "y2023/ex02", "y2023/ex03", "y2023/ex04", + "y2023/ex05", ] [profile.bench] diff --git a/y2023/ex05/Cargo.toml b/y2023/ex05/Cargo.toml new file mode 100644 index 0000000..8173883 --- /dev/null +++ b/y2023/ex05/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "y2023ex05" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +nom = "7.1.3" + +[[bench]] +name = "bench_y2023ex05" +harness = false + +[dev-dependencies] +criterion = "0.5.1" diff --git a/y2023/ex05/README.md b/y2023/ex05/README.md new file mode 100644 index 0000000..ebdb29d --- /dev/null +++ b/y2023/ex05/README.md @@ -0,0 +1,129 @@ +# Day 5: If You Give A Seed A Fertilizer + +[Check it out on adventofcode.com](https://adventofcode.com/2023/day/5) + +## Part One + +You take the boat and find the gardener right where you were told he would be: managing a giant "garden" that looks more to you like a farm. + +"A water source? Island Island _is_ the water source!" You point out that Snow Island isn't receiving any water. + +"Oh, we had to stop the water because we _ran out of sand_ to [filter](https://en.wikipedia.org/wiki/Sand_filter) it with! Can't make snow with dirty water. Don't worry, I'm sure we'll get more sand soon; we only turned off the water a few days... weeks... oh no." His face sinks into a look of horrified realization. + +"I've been so busy making sure everyone here has food that I completely forgot to check why we stopped getting more sand! There's a ferry leaving soon that is headed over in that direction - it's much faster than your boat. Could you please go check it out?" + +You barely have time to agree to this request when he brings up another. "While you wait for the ferry, maybe you can help us with our _food production problem_. The latest Island Island [Almanac](https://en.wikipedia.org/wiki/Almanac) just arrived and we're having trouble making sense of it." + +The almanac (your puzzle input) lists all of the seeds that need to be planted. It also lists what type of soil to use with each kind of seed, what type of fertilizer to use with each kind of soil, what type of water to use with each kind of fertilizer, and so on. Every type of seed, soil, fertilizer and so on is identified with a number, but numbers are reused by each category - that is, soil `123` and fertilizer `123` aren't necessarily related to each other. + +For example: + + seeds: 79 14 55 13 + + seed-to-soil map: + 50 98 2 + 52 50 48 + + soil-to-fertilizer map: + 0 15 37 + 37 52 2 + 39 0 15 + + fertilizer-to-water map: + 49 53 8 + 0 11 42 + 42 0 7 + 57 7 4 + + water-to-light map: + 88 18 7 + 18 25 70 + + light-to-temperature map: + 45 77 23 + 81 45 19 + 68 64 13 + + temperature-to-humidity map: + 0 69 1 + 1 0 69 + + humidity-to-location map: + 60 56 37 + 56 93 4 + + +The almanac starts by listing which seeds need to be planted: seeds `79`, `14`, `55`, and `13`. + +The rest of the almanac contains a list of _maps_ which describe how to convert numbers from a _source category_ into numbers in a _destination category_. That is, the section that starts with `seed-to-soil map:` describes how to convert a _seed number_ (the source) to a _soil number_ (the destination). This lets the gardener and his team know which soil to use with which seeds, which water to use with which fertilizer, and so on. + +Rather than list every source number and its corresponding destination number one by one, the maps describe entire _ranges_ of numbers that can be converted. Each line within a map contains three numbers: the _destination range start_, the _source range start_, and the _range length_. + +Consider again the example `seed-to-soil map`: + + 50 98 2 + 52 50 48 + + +The first line has a _destination range start_ of `50`, a _source range start_ of `98`, and a _range length_ of `2`. This line means that the source range starts at `98` and contains two values: `98` and `99`. The destination range is the same length, but it starts at `50`, so its two values are `50` and `51`. With this information, you know that seed number `98` corresponds to soil number `50` and that seed number `99` corresponds to soil number `51`. + +The second line means that the source range starts at `50` and contains `48` values: `50`, `51`, ..., `96`, `97`. This corresponds to a destination range starting at `52` and also containing `48` values: `52`, `53`, ..., `98`, `99`. So, seed number `53` corresponds to soil number `55`. + +Any source numbers that _aren't mapped_ correspond to the _same_ destination number. So, seed number `10` corresponds to soil number `10`. + +So, the entire list of seed numbers and their corresponding soil numbers looks like this: + + seed soil + 0 0 + 1 1 + ... ... + 48 48 + 49 49 + 50 52 + 51 53 + ... ... + 96 98 + 97 99 + 98 50 + 99 51 + + +With this map, you can look up the soil number required for each initial seed number: + +* Seed number `79` corresponds to soil number `81`. +* Seed number `14` corresponds to soil number `14`. +* Seed number `55` corresponds to soil number `57`. +* Seed number `13` corresponds to soil number `13`. + +The gardener and his team want to get started as soon as possible, so they'd like to know the closest location that needs a seed. Using these maps, find _the lowest location number that corresponds to any of the initial seeds_. To do this, you'll need to convert each seed number through other categories until you can find its corresponding _location number_. In this example, the corresponding types are: + +* Seed `79`, soil `81`, fertilizer `81`, water `81`, light `74`, temperature `78`, humidity `78`, _location `82`_. +* Seed `14`, soil `14`, fertilizer `53`, water `49`, light `42`, temperature `42`, humidity `43`, _location `43`_. +* Seed `55`, soil `57`, fertilizer `57`, water `53`, light `46`, temperature `82`, humidity `82`, _location `86`_. +* Seed `13`, soil `13`, fertilizer `52`, water `41`, light `34`, temperature `34`, humidity `35`, _location `35`_. + +So, the lowest location number in this example is `_35_`. + +_What is the lowest location number that corresponds to any of the initial seed numbers?_ + + +Your puzzle answer was `424490994`. + + +## Part Two + +Everyone will starve if you only plant such a small number of seeds. Re-reading the almanac, it looks like the `seeds:` line actually describes _ranges of seed numbers_. + +The values on the initial `seeds:` line come in pairs. Within each pair, the first value is the _start_ of the range and the second value is the _length_ of the range. So, in the first line of the example above: + + seeds: 79 14 55 13 + +This line describes two ranges of seed numbers to be planted in the garden. The first range starts with seed number `79` and contains `14` values: `79`, `80`, ..., `91`, `92`. The second range starts with seed number `55` and contains `13` values: `55`, `56`, ..., `66`, `67`. + +Now, rather than considering four seed numbers, you need to consider a total of _27_ seed numbers. + +In the above example, the lowest location number can be obtained from seed number `82`, which corresponds to soil `84`, fertilizer `84`, water `84`, light `77`, temperature `45`, humidity `46`, and _location `46`_. So, the lowest location number is `_46_`. + +Consider all of the initial seed numbers listed in the ranges on the first line of the almanac. _What is the lowest location number that corresponds to any of the initial seed numbers?_ + +Your puzzle answer was `15290096`. diff --git a/y2023/ex05/benches/bench_y2023ex05.rs b/y2023/ex05/benches/bench_y2023ex05.rs new file mode 100644 index 0000000..ea4c1a6 --- /dev/null +++ b/y2023/ex05/benches/bench_y2023ex05.rs @@ -0,0 +1,11 @@ +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use y2023ex05::{part1, part2}; + +fn criterion_benchmark(c: &mut Criterion) { + let input = include_str!("../input.txt"); + c.bench_function("y2023ex05::part1", |b| b.iter(|| part1(black_box(input)))); + c.bench_function("y2023ex05::part2", |b| b.iter(|| part2(black_box(input)))); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/y2023/ex05/input.txt b/y2023/ex05/input.txt new file mode 100644 index 0000000..68352b9 --- /dev/null +++ b/y2023/ex05/input.txt @@ -0,0 +1,238 @@ +seeds: 3943078016 158366385 481035699 103909769 3553279107 15651230 3322093486 189601966 2957349913 359478652 924423181 691197498 2578953067 27362630 124747783 108079254 1992340665 437203822 2681092979 110901631 + +seed-to-soil map: +2702707184 1771488746 32408643 +1838704579 89787943 256129587 +3308305769 3945110092 140077818 +3628160213 4264964536 30002760 +3481822196 4118626519 146338017 +2314039806 0 23017018 +2094834166 23017018 66770925 +13529560 2374830476 266694587 +1360948085 2280951884 93878592 +2337056824 1405838386 365650360 +2735115827 1389537903 16300483 +2161605091 1122407194 152434715 +2944685788 3581490111 363619981 +3448383587 4085187910 33438609 +293095451 1923371965 152989927 +555976625 1361056107 28481796 +0 2076361892 13529560 +4055868219 3342391034 239099077 +3658162973 2944685788 397705246 +446085378 2641525063 109891247 +584458421 685760755 436646439 +1647644147 2089891452 191060432 +1528169571 1832460171 90911794 +1619081365 1803897389 28562782 +280224147 1348184803 12871304 +1021104860 345917530 339843225 +1454826677 1274841909 73342894 + +soil-to-fertilizer map: +370579153 1660655546 474809840 +1390384163 3890794774 29044725 +3933903064 3062217622 43562309 +2579648014 2135465386 381757066 +3905615715 3862507425 28287349 +4053211235 382332912 208377334 +3718132574 4107484155 187483141 +3977465373 306587050 75745862 +1866333065 230994048 75593002 +1268904151 2940737610 121480012 +3646057320 3790432171 72075254 +845388993 2517222452 423515158 +2291172026 769577840 288475988 +4261588569 3919839499 33378727 +2112304432 590710246 178867594 +1419428888 1213751369 446904177 +2961405080 3105779931 684652240 +230994048 3967899050 139585105 +2097623608 3953218226 14680824 +1941926067 1058053828 155697541 + +fertilizer-to-water map: +0 1551952886 33233684 +961721436 932763195 63696624 +2767354703 3875238046 18117484 +3717194106 2676555200 188038931 +799543557 483022915 162177879 +2428347038 3081230279 28566103 +2872288153 3519235797 218585862 +215425000 1162608123 279396952 +1473270503 411403786 71619129 +2762028477 2930057227 5326226 +3263853515 2169144956 62130350 +3330983617 2935383453 10086546 +2522376237 2231275306 106924906 +2757818051 2103190872 4210426 +3090874015 3187643516 172979500 +2785472187 2530367956 37190043 +1365587214 49710602 107683289 +554985341 330919476 80484310 +3639346972 3109796382 77847134 +1964878739 1442005075 21531118 +2098191120 3737821659 137416387 +1832452033 298110266 32809210 +2456913141 2864594131 65463096 +1025418060 1606654056 340169154 +2277580887 2475812485 29651215 +2416229303 2107401298 12117735 +33233684 176973083 62797441 +157085258 239770524 58339742 +2307232102 2567557999 108997201 +1915168137 0 49710602 +2235607507 3893355530 41973380 +1865261243 1502045992 49906894 +3905233037 3935328910 231121478 +494821952 157393891 19579192 +514401144 996459819 40584197 +4136354515 3360623016 158612781 +3503586692 2945469999 135760280 +635469651 1463536193 38509799 +2629301143 4166450388 128516908 +2822662230 2119519033 49625923 +3325983865 2098191120 4999752 +3341070163 2338200212 137612273 +3478682436 2505463700 24904256 +96031125 1971548655 36328688 +1986409857 1585186570 21467486 +673979450 1037044016 125564107 +1544889632 645200794 287562401 +132359813 1946823210 24725445 + +water-to-light map: +3326310943 1150412752 87200223 +4257088620 4233111242 37878676 +3994159838 4060724644 54228568 +3876001808 4114953212 90976210 +2886658207 1485800780 134153427 +3966978018 4205929422 27181820 +4048388406 3874470488 149045901 +528406865 502600485 237825862 +111547576 1241598488 111964267 +3068561383 1485461466 339314 +3168255879 3056441319 158055064 +3504257503 1453325844 32135622 +2109734789 3372472386 240074722 +3068900697 403245303 99355182 +2027101388 740426347 82633401 +1219093087 1970502974 808008301 +3643122008 1951548756 18954218 +2603944924 279757237 123488066 +766232727 0 10960493 +3712182589 4270989918 1531320 +3536393125 2778511275 106728883 +3482397575 1237612975 3985513 +777193220 1763962961 71462615 +1117452579 1680930659 83032302 +3413511166 3214496383 46428427 +2432743763 2885240158 171201161 +0 3260924810 111547576 +3486383088 1835425576 17874415 +3672475952 3703073187 39706637 +848655835 10960493 268796744 +4197434307 4023516389 37208255 +3459939593 823059748 22457982 +2727432990 1853299991 98248765 +4234642562 4272521238 22446058 +3713713909 3672475952 30597235 +2351588880 1353562755 81154883 +223511843 845517730 304895022 +3744311144 3742779824 131690664 +1200484881 1434717638 18608206 +3020811634 3612547108 47749749 +2349809511 3660296857 1779369 +2825681755 1619954207 60976452 + +light-to-temperature map: +252460180 3718023854 80580651 +3778113118 1519654737 306188725 +333040831 2573805517 96168275 +4084301843 3798604505 210665453 +1694244932 1825843462 379128459 +1487313708 2669973792 206931224 +429209106 2876905016 268167573 +3133421217 3610326681 107697173 +1486370741 3145072589 942967 +697376679 3146015556 464311125 +2152115592 836439718 249469053 +3241118390 214400336 17576418 +214400336 1164650972 38059844 +2073373391 1085908771 78742201 +1161687804 2248952614 324682937 +3258694808 231976754 268511965 +3527206773 1312729085 206925652 +3133251251 2573635551 169966 +2930227394 4091943439 203023857 +2484258126 790765872 45673846 +2639950241 500488719 290277153 +2529931972 1202710816 110018269 +2401584645 4009269958 82673481 +3734132425 2204971921 43980693 + +temperature-to-humidity map: +168091833 268406932 76258451 +3449803430 2843367435 19310453 +2007621581 1615073306 528954706 +1947960540 798304921 59661041 +3469113883 3441273912 247683303 +3980335429 3688957215 155495519 +1382488646 1289756018 231480201 +1613968847 2144028012 203484286 +3030343754 2862677888 310561319 +311459258 1257812898 31943120 +3716797186 4024477040 263538243 +743249314 734822904 63482017 +2843367435 4288015283 6952013 +244350284 201297958 67108974 +806731331 549427536 185395368 +33679712 344665383 134412121 +1817453133 1521236219 93837087 +2850319448 3844452734 180024306 +1193424657 2347512298 189063989 +992126699 0 201297958 +3340905073 3173239207 108898357 +343402378 857965962 399846936 +0 479077504 33679712 +4135830948 3282137564 159136348 +1911290220 512757216 36670320 + +humidity-to-location map: +1586270647 2666237958 31388199 +1639118951 2401662894 243114959 +673413244 1218441073 9004417 +4189219561 4197782169 97185127 +339701505 993997384 224443689 +2088925654 1227445490 16145987 +3048450614 2034241441 196558736 +3245009350 3057456069 37064056 +1990947272 217743214 23964128 +755791330 433456361 436687719 +3750378482 1243591477 29460651 +1347952933 3094520125 238317714 +682417661 3593572644 73373669 +1891967948 3494593320 98979324 +2746577216 1325573050 27089148 +90823161 3346797254 147796066 +238619227 1933159163 101082278 +2884769306 269775053 163681308 +564145194 0 109268050 +2014911400 1273052128 12916400 +2773666364 1295702566 29870484 +0 903174223 90823161 +4286404688 3841991082 8562608 +1617658846 2644777853 21460105 +2714916854 3748178771 31660362 +2275934358 3332837839 13959415 +2027827800 870144080 33030143 +3841991082 4158641967 39140202 +3881131284 3850553690 308088277 +3390548570 2697626157 359829912 +1882233910 1285968528 9734038 +2105071641 2230800177 170862717 +1192479049 1777685279 155473884 +2803536848 3666946313 81232458 +2289893773 1352662198 425023081 +2060857943 241707342 28067711 +3282073406 109268050 108475164 \ No newline at end of file diff --git a/y2023/ex05/src/lib.rs b/y2023/ex05/src/lib.rs new file mode 100644 index 0000000..be00461 --- /dev/null +++ b/y2023/ex05/src/lib.rs @@ -0,0 +1,264 @@ +use nom::{ + branch::alt, + bytes::complete::tag, + character::complete::u64, + combinator::{complete, eof, opt}, + multi::{many_till, separated_list1}, + IResult, +}; +use std::ops::Range; + +#[derive(Debug)] +struct Almanac { + seeds: Vec, + seed_to_soil_map: Mapping, + soil_to_fertilizer_map: Mapping, + fertilizer_to_water_map: Mapping, + water_to_light_map: Mapping, + light_to_temperature_map: Mapping, + temperature_to_humidity_map: Mapping, + humidity_to_location_map: Mapping, +} + +impl Almanac { + fn seed_to_location(&self, seed: u64) -> u64 { + let value = self.seed_to_soil_map.map(seed); + let value = self.soil_to_fertilizer_map.map(value); + let value = self.fertilizer_to_water_map.map(value); + let value = self.water_to_light_map.map(value); + let value = self.light_to_temperature_map.map(value); + let value = self.temperature_to_humidity_map.map(value); + let value = self.humidity_to_location_map.map(value); + value + } +} + +#[derive(Debug, PartialEq, Eq)] +struct MappingEntry { + range: Range, + delta: i64, +} + +impl MappingEntry { + fn new(destination_range_start: u64, source_range_start: u64, range_length: u64) -> Self { + let range = source_range_start..(source_range_start + range_length); + let delta = destination_range_start as i64 - source_range_start as i64; + Self { range, delta } + } +} + +#[derive(Debug, PartialEq, Eq)] +struct Mapping { + entries: Vec, +} + +impl Mapping { + fn map(&self, value: u64) -> u64 { + for entry in &self.entries { + if entry.range.contains(&value) { + return (value as i64 + entry.delta) as u64; + } + } + value + } +} + +fn parse_seeds(input: &str) -> IResult<&str, Vec> { + // seeds: 3943078016 158366385 481035699 103909769 3553279107 15651230 3322093486 189601966 2957349913 359478652 924423181 691197498 2578953067 27362630 124747783 108079254 1992340665 437203822 2681092979 110901631 + + let (input, _) = tag("seeds: ")(input)?; + let (input, seeds) = separated_list1(tag(" "), u64)(input)?; + + Ok((input, seeds)) +} + +fn parse_mapping_entry(input: &str) -> IResult<&str, MappingEntry> { + // 2702707184 1771488746 32408643 + let (input, destination_range_start) = u64(input)?; + let (input, _) = tag(" ")(input)?; + let (input, source_range_start) = u64(input)?; + let (input, _) = tag(" ")(input)?; + let (input, range_length) = u64(input)?; + // add an optional new line consumption + let (input, _) = opt(tag("\n"))(input)?; + + Ok(( + input, + MappingEntry::new(destination_range_start, source_range_start, range_length), + )) +} + +fn parse_mapping(input: &str) -> IResult<&str, Mapping> { + let (input, (entries, _)) = many_till(parse_mapping_entry, alt((tag("\n"), eof)))(input)?; + Ok((input, Mapping { entries })) +} + +fn parse_almanac(input: &str) -> IResult<&str, Almanac> { + let (input, seeds) = parse_seeds(input)?; + let (input, _) = tag("\n\n")(input)?; + let (input, _) = tag("seed-to-soil map:\n")(input)?; + let (input, seed_to_soil_map) = parse_mapping(input)?; + let (input, _) = tag("soil-to-fertilizer map:\n")(input)?; + let (input, soil_to_fertilizer_map) = parse_mapping(input)?; + let (input, _) = tag("fertilizer-to-water map:\n")(input)?; + let (input, fertilizer_to_water_map) = parse_mapping(input)?; + let (input, _) = tag("water-to-light map:\n")(input)?; + let (input, water_to_light_map) = parse_mapping(input)?; + let (input, _) = tag("light-to-temperature map:\n")(input)?; + let (input, light_to_temperature_map) = parse_mapping(input)?; + let (input, _) = tag("temperature-to-humidity map:\n")(input)?; + let (input, temperature_to_humidity_map) = parse_mapping(input)?; + let (input, _) = tag("humidity-to-location map:\n")(input)?; + let (input, humidity_to_location_map) = complete(parse_mapping)(input)?; + + let almanac = Almanac { + seeds, + seed_to_soil_map, + soil_to_fertilizer_map, + fertilizer_to_water_map, + water_to_light_map, + light_to_temperature_map, + temperature_to_humidity_map, + humidity_to_location_map, + }; + Ok((input, almanac)) +} + +pub fn part1(input: &str) -> u64 { + let (_, almanac) = parse_almanac(input).unwrap(); + almanac + .seeds + .iter() + .map(|seed| almanac.seed_to_location(*seed)) + .min() + .unwrap() +} + +pub fn part2(input: &str) -> u64 { + // TODO: this solution is currently very slow (100+ seconds in --release mode) + // figure out how to refactor it to be faster + // ideas: + // - merge all the transformation layers into one + // - find a way to index the ranges more efficiently (so that we don't have to scan them all for every seed) + let (_, almanac) = parse_almanac(input).unwrap(); + almanac + .seeds + .as_slice() + .chunks(2) + .flat_map(|r| { + let range_start = r[0]; + let range_len = r[1]; + let range = range_start..(range_start + range_len); + range.map(|seed| almanac.seed_to_location(seed)) + }) + .min() + .unwrap() +} + +#[cfg(test)] +mod tests { + use super::*; + const INPUT: &str = include_str!("../input.txt"); + const EXAMPLE_INPUT: &str = "seeds: 79 14 55 13 + +seed-to-soil map: +50 98 2 +52 50 48 + +soil-to-fertilizer map: +0 15 37 +37 52 2 +39 0 15 + +fertilizer-to-water map: +49 53 8 +0 11 42 +42 0 7 +57 7 4 + +water-to-light map: +88 18 7 +18 25 70 + +light-to-temperature map: +45 77 23 +81 45 19 +68 64 13 + +temperature-to-humidity map: +0 69 1 +1 0 69 + +humidity-to-location map: +60 56 37 +56 93 4"; + + #[test] + fn test_mapping() { + let entries = vec![MappingEntry::new(50, 98, 2), MappingEntry::new(52, 50, 48)]; + let mapper = Mapping { entries }; + + assert_eq!(mapper.map(98), 50); + assert_eq!(mapper.map(99), 51); + assert_eq!(mapper.map(53), 55); + // not mapped + assert_eq!(mapper.map(10), 10); + } + + #[test] + fn test_parse_almanac() { + let (_, almanac) = parse_almanac(EXAMPLE_INPUT).unwrap(); + assert_eq!(almanac.seeds, vec![79, 14, 55, 13]); + assert_eq!( + almanac.seed_to_soil_map.entries, + vec![MappingEntry::new(50, 98, 2), MappingEntry::new(52, 50, 48)] + ); + assert_eq!( + almanac.soil_to_fertilizer_map.entries, + vec![ + MappingEntry::new(0, 15, 37), + MappingEntry::new(37, 52, 2), + MappingEntry::new(39, 0, 15) + ] + ); + assert_eq!( + almanac.fertilizer_to_water_map.entries, + vec![ + MappingEntry::new(49, 53, 8), + MappingEntry::new(0, 11, 42), + MappingEntry::new(42, 0, 7), + MappingEntry::new(57, 7, 4) + ] + ); + assert_eq!( + almanac.water_to_light_map.entries, + vec![MappingEntry::new(88, 18, 7), MappingEntry::new(18, 25, 70)] + ); + assert_eq!( + almanac.light_to_temperature_map.entries, + vec![ + MappingEntry::new(45, 77, 23), + MappingEntry::new(81, 45, 19), + MappingEntry::new(68, 64, 13) + ] + ); + assert_eq!( + almanac.temperature_to_humidity_map.entries, + vec![MappingEntry::new(0, 69, 1), MappingEntry::new(1, 0, 69)] + ); + assert_eq!( + almanac.humidity_to_location_map.entries, + vec![MappingEntry::new(60, 56, 37), MappingEntry::new(56, 93, 4)] + ); + } + + #[test] + fn test_part1() { + assert_eq!(part1(INPUT), 424490994); + } + + #[test] + fn test_part2() { + assert_eq!(part2(INPUT), 15290096); + } +}