day 2024 day 14
This commit is contained in:
parent
7dfc62354d
commit
e4de674377
1 changed files with 123 additions and 0 deletions
123
elixir/livebook/2024/day14.livemd
Normal file
123
elixir/livebook/2024/day14.livemd
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
# AOC 2024 Day 14
|
||||||
|
|
||||||
|
## Section
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
input = """
|
||||||
|
"""
|
||||||
|
```
|
||||||
|
|
||||||
|
positive `rem` that only returns positive number
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
rrem = fn a, b ->
|
||||||
|
t = rem(a, b)
|
||||||
|
if t < 0 do
|
||||||
|
t + b
|
||||||
|
else
|
||||||
|
t
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
quadrant = fn {x, y}, {w, h} ->
|
||||||
|
{cx, cy} = {div(w, 2), div(h, 2)}
|
||||||
|
{
|
||||||
|
(if x < cx, do: -1, else: (if cx < x, do: 1, else: nil)),
|
||||||
|
(if y < cy, do: -1, else: (if cy < y, do: 1, else: nil))
|
||||||
|
}
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
w = 101
|
||||||
|
h = 103
|
||||||
|
```
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
pos = for line <- input |> String.trim() |> String.split("\n", trim: true),
|
||||||
|
[p, v] = String.split(line, " "),
|
||||||
|
{x,y} = p |> String.split("=") |> Enum.at(1) |> String.split(",") |> Enum.map(&String.to_integer/1) |> List.to_tuple(),
|
||||||
|
{px, py} = v |> String.split("=") |> Enum.at(1) |> String.split(",") |> Enum.map(&String.to_integer/1) |> List.to_tuple(),
|
||||||
|
reduce: %{}
|
||||||
|
do
|
||||||
|
acc ->
|
||||||
|
{fx, fy} = {rrem.(x + 100*px, w), rrem.(y + 100*py, h)}
|
||||||
|
if (fx != div(w, 2) and fy != div(h, 2)) do
|
||||||
|
acc |> Map.update(quadrant.({fx, fy}, {w, h}), 1, &(&1 + 1))
|
||||||
|
else
|
||||||
|
acc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
pos |> Map.values() |> Enum.product()
|
||||||
|
```
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
points = for line <- input |> String.trim() |> String.split("\n", trim: true),
|
||||||
|
[p, v] = String.split(line, " "),
|
||||||
|
{x,y} = p |> String.split("=") |> Enum.at(1) |> String.split(",") |> Enum.map(&String.to_integer/1) |> List.to_tuple(),
|
||||||
|
{px, py} = v |> String.split("=") |> Enum.at(1) |> String.split(",") |> Enum.map(&String.to_integer/1) |> List.to_tuple(),
|
||||||
|
reduce: MapSet.new
|
||||||
|
do
|
||||||
|
acc ->
|
||||||
|
MapSet.put(acc, {{x, y}, {px, py}})
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
draw = fn points ->
|
||||||
|
for y <- 0..(h-1) do
|
||||||
|
for x <- 0..(w-1) do
|
||||||
|
File.write("buffer.txt", (if MapSet.member?(points, {x, y}), do: "*", else: "."), [:write, :append])
|
||||||
|
if x == (w-1) do
|
||||||
|
File.write("buffer.txt", "\n", [:write, :append])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
q = Stream.iterate(0, &(&1 + 1))
|
||||||
|
|> Enum.take(10_000)
|
||||||
|
|> Enum.reduce(%{}, fn i, seen ->
|
||||||
|
safety = for {{x, y}, {px, py}} <- points,
|
||||||
|
reduce: %{} do
|
||||||
|
acc ->
|
||||||
|
f = quadrant.({rrem.(x + i*px, w), rrem.(y + i*py, h)}, {w, h})
|
||||||
|
case f do
|
||||||
|
{nil, _ } -> acc
|
||||||
|
{_, nil} -> acc
|
||||||
|
x -> Map.update(acc, x, 1, &(&1 + 1))
|
||||||
|
end
|
||||||
|
end |> Map.values() |> Enum.product()
|
||||||
|
Map.put(seen, i, safety)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
q |> Enum.min_by(&elem(&1, 1))
|
||||||
|
```
|
||||||
|
|
||||||
|
I solved part two by a mix of searching frames around the min safety factor. The below cell renders the frames in a range near the min.
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
for i <- 6200..6300 do
|
||||||
|
for {{x, y}, {px, py}} <- points,
|
||||||
|
reduce: MapSet.new do
|
||||||
|
acc ->
|
||||||
|
f = {rem(x + i*px, w), rem(y + i*py, h)}
|
||||||
|
MapSet.put(acc, f)
|
||||||
|
end |> draw.()
|
||||||
|
end
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
|
||||||
|
```
|
Loading…
Add table
Reference in a new issue