Skip to content

Commit f7c9a35

Browse files
committed
2024 day 14, part 2
I don't like visual puzzles - they require lots of trial and error and inspecting of output until you find the pattern you're looking for, then you can work backwards
1 parent a9d839c commit f7c9a35

File tree

5 files changed

+126
-29
lines changed

5 files changed

+126
-29
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
My Elixir solutions for [Advent of Code](https://adventofcode.com/) (all years).
66

77
<!-- stars start -->
8-
<p><img src="https://img.shields.io/static/v1?label=Total&message=446%20stars&style=for-the-badge&color=green" alt="446 stars" /></p>
9-
<p><a href="./lib/y2024/"><img src="https://img.shields.io/static/v1?label=2024&message=27%20stars&style=for-the-badge&color=yellow" alt="27 stars" /></a><br />
8+
<p><img src="https://img.shields.io/static/v1?label=Total&message=447%20stars&style=for-the-badge&color=green" alt="447 stars" /></p>
9+
<p><a href="./lib/y2024/"><img src="https://img.shields.io/static/v1?label=2024&message=28%20stars&style=for-the-badge&color=yellow" alt="28 stars" /></a><br />
1010
<a href="./lib/y2023/"><img src="https://img.shields.io/static/v1?label=2023&message=44%20stars&style=for-the-badge&color=green" alt="44 stars" /></a><br />
1111
<a href="./lib/y2022/"><img src="https://img.shields.io/static/v1?label=2022&message=%E2%AD%90%EF%B8%8F%2050%20stars%20%E2%AD%90%EF%B8%8F&style=for-the-badge&color=brightgreen" alt="50 stars" /></a><br />
1212
<a href="./lib/y2021/"><img src="https://img.shields.io/static/v1?label=2021&message=46%20stars&style=for-the-badge&color=green" alt="46 stars" /></a><br />

lib/advent/grid.ex

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ defmodule Advent.Grid do
4949
end
5050

5151
def display(grid, highlight \\ []) do
52+
grid
53+
|> rows(highlight)
54+
|> Enum.map(&IO.puts/1)
55+
56+
grid
57+
end
58+
59+
def rows(grid, highlight \\ []) do
5260
vertices = Map.keys(grid)
5361
{{min_row, min_col}, {max_row, max_col}} = Enum.min_max(vertices)
5462

@@ -72,10 +80,7 @@ defmodule Advent.Grid do
7280
row
7381
|> Enum.filter(& &1)
7482
|> List.to_string()
75-
|> IO.puts()
7683
end)
77-
78-
grid
7984
end
8085

8186
defp highlight?(list, coord) when is_list(list) do

lib/y2024/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
My Elixir solutions for [Advent of Code 2024](https://adventofcode.com/2024).
44

5-
<!-- stars 2024 start --><img src="https://img.shields.io/static/v1?label=2024&message=27%20stars&style=for-the-badge&color=yellow" alt="27 stars" /><!-- stars 2024 end -->
5+
<!-- stars 2024 start --><img src="https://img.shields.io/static/v1?label=2024&message=28%20stars&style=for-the-badge&color=yellow" alt="28 stars" /><!-- stars 2024 end -->
66

77
## Benchmarks
88

@@ -38,7 +38,8 @@ day 11, part 1 838.21 1.19 ms ±4.86% 1.21 ms 1.
3838
day 11, part 2 19.52 51.22 ms ±1.86% 51.26 ms 53.37 ms
3939
day 12, part 1 7.16 139.70 ms ±1.82% 139.22 ms 144.95 ms
4040
day 12, part 2 6.84 146.22 ms ±1.32% 145.82 ms 151.25 ms
41-
day 13, part 1 1.31 K 765.25 μs ±3.72% 754 μs 837.77 μs
42-
day 13, part 2 1.33 K 753.73 μs ±3.42% 744.42 μs 822.51 μs
43-
day 14, part 1 496.97 2.01 ms ±9.95% 1.88 ms 2.36 ms
41+
day 13, part 2 1298.79 0.77 ms ±3.47% 0.76 ms 0.85 ms
42+
day 13, part 1 1294.57 0.77 ms ±4.01% 0.76 ms 0.86 ms
43+
day 14, part 1 516.12 1.94 ms ±8.66% 1.85 ms 2.30 ms
44+
day 14, part 2 1.41 707.27 ms ±0.37% 707.76 ms 710.36 ms
4445
```

lib/y2024/day14.ex

Lines changed: 110 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,118 @@ defmodule Y2024.Day14 do
22
use Advent.Day, no: 14
33

44
def part1(input, size, ticks \\ 100) do
5+
# Count up to reach the set number of ticks
6+
win_state = fn {_, _, current} -> current == ticks end
7+
58
input
6-
|> tick(size, ticks)
9+
|> tick(size, win_state, 0)
10+
|> elem(0)
711
|> quadrantize(size)
812
end
913

10-
defp tick(input, _size, 0), do: input
14+
def part2(input, size) do
15+
# Count up until you see a treeeeee!?!?!?
16+
trees =
17+
[
18+
"1111111111111111111111111111111",
19+
"1 1",
20+
"1 1",
21+
"1 1",
22+
"1 1",
23+
"1 1 1",
24+
"1 111 1",
25+
"1 11111 1",
26+
"1 1111111 1",
27+
"1 111111111 1",
28+
"1 11111 1",
29+
"1 1111111 1",
30+
"1 111111111 1",
31+
"1 11111111111 1",
32+
"1 1111111111111 1",
33+
"1 111111111 1",
34+
"1 11111111111 1",
35+
"1 1111111111111 1",
36+
"1 111111111111111 1",
37+
"1 11111111111111111 1",
38+
"1 1111111111111 1",
39+
"1 111111111111111 1",
40+
"1 11111111111111111 1",
41+
"1 1111111111111111111 1",
42+
"1 111111111111111111111 1",
43+
"1 111 1",
44+
"1 111 1",
45+
"1 111 1",
46+
"1 1",
47+
"1 1",
48+
"1 1",
49+
"1 1",
50+
"1111111111111111111111111111111"
51+
]
52+
|> Enum.with_index()
1153

12-
defp tick(input, {max_row, max_col}, ticks) do
13-
Enum.map(input, fn %{position: {row, col}, velocity: {v_row, v_col}} ->
14-
new_position = {rem(row + v_row + max_row, max_row), rem(col + v_col + max_col, max_col)}
15-
%{position: new_position, velocity: {v_row, v_col}}
16-
end)
17-
|> tick({max_row, max_col}, ticks - 1)
54+
win_state = fn {input, {max_row, max_col}, current} ->
55+
# After lots of trial and error printing out the grid after a set number
56+
# of ticks, there seem to be cycles where it looks like robots are coming
57+
# together at given points - the two tick number conditions below
58+
# One of those must be right answer
59+
if rem(current, 103) == 31 || rem(current, 101) == 88 do
60+
# Turn the robot list into a grid shape
61+
grid =
62+
input
63+
|> Enum.group_by(& &1.position)
64+
|> Enum.map(fn {{row, col}, list} -> {{col, row}, length(list)} end)
65+
|> Map.new()
66+
67+
coords = for row <- 0..(max_row - 1), col <- 0..(max_col - 1), do: {col, row}
68+
69+
row_strings =
70+
coords
71+
|> Enum.map(fn coord -> {coord, Map.get(grid, coord, " ")} end)
72+
|> Map.new()
73+
|> Advent.Grid.rows()
74+
|> Enum.with_index()
75+
|> Map.new(fn {row, index} -> {index, row} end)
76+
77+
# The real logic - find out if all of the rows in the `trees` list
78+
# are found at the same starting index in any row of the grid
79+
# https://stackoverflow.com/a/35551220
80+
Enum.find(row_strings, fn {row_index, row} ->
81+
{head_tree, _} = hd(trees)
82+
83+
case :binary.match(row, head_tree) do
84+
:nomatch ->
85+
false
86+
87+
{col_index, length} ->
88+
# The first tree row is found in the current grid, now are all of
89+
# the other rows of the tree found in subsequent rows of the grid?
90+
Enum.all?(trees, fn {tree_row, tree_index} ->
91+
{col_index, length} ==
92+
row_strings
93+
|> Map.get(row_index + tree_index, "")
94+
|> :binary.match(tree_row)
95+
end)
96+
end
97+
end)
98+
end
99+
end
100+
101+
input
102+
|> tick(size, win_state, 0)
103+
|> elem(1)
104+
end
105+
106+
defp tick(input, {max_row, max_col}, win_condition, ticks) do
107+
if win_condition.({input, {max_row, max_col}, ticks}) do
108+
{input, ticks}
109+
else
110+
input
111+
|> Enum.map(fn %{position: {row, col}, velocity: {v_row, v_col}} ->
112+
new_position = {rem(row + v_row + max_row, max_row), rem(col + v_col + max_col, max_col)}
113+
%{position: new_position, velocity: {v_row, v_col}}
114+
end)
115+
|> tick({max_row, max_col}, win_condition, ticks + 1)
116+
end
18117
end
19118

20119
defp quadrantize(input, {row, col}) do
@@ -29,14 +128,6 @@ defmodule Y2024.Day14 do
29128
|> Enum.reduce(1, fn {_, list}, acc -> acc * length(list) end)
30129
end
31130

32-
# @doc """
33-
# iex> Day14.part2("update or delete me")
34-
# "update or delete me"
35-
# """
36-
# def part2(input) do
37-
# input
38-
# end
39-
40131
@doc "Display the grid to see what's going on."
41132
def display(input, {max_row, max_col}) do
42133
IO.puts("")
@@ -50,7 +141,7 @@ defmodule Y2024.Day14 do
50141
coords = for row <- 0..(max_row - 1), col <- 0..(max_col - 1), do: {col, row}
51142

52143
coords
53-
|> Enum.map(fn coord -> {coord, Map.get(new_input, coord, ".")} end)
144+
|> Enum.map(fn coord -> {coord, Map.get(new_input, coord, " ")} end)
54145
|> Map.new()
55146
|> Advent.Grid.display()
56147

@@ -74,6 +165,6 @@ defmodule Y2024.Day14 do
74165
end)
75166
end
76167

77-
def part1_verify, do: input() |> parse_input() |> part1({101, 103})
78-
# def part2_verify, do: input() |> parse_input() |> part2()
168+
def part1_verify, do: input() |> parse_input() |> part1({101, 103}, 100)
169+
def part2_verify, do: input() |> parse_input() |> part2({101, 103})
79170
end

test/y2024/day14_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,5 @@ defmodule Y2024.Day14Test do
2424
end
2525

2626
test "verification, part 1", do: assert(Day14.part1_verify() == 226_236_192)
27-
# test "verification, part 2", do: assert(Day14.part2_verify() == "update or delete me")
27+
test "verification, part 2", do: assert(Day14.part2_verify() == 8168)
2828
end

0 commit comments

Comments
 (0)