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
use crate::common::parser::parse_lines;
use crate::input::Input;
pub fn solve(input: &mut Input) -> Result<u32, String> {
const TARGET_SIZE: u8 = 150;
let container_sizes = parse_lines::<u8>(input.text)?;
if input.is_part_one() {
let mut answers = vec![0; (TARGET_SIZE + 1) as usize];
answers[0] = 1;
for container_size in container_sizes {
for next_size in (container_size..=TARGET_SIZE).rev() {
answers[next_size as usize] += answers[(next_size - container_size) as usize];
}
}
Ok(answers[TARGET_SIZE as usize])
} else {
let mut all_bits = 0_u32;
for i in 0..container_sizes.len() {
all_bits |= 1 << i;
}
for containers_to_use in 1..=container_sizes.len() {
let mut possible_combinations = 0;
for bit_mask in 1..=all_bits {
if bit_mask.count_ones() == containers_to_use as u32 {
let total_size: u32 = container_sizes
.iter()
.map(|&size| u32::from(size))
.enumerate()
.filter(|&(idx, _size)| ((1 << idx) & bit_mask) > 0)
.map(|(_idx, size)| size)
.sum();
if total_size == u32::from(TARGET_SIZE) {
possible_combinations += 1;
}
}
}
if possible_combinations != 0 {
return Ok(possible_combinations);
}
}
Err("No solution found".to_string())
}
}
#[test]
pub fn tests() {
use crate::input::{test_part_one, test_part_two};
let real_input = include_str!("day17_input.txt");
test_part_one!(real_input => 1304);
test_part_two!(real_input => 18);
}