Advent of Code 2023 - Day 7

Greetings, everyone! It’s Ukrainian Erlanger :metal:, and I’m thrilled to be with you on this exciting coding journey! Today marks Day 7 of the thrilling Advent of Code, bringing a fresh puzzle for us to unravel. Remember, sharing is caring - don’t forget to showcase your amazing code solutions in the comments below! Wishing you all a fantastic Thursday filled with coding adventures. Happy coding, folks! :blush:

2 Likes

My day 7 solution:

defmodule Aoc.Seven do
  def parse(string) do
    string
    |> String.split("\n", trim: true)
    |> Enum.map(fn line ->
      line
      |> String.split(" ", trim: true)
      |> then(fn [hand, bet] -> {String.to_charlist(hand), String.to_integer(bet)} end)
    end)
  end

  def part_one(input) do
    input
    |> hand_values(false)
  end

  def part_two(input) do
    input
    |> hand_values(true)
  end

  def hand_values(hands, add_joker?) do
    hands
    |> Enum.sort_by(&hand_type(&1, add_joker?))
    |> Enum.with_index(1)
    |> Enum.map(fn {{_hand, bet}, index} -> bet * index end)
    |> Enum.sum()
  end

  @order %{false: ~c"23456789TJQKA", true: ~c"J23456789TQKA"}

  def hand_type({hand, _bet}, add_joker?) do
    type =
      hand
      |> Enum.frequencies()
      |> maybe_add_joker(add_joker?)
      |> Map.values()
      |> Enum.sort()
      |> case do
        [1, 1, 1, 1, 1] -> 1
        [1, 1, 1, 2] -> 2
        [1, 2, 2] -> 3
        [1, 1, 3] -> 4
        [2, 3] -> 5
        [1, 4] -> 6
        [5] -> 7
      end

    order = Enum.map(hand, fn char -> Enum.find_index(@order[add_joker?], &(&1 == char)) end)

    {type, order}
  end

  def maybe_add_joker(map, add_joker?) when add_joker? and map_size(map) > 1 do
    {n, new_map} = Map.pop(map, ?J, 0)
    {max_k, max_v} = Enum.max_by(new_map, &elem(&1, 1))
    Map.put(new_map, max_k, max_v + n)
  end

  def maybe_add_joker(map, _), do: map
end

input = File.read!("priv/7.txt") |> Aoc.Seven.parse()

input |> Aoc.Seven.part_one() |> IO.inspect(label: "part 1")
input |> Aoc.Seven.part_two() |> IO.inspect(label: "part 2")
1 Like
1 Like