Advent of Code 2023 - Day 12

Greetings, fantastic coding enthusiasts! Ukrainian Erlanger here :metal:, and it’s a terrific Tuesday. Today marks Day 12 in our riveting exploration of Advent of Code, introducing yet another exciting puzzle to solve. Dive into the challenge and, as always, share your ingenious code solutions in the comments below. Let’s keep the collaborative spirit alive and make this Tuesday a coding triumph! Happy coding, everyone! :blush:

2 Likes

In hindsight it was not that difficult, but it took forever to figure out and implement for some reason:

defmodule Aoc.Twelve do
  def parse(string) do
    string
    |> String.split("\n", trim: true)
    |> Enum.map(&String.split(&1, " ", trim: true))
  end

  defp post_parse(input, duplicates \\ 1) do
    for [seqs0, nums0] <- input do
      seqs =
        seqs0
        |> List.duplicate(duplicates)
        |> Enum.join("?")

      nums =
        nums0
        |> List.duplicate(duplicates)
        |> Enum.join(",")

      {String.split(seqs, ".", trim: true) |> Enum.map(&String.to_charlist/1),
       String.split(nums, ",", trim: true) |> Enum.map(&String.to_integer/1)}
    end
  end

  def part_one(input) do
    input
    |> post_parse()
    |> Enum.map(&fit/1)
    |> Enum.sum()
  end

  def part_two(input) do
    input
    |> post_parse(5)
    |> Enum.map(&fit/1)
    |> Enum.sum()
  end

  defp fit({a, b}) do
    {result, _} = mfit(a, b, %{})
    result
  end

  defp fit(seqs0, nums0, memo) do
    case {seqs0, nums0} do
      {[[?# | _] = s | seqs], [n | nums]} when length(s) >= n ->
        {_, rest} = Enum.split(s, n)

        case rest do
          [] -> mfit(seqs, nums, memo)
          [?# | _] -> {0, memo}
          [??] -> mfit(seqs, nums, memo)
          [?? | r] -> mfit([r | seqs], nums, memo)
        end

      {[[] | seqs], nums} ->
        mfit(seqs, nums, memo)

      {[s | seqs], [n | nums]} when length(s) < n ->
        if any_sharp([s]) do
          {0, memo}
        else
          mfit(seqs, [n | nums], memo)
        end

      {[[?? | rest] | seqs], [_ | _] = nums} ->
        {v1, memo1} = mfit([[?# | rest] | seqs], nums, memo)
        {v2, memo2} = mfit([rest | seqs], nums, memo1)
        {v1 + v2, memo2}

      {[], []} ->
        {1, memo}

      {s, []} ->
        res =
          if any_sharp(s) do
            0
          else
            1
          end

        {res, memo}

      {_, _} ->
        {0, memo}
    end
  end

  defp mfit(a, b, memo) do
    key = {a, b}

    case memo[key] do
      nil ->
        {r, memo1} = fit(a, b, memo)
        {r, Map.put(memo1, key, r)}

      r ->
        {r, memo}
    end
  end

  defp any_sharp(s) do
    Enum.any?(s, &Enum.member?(&1, ?#))
  end
end

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

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