aoc-rs-2021/src/day_07/mod.rs
Jan Christian Grünhage dbd5139991 implement day 7
2021-12-07 10:43:19 +01:00

71 lines
1.7 KiB
Rust

mod model;
mod parsing;
use aoc_runner_derive::{aoc, aoc_generator};
pub use model::CrabSub;
pub use parsing::parse_crab_sub_swarm;
use yap::IntoTokens;
#[aoc_generator(day7)]
pub fn parse_input(input: &str) -> Vec<CrabSub> {
parse_crab_sub_swarm(&mut input.into_tokens())
}
#[aoc(day7, part1)]
pub fn part1(input: &[CrabSub]) -> usize {
solve(input, &|x| x)
}
fn bounds(input: &[CrabSub]) -> (usize, usize) {
let locations: Vec<usize> = input.iter().map(|sub| sub.location).collect();
(
*locations.iter().min().unwrap(),
*locations.iter().max().unwrap(),
)
}
pub fn solve(input: &[CrabSub], fuel_calc: &dyn Fn(usize) -> usize) -> usize {
let mut req_fuel = usize::MAX;
let (min, max) = bounds(input);
for i in min..=max {
let mut new_req_fuel = 0;
for sub in input.iter() {
new_req_fuel += fuel_calc((i as isize - sub.location as isize).abs() as usize);
}
if req_fuel > new_req_fuel {
req_fuel = new_req_fuel;
}
}
req_fuel
}
#[aoc(day7, part2)]
pub fn part2(input: &[CrabSub]) -> usize {
solve(input, &|distance| (1..=distance).sum())
}
#[cfg(test)]
mod test {
const EXAMPLE_INPUT: &str = "16,1,2,0,4,2,7,1,2,14";
const RESULT_PART_1: usize = 37;
const RESULT_PART_2: usize = 168;
#[test]
fn part1_example() {
let result = super::part1(&super::parse_input(EXAMPLE_INPUT));
assert_eq!(result, RESULT_PART_1);
}
#[test]
fn part2_example() {
let result = super::part2(&super::parse_input(EXAMPLE_INPUT));
assert_eq!(result, RESULT_PART_2);
}
#[test]
fn parse_example() {
let example = super::parse_input(EXAMPLE_INPUT);
assert_eq!(example.len(), 10);
}
}