Powered by AppSignal & Oban Pro

AoC 2016 Day 19

2016/day19.livemd

AoC 2016 Day 19

Setup

example = 5
live = 3_014_387

P1

defmodule P1 do
  def solve(n), do: recur(n, 1, 1)

  defp recur(1, h, _) do
    h
  end

  defp recur(n, h, r) when rem(n, 2) == 1 do
    recur(div(n, 2), h + 2 ** r, r + 1)
  end

  defp recur(n, h, r) when rem(n, 2) == 0 do
    recur(div(n, 2), h, r + 1)
  end
end
P1.solve(live)

P2

defmodule P2 do
  def solve(n) do
    recur(Enum.to_list(1..n), n, 1, div(n, 3), [], [])
  end

  defp recur([a, _], _, _, _, [], []), do: a

  defp recur([h | rest], n, index, threshold, done, gone) when index <= threshold do
    recur(
      rest,
      n - 1,
      index + 1,
      threshold,
      [h | done],
      [index * 2 - 1 + div(n, 2) | gone]
    )
  end

  defp recur(rest, n, index, _threshold, done, gone) do
    recur(
      flush(rest, index, [], Enum.reverse(gone)) ++ Enum.reverse(done),
      n,
      1,
      div(n, 3),
      [],
      []
    )
  end

  defp flush([_h | rest], index, done, [index | gone]) do
    flush(rest, index + 1, done, gone)
  end

  defp flush([h | rest], index, done, gone) do
    flush(rest, index + 1, [h | done], gone)
  end

  defp flush([], _, done, _) do
    Enum.reverse(done)
  end
end
P2.solve(live)