diff --git a/23/elixir/lib/days/day7.ex b/23/elixir/lib/days/day7.ex index e03d7b5..c79b945 100644 --- a/23/elixir/lib/days/day7.ex +++ b/23/elixir/lib/days/day7.ex @@ -45,32 +45,38 @@ defmodule AOC.Day7 do end def best_joker_replacement(hand) do - freqs = Enum.frequencies(hand) - |> Enum.reject(fn {card, _count} -> card == ?J end) + freqs = + Enum.frequencies(hand) + |> Enum.reject(fn {card, _count} -> card == ?J end) 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.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.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) + if length(doubles) == 1 do hd(doubles) |> elem(0) else [{double1, _}, {double2, _}] = doubles + if Map.fetch!(@card_to_power, double1) >= Map.fetch!(@card_to_power, double2) do double1 else double2 end end + true -> freqs |> 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) end) |> hd() @@ -80,36 +86,41 @@ defmodule AOC.Day7 do def find_best_joker_configuration(hand) do freqs = Enum.frequencies(hand) joker_count = Map.get(freqs, ?J, 0) - + case joker_count do - 0 -> hand - 5 -> 'AAAAA' + 0 -> + hand + + 5 -> + ~c"AAAAA" + _ -> joker_replacement = best_joker_replacement(hand) - + replace_jokers(hand, joker_replacement) end end def hand_to_type(hand, joker_rule) do - freqs = hand - |> String.to_charlist() - |> then(fn hand -> - if joker_rule do - find_best_joker_configuration(hand) - else - hand - end - end) - |> Enum.frequencies() - |> Enum.map(fn {_k, v} -> v end) + freqs = + hand + |> String.to_charlist() + |> then(fn hand -> + if joker_rule do + find_best_joker_configuration(hand) + else + hand + end + end) + |> Enum.frequencies() + |> Enum.map(fn {_k, v} -> v end) cond do Enum.member?(freqs, 5) -> :five_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) -> :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 true -> :high_card end diff --git a/23/elixir/lib/days/day8.ex b/23/elixir/lib/days/day8.ex index 9cd8794..2aef73c 100644 --- a/23/elixir/lib/days/day8.ex +++ b/23/elixir/lib/days/day8.ex @@ -9,12 +9,18 @@ defmodule AOC.Day8 do def parse_input([instructions, _ | nodes]) do instructions = instructions |> String.to_charlist() |> Stream.cycle() - nodes = Enum.map(nodes, fn s -> - %{"id" => id, "left" => left, "right" => right} = Regex.named_captures(~r/^(?[[:alnum:]]{3}) = \((?[[:alnum:]]{3}), (?[[:alnum:]]{3})\)$/, s) - {id, {left, right}} - end) - |> Enum.into(%{}) + nodes = + Enum.map(nodes, fn s -> + %{"id" => id, "left" => left, "right" => right} = + Regex.named_captures( + ~r/^(?[[:alnum:]]{3}) = \((?[[:alnum:]]{3}), (?[[:alnum:]]{3})\)$/, + s + ) + + {id, {left, right}} + end) + |> Enum.into(%{}) {instructions, nodes} end @@ -25,10 +31,12 @@ defmodule AOC.Day8 do {:halt, step_count} else {left, right} = Map.fetch!(nodes, current_node) - next_node = case instruction do - ?L -> left - ?R -> right - end + + next_node = + case instruction do + ?L -> left + ?R -> right + end {:cont, {next_node, step_count + 1}} end @@ -40,16 +48,21 @@ defmodule AOC.Day8 do end 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 {:halt, {last_end_count, step_count - last_end_count}} 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) - next_node = case instruction do - ?L -> left - ?R -> right - end + + next_node = + case instruction do + ?L -> left + ?R -> right + end {:cont, {next_node, step_count + 1, last_end_count}} end @@ -57,7 +70,8 @@ defmodule AOC.Day8 do end 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 if all_ended do @@ -72,6 +86,7 @@ defmodule AOC.Day8 do def part2({instructions, nodes}) do IO.puts("Use LCM for the following numbers :)") + 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(&elem(&1, 0))