Skip to content

Instantly share code, notes, and snippets.

@kerryb
Last active July 16, 2025 11:41
Show Gist options
  • Save kerryb/9bc3192cb38a1148b451f0e65d0709b2 to your computer and use it in GitHub Desktop.
Save kerryb/9bc3192cb38a1148b451f0e65d0709b2 to your computer and use it in GitHub Desktop.
Solver for egg hunt problem

Tesser 4D treasure hunt

From the Polaris easter egg hunt 2025

Section

defmodule Tesser do
  defstruct [:position, :symbols, :treasure_positions]

  def new(symbol),
    do: %__MODULE__{
      position: {0, 0, 0, 0},
      symbols: %{{0, 0, 0, 0} => symbol},
      treasure_positions: []
    }

  def left(tesser, symbols), do: move(tesser, {-1, 0, 0, 0}, symbols)
  def right(tesser, symbols), do: move(tesser, {1, 0, 0, 0}, symbols)
  def up(tesser, symbols), do: move(tesser, {0, -1, 0, 0}, symbols)
  def down(tesser, symbols), do: move(tesser, {0, 1, 0, 0}, symbols)
  def forward(tesser, symbols), do: move(tesser, {0, 0, -1, 0}, symbols)
  def back(tesser, symbols), do: move(tesser, {0, 0, 1, 0}, symbols)
  def kata(tesser, symbols), do: move(tesser, {0, 0, 0, -1}, symbols)
  def ana(tesser, symbols), do: move(tesser, {0, 0, 0, 1}, symbols)

  defp move(tesser, offset, symbols) do
    symbols
    |> Enum.reduce({tesser, tesser.position}, fn symbol, {tesser, position} ->
      position = translate(position, offset)
      {put_symbol(tesser, position, symbol), position}
    end)
    |> elem(0)
    |> Map.put(:position, translate(tesser.position, offset))
  end

  def treasure(tesser) do
    Map.update!(tesser, :treasure_positions, &[tesser.position | &1])
  end

  def locate_treasure(tesser) do
    Enum.map(tesser.treasure_positions, &tesser.symbols[&1])
  end

  defp translate({a, b, c, d}, {aa, bb, cc, dd}) do
    {a + aa, b + bb, c + cc, d + dd}
  end

  defp put_symbol(tesser, _position, nil), do: tesser

  defp put_symbol(tesser, position, symbol) do
    %{tesser | symbols: Map.put(tesser.symbols, position, symbol)}
  end
end
Tesser.new(:rocket)
|> Tesser.forward([:sun, :cup, :probe, :fan])
|> Tesser.right([:helmet, :clock, :head, :flag])
|> Tesser.up([:comet, :bag, :pole, :rock])
|> Tesser.left([:plank, :magnet, :constellation, :shark])
|> Tesser.down([nil, :ship, :pie, :lamp])
|> Tesser.treasure()
|> Tesser.kata([:board, :man, :dice, :sword])
|> Tesser.left([:crown, :arrow, :galaxy, :camera])
|> Tesser.ana([:anchor, :book, :hourglass, :meteor])
|> Tesser.ana([:book, :hourglass, :meteor, :compass])
|> Tesser.right([:poop, :cloud, :globe, :pen])
|> Tesser.kata([])
|> Tesser.down([])
|> Tesser.treasure()
|> Tesser.locate_treasure()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment