add day19a
This commit is contained in:
parent
d20bb3f539
commit
a3a7df74b8
4 changed files with 848 additions and 1 deletions
|
@ -1,5 +1,4 @@
|
|||
defmodule AOC.Day18 do
|
||||
# use AOC.Day, day: 18, input: "example"
|
||||
use AOC.Day, day: 18
|
||||
|
||||
def parse_input(lines) do
|
||||
|
|
103
23/elixir/lib/days/day19.ex
Normal file
103
23/elixir/lib/days/day19.ex
Normal file
|
@ -0,0 +1,103 @@
|
|||
defmodule AOC.Day19 do
|
||||
# use AOC.Day, day: 19, input: "example"
|
||||
use AOC.Day, day: 19
|
||||
|
||||
def string_to_action("R"), do: :reject
|
||||
def string_to_action("A"), do: :accept
|
||||
def string_to_action(workflow), do: {:workflow, workflow}
|
||||
|
||||
def parse_input(lines) do
|
||||
[workflows, _, ratings] = Enum.chunk_by(lines, &(&1 == ""))
|
||||
|
||||
workflows =
|
||||
Enum.map(workflows, fn line ->
|
||||
%{"name" => name, "rules" => rules} =
|
||||
Regex.named_captures(~r/^(?<name>[[:alpha:]]+)\{(?<rules>.*)\}$/, line)
|
||||
|
||||
rules =
|
||||
rules
|
||||
|> String.split(",")
|
||||
|> Enum.map(fn rule ->
|
||||
if String.contains?(rule, ":") do
|
||||
{property, rest} = String.split_at(rule, 1)
|
||||
{operation, rest} = String.split_at(rest, 1)
|
||||
[count, action] = String.split(rest, ":")
|
||||
|
||||
action = string_to_action(action)
|
||||
count = String.to_integer(count)
|
||||
|
||||
operation =
|
||||
case operation do
|
||||
"<" -> &Kernel.</2
|
||||
">" -> &Kernel.>/2
|
||||
end
|
||||
|
||||
fn part ->
|
||||
value = Map.fetch!(part, property)
|
||||
|
||||
if operation.(value, count) do
|
||||
action
|
||||
else
|
||||
:continue
|
||||
end
|
||||
end
|
||||
else
|
||||
action = string_to_action(rule)
|
||||
fn _ -> action end
|
||||
end
|
||||
end)
|
||||
|
||||
{name, rules}
|
||||
end)
|
||||
|> Enum.into(%{})
|
||||
|
||||
ratings =
|
||||
Enum.map(ratings, fn line ->
|
||||
line
|
||||
|> String.trim_leading("{")
|
||||
|> String.trim_trailing("}")
|
||||
|> String.split(",")
|
||||
|> Enum.map(fn property ->
|
||||
[name, value] = String.split(property, "=")
|
||||
{name, String.to_integer(value)}
|
||||
end)
|
||||
|> Enum.into(%{})
|
||||
end)
|
||||
|
||||
{workflows, ratings}
|
||||
end
|
||||
|
||||
def perform_workflow([rule | tl], rating) do
|
||||
case rule.(rating) do
|
||||
:continue -> perform_workflow(tl, rating)
|
||||
action -> action
|
||||
end
|
||||
end
|
||||
|
||||
def sort_rating(workflows, rating, current_workflow_name) do
|
||||
workflow = Map.fetch!(workflows, current_workflow_name)
|
||||
|
||||
case perform_workflow(workflow, rating) do
|
||||
{:workflow, next_workflow_name} ->
|
||||
sort_rating(workflows, rating, next_workflow_name)
|
||||
|
||||
action ->
|
||||
action
|
||||
end
|
||||
end
|
||||
|
||||
def part1({workflows, ratings}) do
|
||||
Enum.filter(ratings, fn rating ->
|
||||
sort_rating(workflows, rating, "in") == :accept
|
||||
end)
|
||||
|> Enum.map(fn x ->
|
||||
Enum.map(x, &elem(&1, 1))
|
||||
|> Enum.sum()
|
||||
end)
|
||||
|> Enum.sum()
|
||||
end
|
||||
|
||||
def part2(_input) do
|
||||
"TOD"
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue