-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathday_15.ex
92 lines (78 loc) · 2.75 KB
/
day_15.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
defmodule AdventOfCode.Y2015.Day15 do
@moduledoc """
--- Day 15: Science for Hungry People ---
Problem Link: https://adventofcode.com/2015/day/15
Difficulty: m
Tags: quadratic-time not-fast-enough sequence needs-improvement
"""
alias AdventOfCode.Helpers.{InputReader, Transformers}
def input, do: InputReader.read_from_file(2015, 15)
def run(input \\ input()) do
input = parse(input)
{run_1(input), run_2(input)}
end
def run_1([sprinkles, peanut_butter, frosting, sugar]) do
for {sprinkles_count, peanut_butter_count, frosting_count, sugar_count} <- get_quadruples() do
{scoring_nutrients, _} =
total_nutrition([
nutrition_value(sprinkles, sprinkles_count),
nutrition_value(peanut_butter, peanut_butter_count),
nutrition_value(frosting, frosting_count),
nutrition_value(sugar, sugar_count)
])
scoring_nutrients |> Enum.product()
end
|> Enum.max()
end
def run_2([sprinkles, peanut_butter, frosting, sugar]) do
for {sprinkles_count, peanut_butter_count, frosting_count, sugar_count} <- get_quadruples() do
{scoring_nutrients, calories} =
total_nutrition([
nutrition_value(sprinkles, sprinkles_count),
nutrition_value(peanut_butter, peanut_butter_count),
nutrition_value(frosting, frosting_count),
nutrition_value(sugar, sugar_count)
])
(calories == 500 && Enum.product(scoring_nutrients)) || nil
end
|> Enum.reject(&is_nil/1)
|> Enum.max()
end
def parse(data) do
data
|> Transformers.lines()
|> Enum.map(&parse_nutrients/1)
end
@regex ~r{(?<name>\w+): capacity (?<capacity>\-?\d+), durability (?<durability>\-?\d+), flavor (?<flavor>\-?\d+), texture (?<texture>\-?\d+), calories (?<calories>\-?\d+)}
defp parse_nutrients(ingredient) do
@regex
|> Regex.named_captures(ingredient)
|> Map.delete("name")
|> Map.new(fn {k, v} -> {String.to_atom(k), String.to_integer(v)} end)
end
defp nutrition_value(nutritions, spoon) do
Map.new(nutritions, fn {k, v} -> {k, v * spoon} end)
end
defp total_nutrition([_, _, _, _] = nutrients) do
capacity = nutrients |> total_of(:capacity)
durability = nutrients |> total_of(:durability)
flavor = nutrients |> total_of(:flavor)
texture = nutrients |> total_of(:texture)
calories = nutrients |> total_of(:calories)
{[capacity, durability, flavor, texture], calories}
end
def total_of(nutrients, type) do
nutrients
|> Enum.sum_by(& &1[type])
|> then(&((&1 < 0 && 0) || &1))
end
defp get_quadruples do
for a <- 0..100,
b <- 0..(100 - a),
c <- 0..(100 - a - b),
d <- 0..(100 - a - b - c),
a + b + c + d == 100 do
{a, b, c, d}
end
end
end