1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
/* Copyright 2023 Mario Finelli
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//! Advent of Code 2015 Day 17: <https://adventofcode.com/2015/day/17>
//!
//! A very easy challenge today that amounts to using all of the combinations
//! of containers that we can use and seeing if we can use that combination to
//! transport the desired number of liters of eggnog.
use itertools::Itertools;
/// The solution for the day seventeen challenge.
///
/// We take the usual input as a string. The second argument is for the number
/// of liters that we want to transport. The third argument is for the part of
/// the problem that we want to solve (part `1` for the total number of
/// possible combinations and part `2` for the number of combinations using the
/// fewest number of containers). We start by parsing the input to create a
/// vector of integers representing the capacity of each container. Then we
/// find all of the possible combinations using from one to the total number
/// of containers that we have. For each combination we check to see if it adds
/// up to the correct number of liters. If it does then we increment our
/// counter. If we're on part two as soon as we have a non-zero number of
/// combinations we can return the answer because we take combinations from
/// one to number of containers and the prompt only asks how many combinations
/// are possible using the fewest number of containers.
///
/// # Example
/// ```rust
/// # use aoc::y15d17::y15d17;
/// // probably read this from the input file...
/// let input = "2\n3\n4\n5\n6\n7\n8\n9";
/// assert_eq!(y15d17(input, 10, 1), 4);
/// assert_eq!(y15d17(input, 10, 2), 3);
/// ```
pub fn y15d17(input: &str, liters: u32, part: u32) -> u32 {
let lines: Vec<_> = input.lines().collect();
let mut containers: Vec<u32> = Vec::new();
let mut total = 0;
for line in lines {
containers.push(line.parse().unwrap());
}
for i in 1..containers.len() {
let mut combinations = 0;
for combination in containers.iter().combinations(i) {
if combination.into_iter().sum::<u32>() == liters {
combinations += 1;
}
}
if part == 2 && combinations != 0 {
return combinations;
}
total += combinations;
}
total
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
#[test]
fn it_works() {
let input = "20\n15\n10\n5\n5\n";
assert_eq!(y15d17(input, 25, 1), 4);
assert_eq!(y15d17(input, 25, 2), 3);
}
#[test]
fn the_solution() {
let contents = fs::read_to_string("input/2015/day17.txt").unwrap();
assert_eq!(y15d17(&contents, 150, 1), 1638);
assert_eq!(y15d17(&contents, 150, 2), 17);
}
}