From 828566cce31031b53fc4992db5a13c99285a0540 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Wed, 30 Oct 2024 16:02:01 +0100 Subject: [PATCH] y2015d15 very chaotic code, how to do dynamic, nested loops? --- y2015/resources/15_input.txt | 4 + y2015/src/bin/d15.rs | 20 ++++ y2015/src/days/d15.rs | 198 +++++++++++++++++++++++++++++++++++ y2015/src/days/mod.rs | 1 + 4 files changed, 223 insertions(+) create mode 100644 y2015/resources/15_input.txt create mode 100644 y2015/src/bin/d15.rs create mode 100644 y2015/src/days/d15.rs diff --git a/y2015/resources/15_input.txt b/y2015/resources/15_input.txt new file mode 100644 index 0000000..6f33d01 --- /dev/null +++ b/y2015/resources/15_input.txt @@ -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 diff --git a/y2015/src/bin/d15.rs b/y2015/src/bin/d15.rs new file mode 100644 index 0000000..e8df673 --- /dev/null +++ b/y2015/src/bin/d15.rs @@ -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)); +} diff --git a/y2015/src/days/d15.rs b/y2015/src/days/d15.rs new file mode 100644 index 0000000..9e27d04 --- /dev/null +++ b/y2015/src/days/d15.rs @@ -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) -> i64 { + let capacity = ingredients + .iter() + .map(|ingredient| ingredient.capacity) + .sum::(); + let durability = ingredients + .iter() + .map(|ingredient| ingredient.durability) + .sum::(); + let flavor = ingredients + .iter() + .map(|ingredient| ingredient.flavor) + .sum::(); + let texture = ingredients + .iter() + .map(|ingredient| ingredient.texture) + .sum::(); + 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 { + 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 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 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::>(); + 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); + } +} diff --git a/y2015/src/days/mod.rs b/y2015/src/days/mod.rs index 14333e1..bdf8d7f 100644 --- a/y2015/src/days/mod.rs +++ b/y2015/src/days/mod.rs @@ -4,6 +4,7 @@ pub mod d11; pub mod d12; pub mod d13; pub mod d14; +pub mod d15; pub mod d2; pub mod d3; pub mod d4;