diff --git a/AOC.Test/Test2015.cs b/AOC.Test/Test2015.cs
index eec49db..b8b5dfe 100644
--- a/AOC.Test/Test2015.cs
+++ b/AOC.Test/Test2015.cs
@@ -20,6 +20,7 @@ public class Test2015
[DataRow(typeof(Day12), "111754", "65402")]
[DataRow(typeof(Day13), "733", "725")]
[DataRow(typeof(Day14), "2655", "1059")]
+ [DataRow(typeof(Day15), "222870", "117936")]
public void CheckAllDays(Type dayType, string part1, string part2)
{
Common.CheckDay(dayType, part1, part2);
@@ -37,6 +38,7 @@ public class Test2015
[DataRow(typeof(Day09), "605", "982")]
[DataRow(typeof(Day10), "237746", "3369156")]
[DataRow(typeof(Day13), "330", "286")]
+ [DataRow(typeof(Day15), "62842880", "57600000")]
public void CheckTestInputs(Type dayType, string part1, string part2)
{
Common.CheckDay(dayType, part1, part2, true);
diff --git a/AOC2015/Day15.cs b/AOC2015/Day15.cs
index 9137f02..0608c30 100644
--- a/AOC2015/Day15.cs
+++ b/AOC2015/Day15.cs
@@ -3,13 +3,69 @@ namespace AOC2015;
///
/// Day 15:
///
-public sealed class Day15 : Day
+public sealed partial class Day15 : Day
{
+ [GeneratedRegex(@"-?\d+")]
+ private static partial Regex Digits();
+
+ private record Ingredient(string Name, int Capacity, int Durability, int Flavor, int Texture, int Calories);
+
+ private readonly List _ingredients;
+ private readonly int _best;
+ private readonly int _best500Cals;
+
public Day15() : base(2015, 15, "Science for Hungry People")
{
+ _ingredients = Input.Select(ParseIngredient).ToList();
+
+ var quantities = new int[_ingredients.Count];
+ _best = 0;
+
+ while (true)
+ {
+ for (var i = 0; i < _ingredients.Count; i++)
+ {
+ quantities[i]++;
+ if (quantities[i] > 100)
+ quantities[i] = 0;
+ else break;
+ }
+
+ var quantityApplied = quantities.Take(_ingredients.Count - 1).Sum();
+ if (quantityApplied == 0) break;
+ if (quantityApplied > 100) continue;
+
+ quantities[^1] = 100 - quantityApplied;
+
+ int cap = 0, dur = 0, fla = 0, tex = 0, cal = 0;
+ for (var j = 0; j < _ingredients.Count; j++)
+ {
+ var q = quantities[j];
+ var i = _ingredients[j];
+
+ cap += q * i.Capacity;
+ dur += q * i.Durability;
+ fla += q * i.Flavor;
+ tex += q * i.Texture;
+ cal += q * i.Calories;
+ }
+
+ var total = Math.Max(0, cap) * Math.Max(0, dur) * Math.Max(0, fla) * Math.Max(0, tex);
+
+ if (total > _best) _best = total;
+ if (total > _best500Cals && cal == 500) _best500Cals = total;
+ }
}
- public override object Part1() => "";
+ private static Ingredient ParseIngredient(string line)
+ {
+ var s = line.Split(':');
+ var nums = Digits().Matches(s[1]).Select(match => int.Parse(match.Value)).ToList();
- public override object Part2() => "";
+ return new(s[0], nums[0], nums[1], nums[2], nums[3], nums[4]);
+ }
+
+ public override object Part1() => _best;
+
+ public override object Part2() => _best500Cals;
}
diff --git a/AOC2015/input2015/test15.in b/AOC2015/input2015/test15.in
new file mode 100644
index 0000000..1a7ff25
--- /dev/null
+++ b/AOC2015/input2015/test15.in
@@ -0,0 +1,2 @@
+Butterscotch: capacity -1, durability -2, flavor 6, texture 3, calories 8
+Cinnamon: capacity 2, durability 3, flavor -2, texture -1, calories 3