@@ -2,19 +2,118 @@ defmodule Y2024.Day14 do
2
2
use Advent.Day , no: 14
3
3
4
4
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
+
5
8
input
6
- |> tick ( size , ticks )
9
+ |> tick ( size , win_state , 0 )
10
+ |> elem ( 0 )
7
11
|> quadrantize ( size )
8
12
end
9
13
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 ( )
11
53
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
18
117
end
19
118
20
119
defp quadrantize ( input , { row , col } ) do
@@ -29,14 +128,6 @@ defmodule Y2024.Day14 do
29
128
|> Enum . reduce ( 1 , fn { _ , list } , acc -> acc * length ( list ) end )
30
129
end
31
130
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
-
40
131
@ doc "Display the grid to see what's going on."
41
132
def display ( input , { max_row , max_col } ) do
42
133
IO . puts ( "" )
@@ -50,7 +141,7 @@ defmodule Y2024.Day14 do
50
141
coords = for row <- 0 .. ( max_row - 1 ) , col <- 0 .. ( max_col - 1 ) , do: { col , row }
51
142
52
143
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 )
54
145
|> Map . new ( )
55
146
|> Advent.Grid . display ( )
56
147
@@ -74,6 +165,6 @@ defmodule Y2024.Day14 do
74
165
end )
75
166
end
76
167
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 } )
79
170
end
0 commit comments