implement day 7
This commit is contained in:
parent
b02d56254d
commit
dbd5139991
70
src/day_07/mod.rs
Normal file
70
src/day_07/mod.rs
Normal file
|
@ -0,0 +1,70 @@
|
|||
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);
|
||||
}
|
||||
}
|
4
src/day_07/model.rs
Normal file
4
src/day_07/model.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
pub struct CrabSub {
|
||||
pub location: usize,
|
||||
}
|
35
src/day_07/parsing.rs
Normal file
35
src/day_07/parsing.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use super::CrabSub;
|
||||
use crate::parsing::parse_number;
|
||||
use yap::Tokens;
|
||||
|
||||
pub fn parse_crab_sub(tokens: &mut impl Tokens<Item = char>) -> Option<CrabSub> {
|
||||
parse_number(tokens).map(|num| CrabSub { location: num })
|
||||
}
|
||||
|
||||
pub fn parse_crab_sub_swarm(tokens: &mut impl Tokens<Item = char>) -> Vec<CrabSub> {
|
||||
tokens
|
||||
.sep_by(|t| parse_crab_sub(t), |t| t.token(','))
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::CrabSub;
|
||||
use yap::IntoTokens;
|
||||
|
||||
#[test]
|
||||
fn parse_crab_sub() {
|
||||
assert_eq!(
|
||||
Some(CrabSub { location: 1 }),
|
||||
super::parse_crab_sub(&mut "1".into_tokens())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_crab_sub_swarm() {
|
||||
assert_eq!(
|
||||
10,
|
||||
super::parse_crab_sub_swarm(&mut "16,1,2,0,4,2,7,1,2,14".into_tokens()).len()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -8,5 +8,6 @@ pub mod day_03;
|
|||
pub mod day_04;
|
||||
pub mod day_05;
|
||||
pub mod day_06;
|
||||
pub mod day_07;
|
||||
|
||||
aoc_lib! { year = 2021 }
|
||||
|
|
Loading…
Reference in a new issue