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}")