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(&is_on_line?(&1, fold))
|> Enum.map(&fold(&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])