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