Powered by AppSignal & Oban Pro

Advent of Code 2015 Day 25

livebooks/aoc/2015/2015_day25.livemd

Advent of Code 2015 Day 25

Mix.install([
  {:kino_aoc, "~> 0.1"}
])

Get Inputs

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2015", "25", System.fetch_env!("LB_SESSION"))

My answer

get_index = fn r, c ->
  k = r + c - 1
  div(k * (k - 1), 2) + c
end
get_index.(3, 2)
defmodule WeatherMachine do
  @initial 20_151_125
  @modulo 33_554_393
  @multiplier 252_533

  def get(r, c) do
    generate(get_index(r, c) - 1)
  end

  defp get_index(r, c) do
    k = r + c - 1
    div(k * (k - 1), 2) + c
  end

  defp generate(n) do
    power = mod_exp(@multiplier, n, @modulo)
    rem(@initial * power, @modulo)
  end

  defp mod_exp(_, 0, _), do: 1

  defp mod_exp(base, exp, mod) do
    if rem(exp, 2) == 0 do
      half = mod_exp(base, div(exp, 2), mod)
      rem(half * half, mod)
    else
      rem(base * mod_exp(base, exp - 1, mod), mod)
    end
  end
end
WeatherMachine.get(3, 1)
WeatherMachine.get(2947, 3029)