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)
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()
instructions
|> Enum.reduce(coords, fn instruction, coords ->
Origami.fold(coords, instruction)
end)
|> Origami.inspect()
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