136 lines
3.1 KiB
Rust
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);
|
||
|
}
|
||
|
}
|