62 lines
1.6 KiB
Rust
62 lines
1.6 KiB
Rust
use nom::{
|
|
bytes::complete::tag,
|
|
character::complete::{self, newline},
|
|
combinator::map,
|
|
multi::separated_list1,
|
|
sequence::separated_pair,
|
|
IResult,
|
|
};
|
|
|
|
fn parse_input(input: &str) -> IResult<&str, Vec<(u64, u64, u64)>> {
|
|
let (input, dimensions) = separated_list1(
|
|
newline,
|
|
map(
|
|
separated_pair(
|
|
complete::u64,
|
|
tag("x"),
|
|
separated_pair(complete::u64, tag("x"), complete::u64),
|
|
),
|
|
|(x, (y, z))| (x, y, z),
|
|
),
|
|
)(input)?;
|
|
Ok((input, dimensions))
|
|
}
|
|
|
|
fn solve_first(dimensions: &[(u64, u64, u64)]) -> u64 {
|
|
dimensions
|
|
.iter()
|
|
.map(|&(l, w, h)| {
|
|
2 * l * w + 2 * w * h + 2 * l * h + std::cmp::min(l * w, std::cmp::min(w * h, h * l))
|
|
})
|
|
.sum()
|
|
}
|
|
|
|
fn solve_second(dimensions: &[(u64, u64, u64)]) -> u64 {
|
|
dimensions
|
|
.iter()
|
|
.map(|&(l, w, h)| smallest_perimeter(l, w, h) + l * w * h)
|
|
.sum()
|
|
}
|
|
|
|
fn smallest_perimeter(l: u64, w: u64, h: u64) -> u64 {
|
|
(l + w + h - std::cmp::max(l, std::cmp::max(w, h))) * 2
|
|
}
|
|
|
|
fn main() {
|
|
println!("Hello, this is Patrick!");
|
|
|
|
let input_txt = include_str!("../input.txt");
|
|
let (_rest, dimensions) = parse_input(input_txt).unwrap_or(("", vec![]));
|
|
|
|
let first_result = solve_first(&dimensions[..]);
|
|
|
|
println!(
|
|
"The elves will need {} square feet of wrapping paper",
|
|
first_result
|
|
);
|
|
|
|
let second_result = solve_second(&dimensions[..]);
|
|
|
|
println!("The elves will need {} feet of ribbon", second_result);
|
|
}
|