Powered by AppSignal & Oban Pro

Advent of Code 2023 - Day 7

2023/day-07.livemd

Advent of Code 2023 - Day 7

Mix.install([
  {:kino_aoc, "~> 0.1.5"}
])

Prep

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2023", "7", System.fetch_env!("LB_AOC_SESSION"))
IO.puts(puzzle_input)
strengths =
  ?2..?9
  |> Map.new(&{&1, &1 - ?0})
  |> Map.merge(%{
    ?T => 10,
    ?J => 11,
    ?Q => 12,
    ?K => 13,
    ?A => 14
  })

Part 1

puzzle_input
|> String.split()
|> Stream.chunk_every(2)
|> Stream.map(fn [hand, bid] ->
  cards = String.to_charlist(hand)
  freqs = cards |> Enum.frequencies() |> Map.values() |> Enum.sort(:desc)
  scores = Enum.map(cards, &strengths[&1])
  {freqs, scores, String.to_integer(bid)}
end)
|> Enum.sort()
|> Stream.map(&elem(&1, 2))
|> Stream.with_index(1)
|> Stream.map(fn {bid, rank} -> bid * rank end)
|> Enum.sum()

Part 2

strengths = %{strengths | ?J => 1}
puzzle_input
|> String.split()
|> Stream.chunk_every(2)
|> Stream.map(fn [hand, bid] ->
  cards = String.to_charlist(hand)
  freqs = cards |> Enum.frequencies()
  {jokers, freqs} = Map.pop(freqs, ?J, 0)
  freqs = freqs |> Map.values() |> Enum.sort(:desc)
  freqs = (freqs == [] && [5]) || [hd(freqs) + jokers | tl(freqs)]
  scores = Enum.map(cards, &strengths[&1])
  {freqs, scores, String.to_integer(bid)}
end)
|> Enum.sort()
|> Stream.map(&elem(&1, 2))
|> Stream.with_index(1)
|> Stream.map(fn {bid, rank} -> bid * rank end)
|> Enum.sum()