Skip to content

Instantly share code, notes, and snippets.

@SteffenDE
Created December 15, 2021 18:58
Show Gist options
  • Save SteffenDE/40e98902f544d12137c27ec05b0a5499 to your computer and use it in GitHub Desktop.
Save SteffenDE/40e98902f544d12137c27ec05b0a5499 to your computer and use it in GitHub Desktop.

AoC Day 13 - Transparent Origami

Setup

Mix.install([:kino, :vega_lite])
input = Kino.Input.textarea("Please input data:")
[lines, instructions] =
  input
  |> Kino.Input.read()
  |> String.split("\n\n")
  |> Enum.map(&String.split(&1, "\n"))
coords =
  Enum.map(lines, &String.split(&1, ","))
  |> Enum.map(&Enum.map(&1, fn numbers -> String.to_integer(numbers) end))
  |> Enum.map(fn [x, y] -> {x, y} end)
instructions =
  Enum.map(instructions, fn "fold along " <> instruction ->
    case String.split(instruction, "=") do
      ["x", num] -> {:x, String.to_integer(num)}
      ["y", num] -> {:y, String.to_integer(num)}
    end
  end)

Part 1

defmodule Origami do
  defp do_fold({x, y}, :x, fold_pos), do: {fold_pos - abs(x - fold_pos), y}
  defp do_fold({x, y}, :y, fold_pos), do: {x, fold_pos - abs(y - fold_pos)}

  def fold(grid, {x_or_y, fold_pos}) do
    Enum.map(grid, fn point -> do_fold(point, x_or_y, fold_pos) end)
  end

  def inspect(grid) do
    {max_x, _} = Enum.max_by(grid, fn {x, _y} -> x end)
    {_, max_y} = Enum.max_by(grid, fn {_x, y} -> y end)
    set = MapSet.new(grid)

    for y <- 0..max_y do
      IO.puts(for(x <- 0..max_x, do: if({x, y} in set, do: "#", else: ".")))
    end

    grid
  end

  def count_dots(grid) do
    length(Enum.uniq(grid))
  end
end
instructions
|> Enum.take(1)
|> then(fn [instruction] -> Origami.fold(coords, instruction) end)
|> Origami.count_dots()

Part 2

instructions
|> Enum.reduce(coords, fn instruction, coords ->
  Origami.fold(coords, instruction)
end)
|> Origami.inspect()

VegaLite

https://github.com/miladamilli/Advent_of_Code_2021/blob/master/day13.livemd

alias VegaLite, as: Vl
paper =
  Vl.new(width: 900, height: 150)
  |> Vl.config(view: [stroke: :transparent])
  |> Vl.mark(:square, opacity: 0.4, size: 900)
  |> Vl.encode_field(:x, "x", type: :quantitative, axis: false)
  |> Vl.encode_field(:y, "y", type: :quantitative, axis: false)
  |> Vl.encode_field(:color, "x",
    type: :quantitative,
    scale: [range: ["#27e3c8", "#b25ae7"]],
    legend: false
  )
  |> Kino.VegaLite.new()
  |> Kino.render()

Enum.reduce(instructions, coords, fn instruction, coords ->
  new_dots = Origami.fold(coords, instruction)
  data_to_plot = Enum.map(new_dots, fn {x, y} -> %{"x" => x, "y" => -y} end)
  Kino.VegaLite.clear(paper)
  Kino.VegaLite.push_many(paper, data_to_plot)
  Process.sleep(350)
  new_dots
end)

:ok
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment