AdventOfCode2023/src/day5.rs
2023-12-18 09:37:35 -05:00

136 lines
3.1 KiB
Rust

use aoc_runner_derive::{aoc, aoc_generator};
#[aoc_generator(day5)]
fn parse(input: &str) -> Vec<Vec<Vec<i64>>> {
let mappers: Vec<Vec<Vec<i64>>> = input.split("\n\n")
.map(|maps| &maps[(maps.find(':').unwrap() + 1)..])
.map(|maps| maps.trim())
.map(|maps| {
maps.split('\n')
.map(|range| {
range.split(' ')
.map(|num| num.parse::<i64>().unwrap())
.collect::<Vec<_>>()
})
.collect::<Vec<_>>()
})
.collect();
mappers
}
#[aoc(day5, part1)]
fn part1(mappers: &Vec<Vec<Vec<i64>>>) -> i64 {
let seeds = mappers.first().unwrap().first().unwrap().clone();
let mut borrow_work_around: Vec<Vec<Vec<i64>>> = Vec::new();
mappers.clone_into(&mut borrow_work_around);
let mappers: &mut [Vec<Vec<i64>>] = &mut borrow_work_around.get_mut(1..).unwrap();
for mapper in mappers.into_iter() {
for range in mapper {
range[2] = range[1] + range[2] - 1;
}
}
let mut cur_vals: Vec<_> = seeds;
for mapper in mappers {
for val in cur_vals.iter_mut() {
for range in mapper.into_iter() {
if range[1] <= *val && *val <= range[2] {
let diff = *val - range[1];
*val = range[0] + diff;
break;
}
}
}
}
cur_vals.into_iter().min().unwrap()
}
#[aoc(day5, part2)]
fn part2(mappers: &Vec<Vec<Vec<i64>>>) -> i64 {
let seeds = mappers.first().unwrap().first().unwrap().clone();
let mut borrow_work_around: Vec<Vec<Vec<i64>>> = Vec::new();
mappers.clone_into(&mut borrow_work_around);
let mappers: &mut [Vec<Vec<i64>>] = &mut borrow_work_around.get_mut(1..).unwrap();
for mapper in mappers.into_iter() {
for range in mapper {
range[2] = range[1] + range[2] - 1;
}
}
let mut cur_vals: Vec<_> = Vec::new();
for i in 0..seeds.len() / 2 {
let end = seeds[i * 2] + seeds[(i * 2) + 1];
let mut range: Vec<_> = (seeds[i * 2]..end).collect();
cur_vals.append(&mut range);
}
println!("{}", cur_vals.len());
for mapper in mappers {
for val in cur_vals.iter_mut() {
println!("{}", val);
for range in mapper.into_iter() {
if range[1] <= *val && *val <= range[2] {
let diff = *val - range[1];
*val = range[0] + diff;
break;
}
}
}
}
cur_vals.into_iter().min().unwrap()
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &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 part1_example() {
assert_eq!(part1(&parse(EX)), 35);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 46);
}
}