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

Day 13: Transparent Origami

2021/day_13_transparent_origami.livemd

Day 13: Transparent Origami

Mix.install([:kino, :kino_vega_lite])

alias VegaLite, as: Vl

input = Kino.Input.textarea("Please paste your input:")

Setup

[dots_input, folds_input] =
  input
  |> Kino.Input.read()
  |> String.split("\n\n", trim: true)
  |> Enum.map(&String.split(&1, "\n", trim: true))

dots =
  dots_input
  |> Enum.map(fn dots_str ->
    String.split(dots_str, ",")
    |> Enum.map(&String.to_integer/1)
    |> List.to_tuple()
  end)
  |> MapSet.new()

folds =
  folds_input
  |> Enum.map(fn "fold along " <> fold_str ->
    [axis, value_str] = String.split(fold_str, "=")

    [axis, String.to_integer(value_str)]
  end)

{dots, folds}

Part 1

https://adventofcode.com/2021/day/13

Solve: Part 1

defmodule Day13.Part1 do
  def run(dots, folds) do
    do_run(dots, folds)
  end

  defp do_run(dots, []) do
    dots
  end

  defp do_run(dots, [fold | rest_folds]) do
    new_dots =
      dots
      |> Enum.reject(&amp;is_on_line?(&amp;1, fold))
      |> Enum.map(&amp;fold(&amp;1, fold))
      |> MapSet.new()

    do_run(new_dots, rest_folds)
  end

  defp is_on_line?({x, _y}, ["x", x]), do: true
  defp is_on_line?({_x, y}, ["y", y]), do: true
  defp is_on_line?(_dot, _fold), do: false

  defp fold({x, y}, ["x", fold_x]) do
    {fold_x - abs(x - fold_x), y}
  end

  defp fold({x, y}, ["y", fold_y]) do
    {x, fold_y - abs(y - fold_y)}
  end
end

Day13.Part1.run(dots, folds |> Enum.take(1))
|> Enum.count()

Part 2

https://adventofcode.com/2021/day/13#part2

Solve: Part 2

values =
  Day13.Part1.run(dots, folds)
  |> Enum.map(fn {x, y} -> %{"x" => x, "y" => y} end)

Vl.new(width: 800, height: 200)
|> Vl.data_from_values(values)
|> Vl.mark(:rect)
|> Vl.encode_field(:x, "x")
|> Vl.encode_field(:y, "y")
|> Vl.encode(:color, aggregate: :count)
|> Vl.config(view: [stroke: nil])