67 lines
1.3 KiB
Elixir
67 lines
1.3 KiB
Elixir
defmodule Aoc2023.Day7 do
|
|
use Aoc2023
|
|
|
|
def hand_type(values) do
|
|
values
|
|
|> Enum.frequencies()
|
|
|> then(fn freq ->
|
|
{jokers, freq_} = freq |> Map.pop(0, 0)
|
|
common = freq_ |> Enum.max_by(pipe(elem(1)), fn -> {1, nil} end) |> elem(0)
|
|
freq_ |> Map.update(common, jokers, &(&1 + jokers))
|
|
end)
|
|
|> Enum.map(pipe(elem(1)))
|
|
|> Enum.sort(:desc)
|
|
|> case do
|
|
[5] -> 6
|
|
[4, 1] -> 5
|
|
[3, 2] -> 4
|
|
[3, 1, 1] -> 3
|
|
[2, 2, 1] -> 2
|
|
[2, 1, 1, 1] -> 1
|
|
[1, 1, 1, 1, 1] -> 0
|
|
end
|
|
end
|
|
|
|
def parse(input) do
|
|
fn rankings ->
|
|
input
|
|
|> lines
|
|
|> Enum.map(&String.split/1)
|
|
|> Enum.map(fn [hand, bid] ->
|
|
{
|
|
hand |> String.to_charlist() |> Enum.map(&Map.get(rankings, &1)),
|
|
bid |> String.to_integer()
|
|
}
|
|
end)
|
|
|> Enum.sort_by(elem(0) |> hand_type &&& elem(0), :asc)
|
|
|> Enum.with_index(1)
|
|
|> Enum.map(fn {{_, bid}, index} -> bid * index end)
|
|
|> Enum.sum()
|
|
end
|
|
end
|
|
|
|
@ranking [
|
|
?2,
|
|
?3,
|
|
?4,
|
|
?5,
|
|
?6,
|
|
?7,
|
|
?8,
|
|
?9,
|
|
?T,
|
|
?J,
|
|
?Q,
|
|
?K,
|
|
?A,
|
|
] |> Enum.with_index(1) |> Map.new
|
|
|
|
def part1(input) do
|
|
input.(@ranking)
|
|
end
|
|
|
|
def part2(input) do
|
|
input.(@ranking |> Map.put(?J, 0))
|
|
end
|
|
end
|