naive day5 solution
parent
45481154d1
commit
b750d99261
|
@ -0,0 +1,170 @@
|
|||
use aoc_runner_derive::{aoc, aoc_generator};
|
||||
use std::ops::RangeInclusive;
|
||||
use std::str::Lines;
|
||||
|
||||
struct RangeMap {
|
||||
source: RangeInclusive<u64>,
|
||||
destination: RangeInclusive<u64>,
|
||||
}
|
||||
|
||||
struct Almanac {
|
||||
seeds: Vec<u64>,
|
||||
seed_to_soil: Vec<RangeMap>,
|
||||
soil_to_fertilizer: Vec<RangeMap>,
|
||||
fertilizer_to_water: Vec<RangeMap>,
|
||||
water_to_light: Vec<RangeMap>,
|
||||
light_to_temperature: Vec<RangeMap>,
|
||||
temperature_to_humidity: Vec<RangeMap>,
|
||||
humidity_to_location: Vec<RangeMap>,
|
||||
}
|
||||
|
||||
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::<u64>().unwrap();
|
||||
}
|
||||
vals
|
||||
}
|
||||
|
||||
fn next_rangemap(lines: &mut Lines) -> Vec<RangeMap> {
|
||||
let mut rm: Vec<RangeMap> = 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::<Vec<&str>>()[1]
|
||||
.split(" ")
|
||||
.map(|s| s.parse::<u64>().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<RangeMap>) -> 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<u64>, 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::<Vec<u64>>();
|
||||
*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<u64> = 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);
|
||||
}
|
||||
}
|
|
@ -4,5 +4,6 @@ mod day01;
|
|||
mod day02;
|
||||
mod day03;
|
||||
mod day04;
|
||||
mod day05;
|
||||
|
||||
aoc_lib! { year = 2023 }
|
||||
|
|
Loading…
Reference in New Issue