40 lines
962 B
Elixir
40 lines
962 B
Elixir
defmodule Aoc2023.Day4 do
|
|
use Aoc2023
|
|
|
|
defp numbers(values) do
|
|
values |> String.split() |> Enum.map(&String.to_integer/1) |> MapSet.new()
|
|
end
|
|
|
|
def parse(input) do
|
|
input
|
|
|> lines
|
|
|> Enum.map(
|
|
&Regex.run(~r/Card\s+(?<id>\d+): (?<winning>(\s*\d+)+) \| (?<values>(\s*\d+)+)/, &1,
|
|
capture: ["id", "winning", "values"]
|
|
)
|
|
)
|
|
|> Enum.map(fn [id, winning, values] ->
|
|
{String.to_integer(id),
|
|
MapSet.intersection(numbers(winning), numbers(values)) |> MapSet.size()}
|
|
end)
|
|
end
|
|
|
|
def part1(input) do
|
|
for {_, count} <- input,
|
|
count > 0 do
|
|
2 ** (count - 1)
|
|
end
|
|
|> Enum.sum()
|
|
end
|
|
|
|
def part2(input) do
|
|
for {id, count} <- input,
|
|
id_ <- (id + 1)..(id + count)//1,
|
|
reduce: input |> Enum.map(elem(0) &&& const(1)) |> Enum.into(%{}) do
|
|
acc -> Map.update!(acc, id_, &(&1 + Map.get(acc, id)))
|
|
end
|
|
|> Enum.map(pipe(elem(1)))
|
|
|> Enum.sum()
|
|
end
|
|
end
|