diff --git a/5/Cargo.lock b/5/Cargo.lock index 7a62bb0..5a6ff7f 100644 --- a/5/Cargo.lock +++ b/5/Cargo.lock @@ -2,6 +2,105 @@ # 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 = "day5" version = "0.1.0" +dependencies = [ + "itertools", + "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 = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[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" diff --git a/5/Cargo.toml b/5/Cargo.toml index f9b62bf..6e81dde 100644 --- a/5/Cargo.toml +++ b/5/Cargo.toml @@ -6,3 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +itertools = "0.12.0" +rayon = "1.8.0" diff --git a/5/src/main.rs b/5/src/main.rs index 977b59b..cbc1aed 100644 --- a/5/src/main.rs +++ b/5/src/main.rs @@ -2,6 +2,9 @@ use std::fs::File; use std::io::{BufRead, BufReader, Lines}; use std::ops::Range; +use itertools::Itertools; +use rayon::prelude::*; + // --- Day 5: If You Give A Seed A Fertilizer --- // You take the boat and find the gardener right where you were told he would be: @@ -278,7 +281,12 @@ impl Almanac { // What is the lowest location number that corresponds to any of the initial seed numbers? fn problem1_lowest_location(almanac: &Almanac) -> u64 { - almanac.seeds.iter().map(|seed| almanac.lookup(*seed)).min().unwrap() + almanac + .seeds + .iter() + .map(|seed| almanac.lookup(*seed)) + .min() + .unwrap() } fn problem1(input: Lines) -> u64 { @@ -287,15 +295,60 @@ fn problem1(input: Lines) -> u64 { } // PROBLEM 2 solution + +// 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? + +fn problem2_lowest_location(almanac: &Almanac) -> u64 { + let seed_ranges = almanac + .seeds + .iter() + .tuples() + .map(|(range_start, length)| *range_start..*range_start + *length); + + seed_ranges + .map(|range| { + range + .into_par_iter() + .map(|x| almanac.lookup(x)) + .min() + .unwrap() + }) + .min() + .unwrap() +} + fn problem2(input: Lines) -> u64 { - 0 + let almanac = Almanac::from(input); + problem2_lowest_location(&almanac) } #[cfg(test)] mod tests { use std::io::{BufRead, Cursor}; - use crate::{Almanac, AlmanacMapping, problem1_lowest_location}; + use crate::*; const EXAMPLE_ALMANAC: &str = &"seeds: 79 14 55 13 @@ -359,4 +412,11 @@ humidity-to-location map: let a = Almanac::from(c.lines()); assert_eq!(problem1_lowest_location(&a), 35); } + + #[test] + fn test_problem2_example() { + let c = Cursor::new(EXAMPLE_ALMANAC); + let a = Almanac::from(c.lines()); + assert_eq!(problem2_lowest_location(&a), 46); + } }