advent_of_code/elixir/livebook/2024/day22.livemd

1.7 KiB

AOC 2024 Day 22

[{:kino_benchee, "~> 0.1.0"}] |> Mix.install

Section

input = """
"""

Section

defmodule MonkeyMarket do
  @doc """
  
  ## Example
  iex> MonkeyMarket.part2([1,2,3,2024])
  23
  """
  def part2(input) do
    for m <- (
      for j <- input do
          diffs = MonkeyMarket.next(j, 2000)
          |> Stream.map(&rem(&1, 10))
          |> Enum.reverse()
          |> Stream.chunk_every(2, 1, :discard)
          |> Stream.map(fn [a,b] -> {b, b-a} end)
      
        for [_,_,_,{n,_}] = chunk <- diffs 
          |> Stream.chunk_every(4, 1, :discard),
          chunk = chunk |> Enum.map(&(elem(&1, 1))),
          
          reduce: %{} do
          acc2 ->
            acc2 |> Map.update(chunk, n, &(&1))
          end
      end), reduce: %{} do
      acc -> Map.merge(
        m,
        acc,
        fn _, s1, s2 ->
          s1+s2
        end
      )
    end
    |> Enum.max_by(&elem(&1, 1))
    |> elem(1)
  end
  @doc """

  ## Example
  iex> MonkeyMarket.part1([1,10,100,2024])
  37327623
  """
  def part1(input) do
    input
    |> Stream.map(&hd(MonkeyMarket.next(&1, 2000)))
    |> Enum.sum()
  end
  
  def next(a) do
      a = a |> Bitwise.bsl(6) |> Bitwise.bxor(a) |> Bitwise.band(16777215)
      a = a |> Bitwise.bsr(5) |> Bitwise.bxor(a) |> Bitwise.band(16777215)
      a |> Bitwise.bsl(11) |> Bitwise.bxor(a) |> Bitwise.band(16777215)
  end
  
  def next(a, x) when is_integer(a), do: next([a], x)
  def next(a, 0), do: a
  def next([prev | _ ] = a, n), do: next([next(prev) | a], n - 1)
end
Benchee.run(%{
  part1: fn -> MonkeyMarket.part1(input) end
})

MonkeyMarket.part2(input)