From b750d992613fcb064da809fd591a1b3684e48268 Mon Sep 17 00:00:00 2001 From: Andrew Coleman Date: Tue, 5 Dec 2023 13:01:42 -0500 Subject: [PATCH] naive day5 solution --- 2023/src/day05.rs | 170 ++++++++++++++++++++++++++++++++++++++++++++++ 2023/src/lib.rs | 1 + 2 files changed, 171 insertions(+) create mode 100644 2023/src/day05.rs diff --git a/2023/src/day05.rs b/2023/src/day05.rs new file mode 100644 index 0000000..88e29f9 --- /dev/null +++ b/2023/src/day05.rs @@ -0,0 +1,170 @@ +use aoc_runner_derive::{aoc, aoc_generator}; +use std::ops::RangeInclusive; +use std::str::Lines; + +struct RangeMap { + source: RangeInclusive, + destination: RangeInclusive, +} + +struct Almanac { + seeds: Vec, + seed_to_soil: Vec, + soil_to_fertilizer: Vec, + fertilizer_to_water: Vec, + water_to_light: Vec, + light_to_temperature: Vec, + temperature_to_humidity: Vec, + humidity_to_location: Vec, +} + +fn line_to_triple(input: &str) -> [u64; 3] { + let mut vals: [u64; 3] = [0; 3]; + for (index, i) in input.split(" ").enumerate() { + vals[index] = i.parse::().unwrap(); + } + vals +} + +fn next_rangemap(lines: &mut Lines) -> Vec { + let mut rm: Vec = vec![]; + + while let Some(line) = lines.next() { + if line.is_empty() { + break; + } + let triple = line_to_triple(&line); + rm.push(RangeMap { + source: triple[1]..=(triple[1] + triple[2]), + destination: triple[0]..=(triple[0] + triple[2]), + }); + } + + rm +} + +#[aoc_generator(day5)] +fn parse(input: &str) -> Almanac { + let mut lines = input.lines(); + let seeds = lines.next().unwrap().split(": ").collect::>()[1] + .split(" ") + .map(|s| s.parse::().unwrap()) + .collect(); + lines.next(); + lines.next(); + + let seed_to_soil = next_rangemap(&mut lines); + lines.next(); + let soil_to_fertilizer = next_rangemap(&mut lines); + lines.next(); + let fertilizer_to_water = next_rangemap(&mut lines); + lines.next(); + let water_to_light = next_rangemap(&mut lines); + lines.next(); + let light_to_temperature = next_rangemap(&mut lines); + lines.next(); + let temperature_to_humidity = next_rangemap(&mut lines); + lines.next(); + let humidity_to_location = next_rangemap(&mut lines); + + Almanac { + seeds, + seed_to_soil, + soil_to_fertilizer, + fertilizer_to_water, + water_to_light, + light_to_temperature, + temperature_to_humidity, + humidity_to_location, + } +} + +fn match_to(s: u64, maps: &Vec) -> u64 { + if let Some(rm) = maps.iter().find(|m| m.source.contains(&s)) { + let offset = s - rm.source.start(); + rm.destination.start() + offset + } else { + s + } +} + +fn min_location(seeds: &Vec, input: &Almanac) -> u64 { + let locations = seeds + .iter() + .map(|s| match_to(*s, &input.seed_to_soil)) + .map(|s| match_to(s, &input.soil_to_fertilizer)) + .map(|s| match_to(s, &input.fertilizer_to_water)) + .map(|s| match_to(s, &input.water_to_light)) + .map(|s| match_to(s, &input.light_to_temperature)) + .map(|s| match_to(s, &input.temperature_to_humidity)) + .map(|s| match_to(s, &input.humidity_to_location)) + .collect::>(); + *locations.iter().min().unwrap() +} + +#[aoc(day5, part1)] +fn part1(input: &Almanac) -> u64 { + min_location(&input.seeds, input) +} + +#[aoc(day5, part2, bf)] +fn part2(input: &Almanac) -> u64 { + let mut seeds: Vec = vec![]; + let mut index = 0; + while index < input.seeds.len() { + let start = input.seeds[index]; + let count = input.seeds[index + 1]; + index += 2; + for n in start..(start + count) { + seeds.push(n); + } + } + min_location(&seeds, input) +} + +#[cfg(test)] +mod tests { + use super::*; + + const SAMPLE_DATA: &'static str = r#"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 sample_data() { + let maps = parse(&SAMPLE_DATA); + assert_eq!(part1(&maps), 35); + assert_eq!(part2(&maps), 46); + } +} diff --git a/2023/src/lib.rs b/2023/src/lib.rs index c0e7712..bad81fe 100644 --- a/2023/src/lib.rs +++ b/2023/src/lib.rs @@ -4,5 +4,6 @@ mod day01; mod day02; mod day03; mod day04; +mod day05; aoc_lib! { year = 2023 }