y2015d17 + fix some warnings

This commit is contained in:
Fabian Schmidt 2024-11-04 10:16:20 +01:00
parent 7f93abc07d
commit 9438245d84
6 changed files with 155 additions and 17 deletions

View File

@ -0,0 +1,20 @@
11
30
47
31
32
36
3
1
5
3
32
36
15
11
46
26
28
1
19
3

20
y2015/src/bin/d17.rs Normal file
View File

@ -0,0 +1,20 @@
use std::fs;
use y2015::days::d17;
fn main() {
part1();
part2();
}
fn part1() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/17_input.txt")).unwrap();
println!("{}", d17::process_part1(&content, 150));
}
fn part2() {
let root = env!("CARGO_MANIFEST_DIR");
let content = fs::read_to_string(format!("{root}/resources/17_input.txt")).unwrap();
println!("{}", d17::process_part2(&content, 150));
}

View File

@ -173,10 +173,6 @@ pub fn process_part1(input: &str) -> i64 {
biggest_score biggest_score
} }
pub fn process_part2(input: &str) -> u32 {
0
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -59,16 +59,3 @@ pub fn process_part2(input: &str) -> String {
} }
"".to_string() "".to_string()
} }
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &str = "{{EXAMPLE}}";
#[test]
fn part2() {
let result = process_part2(INPUT);
assert_eq!(result, 0);
}
}

113
y2015/src/days/d17.rs Normal file
View File

@ -0,0 +1,113 @@
use std::{error::Error, fmt::Debug};
pub fn process_part1(input: &str, litres: u32) -> u32 {
let containers = input
.lines()
.map(|container| container.parse::<u32>().unwrap())
.collect::<Vec<u32>>();
let mut correct_combinations = Vec::new();
for k in 1..=containers.len() {
let num_combinations = binomial(containers.len(), k);
for i in 1..=num_combinations {
let res = combination(containers.clone(), k, i).unwrap();
if res.iter().sum::<u32>() == litres {
correct_combinations.push(res);
}
}
}
correct_combinations.len() as u32
}
pub fn process_part2(input: &str, litres: u32) -> u32 {
let containers = input
.lines()
.map(|container| container.parse::<u32>().unwrap())
.collect::<Vec<u32>>();
let mut correct_combinations = Vec::new();
for k in 1..=containers.len() {
let num_combinations = binomial(containers.len(), k);
for i in 1..=num_combinations {
let res = combination(containers.clone(), k, i).unwrap();
if res.iter().sum::<u32>() == litres {
correct_combinations.push(res);
}
}
if !correct_combinations.is_empty() {
break;
}
}
correct_combinations.len() as u32
}
fn combination<T: Clone + Debug>(
elements: Vec<T>,
k: usize,
nth: usize,
) -> Result<Vec<T>, Box<dyn Error>> {
let num_elements = elements.len();
let num_combinations = binomial(num_elements, k);
if nth > num_combinations || k > num_elements || nth == 0 || k == 0 {
return Err(Box::from("Out of bounds"));
}
let mut i = 0;
let mut remaining_k = k;
let mut comb = Vec::new();
let mut remainder = nth - 1;
while remaining_k > 0 {
// Count the number of combinations that start with elements[i]
// example with n = 5, k = 2
// nth <= 4 select first
// nth <= 7 select second
// nth <= 9 select third
// nth == 10 select fourth
let count = binomial(num_elements - i - 1, remaining_k - 1);
if remainder < count {
// If the nth combination is within the count, pick this element
comb.push(elements[i].clone());
remaining_k -= 1;
} else {
remainder -= count;
}
i += 1;
}
Ok(comb)
}
fn factorial(num: usize) -> usize {
let mut fact = 1;
for n in 1..=num {
fact *= n;
}
fact
}
fn binomial(n: usize, k: usize) -> usize {
if k > n {
0
} else {
factorial(n) / (factorial(k) * factorial(n - k))
}
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &str = "20
15
10
5
5";
#[test]
fn part1() {
let result = process_part1(INPUT, 25);
assert_eq!(result, 4);
}
#[test]
fn part2() {
let result = process_part2(INPUT, 25);
assert_eq!(result, 3);
}
}

View File

@ -15,3 +15,5 @@ pub mod d8;
pub mod d9; pub mod d9;
pub mod d16; pub mod d16;
pub mod d17;