y2015d15 very chaotic code, how to do dynamic, nested loops?

This commit is contained in:
Fabian Schmidt 2024-10-30 16:02:01 +01:00
parent 15be81c564
commit 828566cce3
4 changed files with 223 additions and 0 deletions

View File

@ -0,0 +1,4 @@
Sprinkles: capacity 2, durability 0, flavor -2, texture 0, calories 3
Butterscotch: capacity 0, durability 5, flavor -3, texture 0, calories 3
Chocolate: capacity 0, durability 0, flavor 5, texture -1, calories 8
Candy: capacity 0, durability -1, flavor 0, texture 5, calories 8

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

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

198
y2015/src/days/d15.rs Normal file
View File

@ -0,0 +1,198 @@
use std::ops::Mul;
#[derive(Debug, Clone)]
struct Ingredient {
name: String,
capacity: i64,
durability: i64,
flavor: i64,
texture: i64,
calories: i64,
}
impl Ingredient {
fn score(ingredients: Vec<Self>) -> i64 {
let capacity = ingredients
.iter()
.map(|ingredient| ingredient.capacity)
.sum::<i64>();
let durability = ingredients
.iter()
.map(|ingredient| ingredient.durability)
.sum::<i64>();
let flavor = ingredients
.iter()
.map(|ingredient| ingredient.flavor)
.sum::<i64>();
let texture = ingredients
.iter()
.map(|ingredient| ingredient.texture)
.sum::<i64>();
if capacity < 0 || durability < 0 || flavor < 0 || texture < 0 {
return 0;
}
capacity * durability * flavor * texture
//* (self.calories + other.calories)
}
}
impl PartialOrd for Ingredient {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
fn lt(&self, other: &Self) -> bool {
std::matches!(self.partial_cmp(other), Some(std::cmp::Ordering::Less))
}
fn le(&self, other: &Self) -> bool {
std::matches!(
self.partial_cmp(other),
Some(std::cmp::Ordering::Less | std::cmp::Ordering::Equal)
)
}
fn gt(&self, other: &Self) -> bool {
std::matches!(self.partial_cmp(other), Some(std::cmp::Ordering::Greater))
}
fn ge(&self, other: &Self) -> bool {
std::matches!(
self.partial_cmp(other),
Some(std::cmp::Ordering::Greater | std::cmp::Ordering::Equal)
)
}
}
impl Ord for Ingredient {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
let score = self.capacity + self.durability + self.flavor + self.texture + self.calories;
let other_score =
other.capacity + other.durability + other.flavor + other.texture + other.calories;
score.cmp(&other_score)
}
}
impl PartialEq for Ingredient {
fn eq(&self, other: &Self) -> bool {
self.capacity + self.durability + self.flavor + self.texture + self.calories
== other.capacity + other.durability + other.flavor + other.texture + other.calories
}
}
impl Eq for Ingredient {}
impl Mul<Ingredient> for i64 {
type Output = Ingredient;
fn mul(self, rhs: Ingredient) -> Self::Output {
Ingredient {
name: rhs.name,
capacity: rhs.capacity * self,
durability: rhs.durability * self,
flavor: rhs.flavor * self,
texture: rhs.texture * self,
calories: rhs.calories * self,
}
}
}
impl Mul<i64> for Ingredient {
type Output = Self;
fn mul(self, rhs: i64) -> Self::Output {
Ingredient {
name: self.name,
capacity: self.capacity * rhs,
durability: self.durability * rhs,
flavor: self.flavor * rhs,
texture: self.texture * rhs,
calories: self.calories * rhs,
}
}
}
pub fn process_part1(input: &str) -> i64 {
let mut ingredients = vec![];
input.lines().for_each(|line| {
let (ingredient, props) = line.split_once(": ").unwrap();
let ingredient = ingredient.to_string();
let props = props
.split(", ")
.map(|prop| {
let (_, value) = prop.split_once(" ").unwrap();
value.parse().unwrap()
})
.collect::<Vec<i64>>();
ingredients.push(Ingredient {
name: ingredient,
capacity: props[0],
durability: props[1],
flavor: props[2],
texture: props[3],
calories: props[4],
});
});
let mut biggest_score = 0;
// for test
//for idx1 in 1..=99 {
// for idx2 in 1..=99 {
// if idx1 + idx2 != 100 {
// continue;
// }
// let score = Ingredient::score(vec![idx1 * ingredients[0].clone(), idx2 * ingredients[1].clone()]);
// if score > biggest_score {
// biggest_score = score;
// }
// }
//}
// input has 4 ingredients so 4 nested loops
for idx1 in 1..=99 {
for idx2 in 1..=99 {
for idx3 in 1..=97 {
for idx4 in 1..=97 {
if idx1 + idx2 + idx3 + idx4 != 100 {
continue;
}
let i1 = idx1 * ingredients[0].clone();
let i2 = idx2 * ingredients[1].clone();
let i3 = idx3 * ingredients[2].clone();
let i4 = idx4 * ingredients[3].clone();
// only for part 2
if i1.calories + i2.calories + i3.calories + i4.calories != 500 {
continue;
}
let score = Ingredient::score(vec![i1, i2, i3, i4]);
if score > biggest_score {
biggest_score = score;
}
}
}
}
}
biggest_score
}
pub fn process_part2(input: &str) -> u32 {
0
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &str = "Butterscotch: capacity -1, durability -2, flavor 6, texture 3, calories 8
Cinnamon: capacity 2, durability 3, flavor -2, texture -1, calories 3";
#[test]
fn part1() {
let result = process_part1(INPUT);
assert_eq!(result, 62842880);
}
#[test]
fn part2() {
let result = process_part2(INPUT);
assert_eq!(result, 0);
}
}

View File

@ -4,6 +4,7 @@ pub mod d11;
pub mod d12; pub mod d12;
pub mod d13; pub mod d13;
pub mod d14; pub mod d14;
pub mod d15;
pub mod d2; pub mod d2;
pub mod d3; pub mod d3;
pub mod d4; pub mod d4;