Skip to content

Commit 7c9e7d3

Browse files
committed
Update Wiki
1 parent 248b167 commit 7c9e7d3

11 files changed

Lines changed: 263 additions & 9 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Large diffs are not rendered by default.

lib/2024/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
[Home](../../README.md) | [2015](../2015/README.md) | [2016](../2016/README.md) | [2017](../2017/README.md) | [2018](../2018/README.md) | [2019](../2019/README.md) | [2020](../2020/README.md) | [2021](../2021/README.md) | [2022](../2022/README.md) | [2023](../2023/README.md) | 2024 | [2025](../2025/README.md)
44

5-
## 16/50
5+
## 18/50
66

7-
[graph](../../wiki/tags/graph.md) `3` [grid](../../wiki/tags/grid.md) `2` [binary-search](../../wiki/tags/binary-search.md) `1` [bron-kerbosch](../../wiki/tags/bron-kerbosch.md) `1` [clique](../../wiki/tags/clique.md) `1` [dijkstra](../../wiki/tags/dijkstra.md) `1` [disjoint-set](../../wiki/tags/disjoint-set.md) `1` [fsm](../../wiki/tags/fsm.md) `1` [geometry2d](../../wiki/tags/geometry2d.md) `1` [lan-party](../../wiki/tags/lan-party.md) `1` [list](../../wiki/tags/list.md) `1` [maximum-clique](../../wiki/tags/maximum-clique.md) `1` [regex](../../wiki/tags/regex.md) `1` [sequence](../../wiki/tags/sequence.md) `1` [sort](../../wiki/tags/sort.md) `1` [topological-sort](../../wiki/tags/topological-sort.md) `1` [validation](../../wiki/tags/validation.md) `1` [word-search](../../wiki/tags/word-search.md) `1`
7+
[graph](../../wiki/tags/graph.md) `3` [grid](../../wiki/tags/grid.md) `3` [binary-search](../../wiki/tags/binary-search.md) `1` [bron-kerbosch](../../wiki/tags/bron-kerbosch.md) `1` [clique](../../wiki/tags/clique.md) `1` [cycle-detection](../../wiki/tags/cycle-detection.md) `1` [dijkstra](../../wiki/tags/dijkstra.md) `1` [disjoint-set](../../wiki/tags/disjoint-set.md) `1` [fsm](../../wiki/tags/fsm.md) `1` [geometry2d](../../wiki/tags/geometry2d.md) `1` [lan-party](../../wiki/tags/lan-party.md) `1` [list](../../wiki/tags/list.md) `1` [maximum-clique](../../wiki/tags/maximum-clique.md) `1` [regex](../../wiki/tags/regex.md) `1` [sequence](../../wiki/tags/sequence.md) `1` [simulation](../../wiki/tags/simulation.md) `1` [slow](../../wiki/tags/slow.md) `1` [sort](../../wiki/tags/sort.md) `1` [topological-sort](../../wiki/tags/topological-sort.md) `1` [validation](../../wiki/tags/validation.md) `1` [word-search](../../wiki/tags/word-search.md) `1`
88

99
| Day | Title | Difficulty | Tags | Source |
1010
|:---:|-------|:----------:|------|--------|
@@ -13,6 +13,7 @@
1313
| [3](https://adventofcode.com/2024/day/3) | [Mull It Over](https://adventofcode.com/2024/day/3) | 🟢 | [regex](../../wiki/tags/regex.md), [fsm](../../wiki/tags/fsm.md) | [day_03.ex](day_03.ex) |
1414
| [4](https://adventofcode.com/2024/day/4) | [Ceres Search](https://adventofcode.com/2024/day/4) | 🟡 | [grid](../../wiki/tags/grid.md), [word-search](../../wiki/tags/word-search.md) | [day_04.ex](day_04.ex) |
1515
| [5](https://adventofcode.com/2024/day/5) | [Print Queue](https://adventofcode.com/2024/day/5) | 🟢 | [graph](../../wiki/tags/graph.md), [topological-sort](../../wiki/tags/topological-sort.md), [sort](../../wiki/tags/sort.md) | [day_05.ex](day_05.ex) |
16+
| [6](https://adventofcode.com/2024/day/6) | [Guard Gallivant](https://adventofcode.com/2024/day/6) | 🟠 | [grid](../../wiki/tags/grid.md), [simulation](../../wiki/tags/simulation.md), [cycle-detection](../../wiki/tags/cycle-detection.md), [slow](../../wiki/tags/slow.md) | [day_06.ex](day_06.ex) |
1617
| [12](https://adventofcode.com/2024/day/12) | [Garden Groups](https://adventofcode.com/2024/day/12) | 🟠 | [geometry2d](../../wiki/tags/geometry2d.md), [disjoint-set](../../wiki/tags/disjoint-set.md) | [day_12.ex](day_12.ex) |
1718
| [18](https://adventofcode.com/2024/day/18) | [RAM Run](https://adventofcode.com/2024/day/18) | 🟠 | [graph](../../wiki/tags/graph.md), [grid](../../wiki/tags/grid.md), [binary-search](../../wiki/tags/binary-search.md), [dijkstra](../../wiki/tags/dijkstra.md) | [day_18.ex](day_18.ex) |
1819
| [23](https://adventofcode.com/2024/day/23) | [LAN Party](https://adventofcode.com/2024/day/23) | 🟠 | [graph](../../wiki/tags/graph.md), [clique](../../wiki/tags/clique.md), [bron-kerbosch](../../wiki/tags/bron-kerbosch.md), [maximum-clique](../../wiki/tags/maximum-clique.md), [lan-party](../../wiki/tags/lan-party.md) | [day_23.ex](day_23.ex) |

lib/2024/day_06.ex

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
defmodule AdventOfCode.Y2024.Day06 do
2+
@moduledoc """
3+
--- Day 6: Guard Gallivant ---
4+
Problem Link: https://adventofcode.com/2024/day/6
5+
Difficulty: m
6+
Tags: grid simulation cycle-detection slow
7+
"""
8+
alias AdventOfCode.Helpers.{InputReader, Transformers}
9+
10+
def input, do: InputReader.read_from_file(2024, 6)
11+
12+
# Directions: up, right, down, left
13+
@dx {0, 1, 0, -1}
14+
@dy {-1, 0, 1, 0}
15+
16+
def run(input \\ input()) do
17+
{grid, rows, cols, sx, sy} = parse(input)
18+
{run_1(grid, rows, cols, sx, sy), run_2(grid, rows, cols, sx, sy)}
19+
end
20+
21+
# Part 1: Simulate guard path
22+
defp run_1(grid, rows, cols, sx, sy) do
23+
{pos_map, _} = simulate(grid, rows, cols, sx, sy, 0, %{}, %{})
24+
map_size(pos_map)
25+
end
26+
27+
# Simulate guard movement - returns {position_map, :exit | :loop}
28+
defp simulate(grid, rows, cols, x, y, dir, pos_map, state_map) do
29+
# Encode state as integer for fast lookup
30+
state_key = (x * rows + y) * 4 + dir
31+
32+
if Map.has_key?(state_map, state_key) do
33+
{pos_map, :loop}
34+
else
35+
new_state = Map.put(state_map, state_key, true)
36+
new_pos = Map.put(pos_map, {x, y}, true)
37+
38+
nx = x + elem(@dx, dir)
39+
ny = y + elem(@dy, dir)
40+
41+
cond do
42+
nx < 0 or nx >= cols or ny < 0 or ny >= rows ->
43+
{new_pos, :exit}
44+
45+
elem(grid, ny * cols + nx) == ?# ->
46+
simulate(grid, rows, cols, x, y, rem(dir + 1, 4), new_pos, new_state)
47+
48+
true ->
49+
simulate(grid, rows, cols, nx, ny, dir, new_pos, new_state)
50+
end
51+
end
52+
end
53+
54+
# Part 2: Count positions where adding an obstacle creates a loop
55+
defp run_2(grid, rows, cols, sx, sy) do
56+
{orig_pos, _} = simulate(grid, rows, cols, sx, sy, 0, %{}, %{})
57+
58+
orig_pos
59+
|> Map.keys()
60+
|> Enum.reject(fn {px, py} -> px == sx and py == sy end)
61+
|> Task.async_stream(
62+
fn {ox, oy} ->
63+
new_grid = put_elem(grid, oy * cols + ox, ?#)
64+
65+
case simulate(new_grid, rows, cols, sx, sy, 0, %{}, %{}) do
66+
{_, :loop} -> 1
67+
_ -> 0
68+
end
69+
end,
70+
ordered: false,
71+
max_concurrency: System.schedulers_online()
72+
)
73+
|> Enum.reduce(0, fn {:ok, count}, acc -> acc + count end)
74+
end
75+
76+
# Parse into flat tuple for O(1) access
77+
defp parse(input) do
78+
lines = Transformers.lines(input)
79+
rows = length(lines)
80+
cols = String.length(hd(lines))
81+
82+
{grid_list_rev, sx, sy} =
83+
lines
84+
|> Enum.with_index()
85+
|> Enum.reduce({[], nil, nil}, fn {line, y}, {acc, sx, sy} ->
86+
chars = String.to_charlist(line)
87+
88+
{new_sx, new_sy} =
89+
case Enum.find_index(chars, &(&1 == ?^)) do
90+
nil -> {sx, sy}
91+
x -> {x, y}
92+
end
93+
94+
normalized = Enum.map(chars, fn c -> if c == ?^, do: ?., else: c end)
95+
{[normalized | acc], new_sx, new_sy}
96+
end)
97+
98+
grid_tuple =
99+
grid_list_rev
100+
|> Enum.reverse()
101+
|> List.flatten()
102+
|> List.to_tuple()
103+
104+
{grid_tuple, rows, cols, sx, sy}
105+
end
106+
end

0 commit comments

Comments
 (0)