— Day 13: Transparent Origami —
Setup
defmodule Setup do
def get_input(prompt) do
case IO.gets(prompt) do
:eof -> ""
line -> line <> get_input(prompt)
end
end
def parse(binary) do
[dots, folds] = binary |> String.split("\n\n")
{parse_dots(dots), parse_folds(folds)}
end
defp parse_dots(binary) do
binary
|> String.split([",", "\n"], trim: true)
|> Enum.chunk_every(2)
|> MapSet.new(fn [x, y] ->
{String.to_integer(x), String.to_integer(y)}
end)
end
defp parse_folds(binary) do
binary
|> String.split("\n", trim: true)
|> Enum.map(&parse_fold/1)
end
defp parse_fold("fold along x=" <> x), do: {:x, String.to_integer(x)}
defp parse_fold("fold along y=" <> y), do: {:y, String.to_integer(y)}
end
defmodule Manual do
def fold({:y, fold}, dots) do
for {x, y} <- dots, reduce: MapSet.new() do
acc ->
cond do
y < fold ->
MapSet.put(acc, {x, y})
y == fold ->
acc
y > fold ->
MapSet.put(acc, {x, fold - y + fold})
end
end
end
def fold({:x, fold}, dots) do
for {x, y} <- dots, reduce: MapSet.new() do
acc ->
cond do
x < fold ->
MapSet.put(acc, {x, y})
x == fold ->
acc
x > fold ->
MapSet.put(acc, {fold - x + fold, y})
end
end
end
end
Part1
Setup.get_input("input")
|> Setup.parse()
|> then(fn {dots, [fold | _folds]} ->
Manual.fold(fold, dots)
end)
|> Enum.count()
Part2
Setup.get_input("input")
|> Setup.parse()
|> then(fn {dots, folds} ->
Enum.reduce(folds, dots, &Manual.fold/2)
end)
|> then(fn dots ->
dots
|> Enum.unzip()
|> Tuple.to_list()
|> Enum.map(&Enum.max/1)
|> then(fn [max_x, max_y] ->
Enum.map(0..max_y, fn y ->
Enum.map(0..max_x, fn x ->
if {x, y} in dots, do: "#", else: " "
end)
|> Enum.join()
end)
end)
end)
|> Enum.join("\n")
|> IO.puts()