Skip to content

Instantly share code, notes, and snippets.

@al2o3cr
Created December 27, 2022 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save al2o3cr/2062ecf2cc11648f88832c5c4b3c2a22 to your computer and use it in GitHub Desktop.
Save al2o3cr/2062ecf2cc11648f88832c5c4b3c2a22 to your computer and use it in GitHub Desktop.
2022 AOC Day 16
defmodule WarmJets do
def start(filename) do
Agent.start(__MODULE__, :init, [filename], name: __MODULE__)
end
def init(filename) do
File.read!(filename)
|> String.trim()
|> String.split("", trim: true)
|> Enum.map(&to_direction/1)
|> :queue.from_list()
end
defp to_direction("<"), do: :left
defp to_direction(">"), do: :right
def next do
Agent.get_and_update(__MODULE__, &rotate/1)
end
defp rotate(queue) do
{{:value, result}, queue} = :queue.out(queue)
{result, :queue.in(result, queue)}
end
end
defmodule Shape do
def all, do: Stream.cycle([wide(), plus(), ell(), tall(), square()])
defp wide, do: [{0, 0}, {1, 0}, {2, 0}, {3, 0}]
defp plus, do: [{0, 1}, {1, 0}, {1, 1}, {1, 2}, {2, 1}]
defp ell, do: [{0, 0}, {1, 0}, {2, 0}, {2, 1}, {2, 2}]
defp tall, do: [{0, 0}, {0, 1}, {0, 2}, {0, 3}]
defp square, do: [{0, 0}, {0, 1}, {1, 0}, {1, 1}]
def start_at(shape, y), do: Enum.map(shape, &add(&1, {2, y}))
def move(shape, :down), do: Enum.map(shape, &add(&1, {0, -1}))
def move(shape, :left), do: Enum.map(shape, &add(&1, {-1, 0}))
def move(shape, :right), do: Enum.map(shape, &add(&1, {1, 0}))
defp add({x, y}, {dx, dy}), do: {x + dx, y + dy}
end
defmodule Chamber do
@max_x 6
def init do
:ets.new(__MODULE__, [:ordered_set, :named_table])
Enum.each(0..@max_x, fn x ->
:ets.insert(__MODULE__, {{x, 0}, :floor})
end)
end
def highest_y do
0..@max_x
|> Enum.map(fn x ->
{^x, result} = :ets.prev(__MODULE__, {x+1, -1})
result
end)
|> Enum.max()
end
def open?(shape) do
Enum.all?(shape, fn pos ->
inside?(pos) and !occupied?(pos)
end)
end
defp inside?({x, y}), do: y > 0 and x in 0..@max_x
defp occupied?(pos), do: :ets.lookup(__MODULE__, pos) != []
def place(shape) do
Enum.map(shape, &:ets.insert(__MODULE__, {&1, :rock}))
end
def drop(shape) do
jet = WarmJets.next()
pushed = Shape.move(shape, jet)
shape =
if open?(pushed) do
pushed
else
shape
end
dropped = Shape.move(shape, :down)
if open?(dropped) do
drop(dropped)
else
place(shape)
end
end
def to_list, do: :ets.tab2list(__MODULE__)
def print do
Enum.each(highest_y()..0, fn y ->
Enum.each(0..@max_x, fn x ->
case :ets.lookup(__MODULE__, {x, y}) do
[] -> IO.write(".")
[{_, :rock}] -> IO.write("#")
[{_, :floor}] -> IO.write("-")
end
end)
IO.puts("")
end)
end
end
WarmJets.start("input.txt")
Chamber.init()
Shape.all()
|> Stream.map(&Shape.start_at(&1, Chamber.highest_y() + 4))
|> Stream.map(&Chamber.drop/1)
|> Stream.take(2022)
|> Stream.run()
Chamber.highest_y() |> IO.inspect()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment