2015: day02: finish

This commit is contained in:
Antoine Martin 2019-12-02 16:59:09 +01:00
parent 5bee7a0ce7
commit ca1952819f
4 changed files with 1132 additions and 1 deletions

1000
aoc2015/input/day02.txt Normal file

File diff suppressed because it is too large Load diff

129
aoc2015/src/day02.rs Normal file
View file

@ -0,0 +1,129 @@
use std::error::Error;
use std::str::FromStr;
use aoc::err;
use aoc::Result;
const INPUT: &str = include_str!("../input/day02.txt");
pub fn run() -> Result<()> {
let presents: Vec<Present> = INPUT
.lines()
.map(|line| line.parse())
.collect::<Result<_>>()?;
println!("part 1: {}", part1(&presents));
println!("part 2: {}", part2(&presents));
Ok(())
}
fn wrapping_paper(present: &Present) -> u64 {
let faces_surfaces = &[
present.length * present.width,
present.width * present.height,
present.height * present.length,
];
let total_area: u64 = faces_surfaces.iter().map(|face| face * 2).sum();
total_area + faces_surfaces.iter().min().unwrap()
}
fn part1(presents: &[Present]) -> u64 {
presents.iter().map(|p| wrapping_paper(p)).sum()
}
fn ribbon_bow_length(present: &Present) -> u64 {
present.length * present.width * present.height
}
fn ribbon_needed(present: &Present) -> u64 {
let faces_perimeters = &[
2 * present.length + 2 * present.width,
2 * present.width + 2 * present.height,
2 * present.height + 2 * present.length,
];
let smallest_perimeter = faces_perimeters.iter().min().unwrap();
smallest_perimeter + ribbon_bow_length(present)
}
fn part2(presents: &[Present]) -> u64 {
presents.iter().map(|p| ribbon_needed(p)).sum()
}
struct Present {
length: u64,
width: u64,
height: u64,
}
impl FromStr for Present {
type Err = Box<dyn Error>;
fn from_str(s: &str) -> Result<Self> {
let x = s
.find('x')
.ok_or_else(|| err!("couldn't find first `x` in {}", s))?;
let length = s[..x].parse()?;
let s = &s[(x + 1)..];
let x = s
.find('x')
.ok_or_else(|| err!("couldn't find second `x` in {}", s))?;
let width = s[..x].parse()?;
let s = &s[(x + 1)..].trim_end();
let height = s.parse()?;
Ok(Present {
length,
width,
height,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1_provided() {
assert_eq!(wrapping_paper(&"2x3x4".parse().unwrap()), 58);
assert_eq!(wrapping_paper(&"1x1x10".parse().unwrap()), 43);
}
#[test]
fn part1_real() {
let presents: Vec<Present> = INPUT
.lines()
.map(|line| line.parse())
.collect::<Result<_>>()
.unwrap();
assert_eq!(part1(&presents), 1598415);
}
#[test]
fn part2_provided() {
assert_eq!(ribbon_needed(&"2x3x4".parse().unwrap()), 34);
assert_eq!(ribbon_needed(&"1x1x10".parse().unwrap()), 14);
}
#[test]
fn part2_real() {
let presents: Vec<Present> = INPUT
.lines()
.map(|line| line.parse())
.collect::<Result<_>>()
.unwrap();
assert_eq!(part2(&presents), 3812909);
}
}

View file

@ -1 +1,2 @@
pub mod day01;
pub mod day02;

View file

@ -1,9 +1,10 @@
use aoc::Result;
use aoc2015::day01;
use aoc2015::day02;
fn main() -> Result<()> {
let days: &[fn() -> Result<()>] = &[day01::run];
let days: &[fn() -> Result<()>] = &[day01::run, day02::run];
aoc::run(days)
}