summaryrefslogblamecommitdiffstats
path: root/src/day11.exs
blob: b5d31ba170e0a4549dfbc78ed2a75e86d3547214 (plain) (tree)































































                                                           
defmodule Day11 do
  def part1(data) do
    parse_and_solve(data, 25)
  end

  def part2(data) do
    parse_and_solve(data, 75)
  end

  defp parse_and_solve(data, count) do
    data
    |> String.split([" ", "\n"], trim: true)
    |> Enum.map(&String.to_integer/1)
    |> solve(count)
    |> elem(0)
  end

  defp solve(nums, rem, cache \\ %{})

  defp solve(nums, 0, cache), do: {Enum.count(nums), cache}

  defp solve([h], rem, cache) do
    key = {h, rem}
    case Map.fetch(cache, key) do
      {_, res} ->
        {res, cache}
      :error ->
        nxt =
          if h == 0 do
            [1]
          else
            digits = Integer.digits(h)
            c = Enum.count(digits)
            if rem(c, 2) == 0 do
              {a, b} = Enum.split(digits, div(c, 2))
              a = Integer.undigits(a)
              b = Integer.undigits(b)
              [a, b]
            else
              [h*2024]
            end
          end
        {res, cache} = solve(nxt, rem-1, cache)
        cache = Map.put(cache, key, res)
        {res, cache}
    end
  end

  defp solve([h | t], rem, cache) do
    {c1, cache} = solve([h], rem, cache)
    {c2, cache} = solve(t, rem, cache)
    {c1 + c2, cache}
  end
end

data = IO.read(:stdio, :eof)

{time1 , ans1} = :timer.tc(fn -> Day11.part1(data) end)
IO.puts("Time  : #{time1 / 1000000}")
IO.puts("Answer: #{ans1}")

{time2 , ans2} = :timer.tc(fn -> Day11.part2(data) end)
IO.puts("Time  : #{time2 / 1000000}")
IO.puts("Answer: #{ans2}")