Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

AoC 2022 Day 2 Vizualization

2022/day02/viz.livemd

AoC 2022 Day 2 Vizualization

Install Dependencies

Mix.install([
  {:vega_lite, "~> 0.1.6"},
  {:kino_vega_lite, "~> 0.1.6"}
])

Setup

alias VegaLite, as: Vl
# lol don't judge me
defmodule RPS do
  def get_score_one("A X", score), do: 4 + score
  def get_score_one("A Y", score), do: 8 + score
  def get_score_one("A Z", score), do: 3 + score
  def get_score_one("B X", score), do: 1 + score
  def get_score_one("B Y", score), do: 5 + score
  def get_score_one("B Z", score), do: 9 + score
  def get_score_one("C X", score), do: 7 + score
  def get_score_one("C Y", score), do: 2 + score
  def get_score_one("C Z", score), do: 6 + score

  def get_score_two("A X", score), do: 3 + score
  def get_score_two("A Y", score), do: 4 + score
  def get_score_two("A Z", score), do: 8 + score
  def get_score_two("B X", score), do: 1 + score
  def get_score_two("B Y", score), do: 5 + score
  def get_score_two("B Z", score), do: 9 + score
  def get_score_two("C X", score), do: 2 + score
  def get_score_two("C Y", score), do: 6 + score
  def get_score_two("C Z", score), do: 7 + score

  def get_elf_score_one("A X", score), do: 4 + score
  def get_elf_score_one("A Y", score), do: 1 + score
  def get_elf_score_one("A Z", score), do: 7 + score
  def get_elf_score_one("B X", score), do: 8 + score
  def get_elf_score_one("B Y", score), do: 5 + score
  def get_elf_score_one("B Z", score), do: 2 + score
  def get_elf_score_one("C X", score), do: 3 + score
  def get_elf_score_one("C Y", score), do: 9 + score
  def get_elf_score_one("C Z", score), do: 6 + score

  def get_elf_score_two("A X", score), do: 4 + score
  def get_elf_score_two("A Y", score), do: 7 + score
  def get_elf_score_two("A Z", score), do: 1 + score
  def get_elf_score_two("B X", score), do: 8 + score
  def get_elf_score_two("B Y", score), do: 5 + score
  def get_elf_score_two("B Z", score), do: 2 + score
  def get_elf_score_two("C X", score), do: 9 + score
  def get_elf_score_two("C Y", score), do: 6 + score
  def get_elf_score_two("C Z", score), do: 3 + score
end
defmodule Viz do
  def new do
    Vl.new(width: 500, height: 150)
    |> Vl.encode_field(:x, "Names", type: :nominal, title: " ")
    |> Vl.encode_field(:y, "Scores", type: :quantitative, axis: %{grid: false}, title: " ")
    |> Vl.layers([
      Vl.new()
      |> Vl.mark(:bar, size: 200, opacity: 0.6)
      |> Vl.encode_field(:color, "Names",
        type: :nominal,
        scale: [range: ["red", "green"]],
        legend: false
      ),
      Vl.new()
      |> Vl.mark(:text, dy: 20, color: "white", font_size: 20, baseline: "top")
      |> Vl.encode_field(:text, "Scores", type: :quantitative)
    ])
    |> Kino.VegaLite.new()
    |> Kino.render()
  end

  def run(viz, plays, elf_score_fn, my_score_fn) do
    Enum.reduce(plays, {0, 0, 1}, fn play, {elf, me, iteration} ->
      elf_score = elf_score_fn.(play, elf)
      my_score = my_score_fn.(play, me)

      if rem(iteration, 50) == 0 do
        data_to_plot = [
          %{"Names" => "Elf", "Scores" => elf_score},
          %{"Names" => "Me", "Scores" => my_score}
        ]

        Kino.VegaLite.clear(viz)
        Kino.VegaLite.push_many(viz, data_to_plot)
        Process.sleep(350)
      end

      {elf_score, my_score, iteration + 1}
    end)
  end
end
# Get the plays
plays =
  File.read!("./input.txt")
  |> String.split("\n", trim: true)

Visualize game with first strategy

game_one_viz = Viz.new()
Viz.run(game_one_viz, plays, &RPS.get_elf_score_one/2, &RPS.get_score_one/2)

Visualize game with second strategy

game_two_viz = Viz.new()
Viz.run(game_two_viz, plays, &RPS.get_elf_score_two/2, &RPS.get_score_two/2)