format elixir code

This commit is contained in:
Pim Kunis 2023-12-08 10:02:14 +01:00
parent 9504b4ecab
commit 71cca82ce0
2 changed files with 64 additions and 38 deletions

View file

@ -45,32 +45,38 @@ defmodule AOC.Day7 do
end end
def best_joker_replacement(hand) do def best_joker_replacement(hand) do
freqs = Enum.frequencies(hand) freqs =
|> Enum.reject(fn {card, _count} -> card == ?J end) Enum.frequencies(hand)
|> Enum.reject(fn {card, _count} -> card == ?J end)
cond do cond do
Enum.any?(freqs, fn {_card, count} -> count == 4 end) -> Enum.any?(freqs, fn {_card, count} -> count == 4 end) ->
{card, _} = Enum.find(freqs, fn {_card, count} -> count == 4 end) {card, _} = Enum.find(freqs, fn {_card, count} -> count == 4 end)
card card
Enum.any?(freqs, fn {_card, count} -> count == 3 end) ->
Enum.any?(freqs, fn {_card, count} -> count == 3 end) ->
{card, _} = Enum.find(freqs, fn {_card, count} -> count == 3 end) {card, _} = Enum.find(freqs, fn {_card, count} -> count == 3 end)
card card
Enum.any?(freqs, fn {_card, count} -> count == 2 end) ->
Enum.any?(freqs, fn {_card, count} -> count == 2 end) ->
doubles = Enum.filter(freqs, fn {_card, count} -> count == 2 end) doubles = Enum.filter(freqs, fn {_card, count} -> count == 2 end)
if length(doubles) == 1 do if length(doubles) == 1 do
hd(doubles) |> elem(0) hd(doubles) |> elem(0)
else else
[{double1, _}, {double2, _}] = doubles [{double1, _}, {double2, _}] = doubles
if Map.fetch!(@card_to_power, double1) >= Map.fetch!(@card_to_power, double2) do if Map.fetch!(@card_to_power, double1) >= Map.fetch!(@card_to_power, double2) do
double1 double1
else else
double2 double2
end end
end end
true -> true ->
freqs freqs
|> Enum.map(fn {card, _count} -> card end) |> Enum.map(fn {card, _count} -> card end)
|> Enum.sort(fn card1, card2 -> |> Enum.sort(fn card1, card2 ->
Map.fetch!(@card_to_power, card1) >= Map.fetch!(@card_to_power, card2) Map.fetch!(@card_to_power, card1) >= Map.fetch!(@card_to_power, card2)
end) end)
|> hd() |> hd()
@ -80,36 +86,41 @@ defmodule AOC.Day7 do
def find_best_joker_configuration(hand) do def find_best_joker_configuration(hand) do
freqs = Enum.frequencies(hand) freqs = Enum.frequencies(hand)
joker_count = Map.get(freqs, ?J, 0) joker_count = Map.get(freqs, ?J, 0)
case joker_count do case joker_count do
0 -> hand 0 ->
5 -> 'AAAAA' hand
5 ->
~c"AAAAA"
_ -> _ ->
joker_replacement = best_joker_replacement(hand) joker_replacement = best_joker_replacement(hand)
replace_jokers(hand, joker_replacement) replace_jokers(hand, joker_replacement)
end end
end end
def hand_to_type(hand, joker_rule) do def hand_to_type(hand, joker_rule) do
freqs = hand freqs =
|> String.to_charlist() hand
|> then(fn hand -> |> String.to_charlist()
if joker_rule do |> then(fn hand ->
find_best_joker_configuration(hand) if joker_rule do
else find_best_joker_configuration(hand)
hand else
end hand
end) end
|> Enum.frequencies() end)
|> Enum.map(fn {_k, v} -> v end) |> Enum.frequencies()
|> Enum.map(fn {_k, v} -> v end)
cond do cond do
Enum.member?(freqs, 5) -> :five_of_a_kind Enum.member?(freqs, 5) -> :five_of_a_kind
Enum.member?(freqs, 4) -> :four_of_a_kind Enum.member?(freqs, 4) -> :four_of_a_kind
Enum.member?(freqs, 3) and Enum.member?(freqs, 2) -> :full_house Enum.member?(freqs, 3) and Enum.member?(freqs, 2) -> :full_house
Enum.member?(freqs, 3) -> :three_of_a_kind Enum.member?(freqs, 3) -> :three_of_a_kind
Enum.count(freqs, & &1==2) == 2 -> :two_pair Enum.count(freqs, &(&1 == 2)) == 2 -> :two_pair
Enum.member?(freqs, 2) -> :one_pair Enum.member?(freqs, 2) -> :one_pair
true -> :high_card true -> :high_card
end end

View file

@ -9,12 +9,18 @@ defmodule AOC.Day8 do
def parse_input([instructions, _ | nodes]) do def parse_input([instructions, _ | nodes]) do
instructions = instructions |> String.to_charlist() |> Stream.cycle() instructions = instructions |> String.to_charlist() |> Stream.cycle()
nodes = Enum.map(nodes, fn s ->
%{"id" => id, "left" => left, "right" => right} = Regex.named_captures(~r/^(?<id>[[:alnum:]]{3}) = \((?<left>[[:alnum:]]{3}), (?<right>[[:alnum:]]{3})\)$/, s)
{id, {left, right}} nodes =
end) Enum.map(nodes, fn s ->
|> Enum.into(%{}) %{"id" => id, "left" => left, "right" => right} =
Regex.named_captures(
~r/^(?<id>[[:alnum:]]{3}) = \((?<left>[[:alnum:]]{3}), (?<right>[[:alnum:]]{3})\)$/,
s
)
{id, {left, right}}
end)
|> Enum.into(%{})
{instructions, nodes} {instructions, nodes}
end end
@ -25,10 +31,12 @@ defmodule AOC.Day8 do
{:halt, step_count} {:halt, step_count}
else else
{left, right} = Map.fetch!(nodes, current_node) {left, right} = Map.fetch!(nodes, current_node)
next_node = case instruction do
?L -> left next_node =
?R -> right case instruction do
end ?L -> left
?R -> right
end
{:cont, {next_node, step_count + 1}} {:cont, {next_node, step_count + 1}}
end end
@ -40,16 +48,21 @@ defmodule AOC.Day8 do
end end
def find_cycle(instructions, nodes, start) do def find_cycle(instructions, nodes, start) do
Enum.reduce_while(instructions, {start, 0, nil}, fn instruction, {current_node, step_count, last_end_count}-> Enum.reduce_while(instructions, {start, 0, nil}, fn instruction,
{current_node, step_count, last_end_count} ->
if String.ends_with?(current_node, "Z") and last_end_count != nil do if String.ends_with?(current_node, "Z") and last_end_count != nil do
{:halt, {last_end_count, step_count - last_end_count}} {:halt, {last_end_count, step_count - last_end_count}}
else else
last_end_count = if String.ends_with?(current_node, "Z"), do: step_count, else: last_end_count last_end_count =
if String.ends_with?(current_node, "Z"), do: step_count, else: last_end_count
{left, right} = Map.fetch!(nodes, current_node) {left, right} = Map.fetch!(nodes, current_node)
next_node = case instruction do
?L -> left next_node =
?R -> right case instruction do
end ?L -> left
?R -> right
end
{:cont, {next_node, step_count + 1, last_end_count}} {:cont, {next_node, step_count + 1, last_end_count}}
end end
@ -57,7 +70,8 @@ defmodule AOC.Day8 do
end end
def brute_force_find_cycle(cycles) do def brute_force_find_cycle(cycles) do
Stream.repeatedly(fn -> nil end) |> Enum.reduce_while(cycles, fn _, cycles -> Stream.repeatedly(fn -> nil end)
|> Enum.reduce_while(cycles, fn _, cycles ->
all_ended = cycles |> Enum.map(&elem(&1, 0)) |> Enum.uniq() |> length() == 1 all_ended = cycles |> Enum.map(&elem(&1, 0)) |> Enum.uniq() |> length() == 1
if all_ended do if all_ended do
@ -72,6 +86,7 @@ defmodule AOC.Day8 do
def part2({instructions, nodes}) do def part2({instructions, nodes}) do
IO.puts("Use LCM for the following numbers :)") IO.puts("Use LCM for the following numbers :)")
Enum.filter(nodes, fn {k, _v} -> String.ends_with?(k, "A") end) Enum.filter(nodes, fn {k, _v} -> String.ends_with?(k, "A") end)
|> Enum.map(fn {k, _v} -> find_cycle(instructions, nodes, k) end) |> Enum.map(fn {k, _v} -> find_cycle(instructions, nodes, k) end)
|> Enum.map(&elem(&1, 0)) |> Enum.map(&elem(&1, 0))