-
-
Save al2o3cr/2062ecf2cc11648f88832c5c4b3c2a22 to your computer and use it in GitHub Desktop.
2022 AOC Day 16
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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