1use std::array::from_fn;
9
10use crate::util::iter::*;
11use crate::util::parse::*;
12
13type Ingredient = [i32; 5];
14type Input = (i32, i32);
15
16pub fn parse(input: &str) -> Input {
17 let recipe: Vec<Ingredient> = input.iter_signed().chunk::<5>().collect();
18 let mut part_one = 0;
19 let mut part_two = 0;
20
21 for a in 0..101 {
22 let first: Ingredient = from_fn(|i| a * recipe[0][i]);
23
24 for b in 0..(101 - a) {
25 let second: Ingredient = from_fn(|i| first[i] + b * recipe[1][i]);
26
27 if second
30 .iter()
31 .zip(recipe[2])
32 .zip(recipe[3])
33 .take(4)
34 .any(|((x, y), z)| x + y.max(z) * (100 - a - b) <= 0)
35 {
36 continue;
37 }
38
39 for c in 0..(101 - a - b) {
40 let d = 100 - a - b - c;
41 let third: Ingredient = from_fn(|i| second[i] + c * recipe[2][i]);
42 let fourth: Ingredient = from_fn(|i| third[i] + d * recipe[3][i]);
43
44 let score = fourth[..4].iter().map(|&x| x.max(0)).product();
45 let calories = fourth[4];
46
47 part_one = part_one.max(score);
48 if calories == 500 {
49 part_two = part_two.max(score);
50 }
51 }
52 }
53 }
54
55 (part_one, part_two)
56}
57
58pub fn part1(input: &Input) -> i32 {
59 input.0
60}
61
62pub fn part2(input: &Input) -> i32 {
63 input.1
64}