@@ -6,20 +6,22 @@ const string = []const u8;
66// Dijkstra module
77const dijkstra = @import ("./dijkstra.zig" );
88
9- /// Task 1 -
9+ /// Task 1 - Simulate the falling bytes and calculate the shortest path from
10+ /// the top-left corner of the grid to the bottom-right corner.
1011///
1112/// Arguments:
1213/// - `contents`: Input file contents.
14+ /// - `bytes`: Number of fallen bytes.
1315/// - `main_allocator`: Base allocator for everything.
1416///
1517/// Returns:
16- /// - Solution for task 1 .
17- pub fn solution_1 (contents : string , bytes : usize , main_allocator : Allocator ) ! u32 {
18+ /// - Length of the shortest path .
19+ pub fn steps_to_the_exit (contents : string , bytes : usize , main_allocator : Allocator ) ! u32 {
1820 var arena = std .heap .ArenaAllocator .init (main_allocator );
1921 defer arena .deinit ();
2022
2123 const allocator = arena .allocator ();
22- const ram = try parse (contents , allocator );
24+ const ram = try parse_ram (contents , allocator );
2325 const end = ram .width * ram .height - 1 ;
2426
2527 const nodes = try dijkstra .dijkstra (
@@ -34,22 +36,24 @@ pub fn solution_1(contents: string, bytes: usize, main_allocator: Allocator) !u3
3436 return nodes .items [end ].distance ;
3537}
3638
37- /// Task 2 -
39+ /// Task 2 - Find the position of the byte that will ultimately block the path
40+ /// between the top-left corner of the grid to the bottom-right corner.
3841///
3942/// Arguments:
4043/// - `contents`: Input file contents.
4144/// - `main_allocator`: Base allocator for everything.
4245///
4346/// Returns:
44- /// - Solution for task 2 .
45- pub fn solution_2 (contents : string , main_allocator : Allocator ) ! string {
47+ /// - Position of the blocking byte as a string .
48+ pub fn position_of_blocking_byte (contents : string , main_allocator : Allocator ) ! string {
4649 var arena = std .heap .ArenaAllocator .init (main_allocator );
4750 defer arena .deinit ();
4851
4952 const allocator = arena .allocator ();
50- const ram = try parse (contents , allocator );
53+ const ram = try parse_ram (contents , allocator );
5154 const end = ram .width * ram .height - 1 ;
5255
56+ // Bisection
5357 var upper_bound = ram .falling_bytes .items .len - 1 ;
5458 var lower_bound : usize = 0 ;
5559 while (lower_bound + 1 < upper_bound ) {
@@ -69,6 +73,7 @@ pub fn solution_2(contents: string, main_allocator: Allocator) !string {
6973 }
7074 }
7175
76+ // Convert position to string (what a pain ...)
7277 const x_str_size = std .math .log10 (@max (ram .falling_bytes .items [lower_bound ].x , 1 )) + 1 ;
7378 const y_str_size = std .math .log10 (@max (ram .falling_bytes .items [lower_bound ].y , 1 )) + 1 ;
7479 const str_size = 1 + x_str_size + y_str_size ;
@@ -82,13 +87,23 @@ pub fn solution_2(contents: string, main_allocator: Allocator) !string {
8287
8388// -------------------------------------------------------------------------- \\
8489
90+ /// 2D Position in a grid.
8591const Position = struct { x : usize , y : usize };
8692
93+ /// RAM object that represents a quadratic grid of cells and a list of falling
94+ /// bytes which will block certain cells.
8795const RAM = struct {
8896 falling_bytes : ArrayList (Position ),
8997 width : usize ,
9098 height : usize ,
9199
100+ /// Init the RAM grid of undefined size.
101+ ///
102+ /// Arguments:
103+ /// - `allocator`: Allocator list of falling bytes.
104+ ///
105+ /// Returns:
106+ /// - The RAM object.
92107 fn init (allocator : Allocator ) RAM {
93108 return RAM {
94109 .falling_bytes = ArrayList (Position ).init (allocator ),
@@ -97,6 +112,17 @@ const RAM = struct {
97112 };
98113 }
99114
115+ /// Create a graph representation of the RAM grid when the given number of
116+ /// bytes have fallen. First create a full graph with all nodes and then
117+ /// remove connections for each falling byte.
118+ ///
119+ /// Arguments:
120+ /// - `self`: The RAM object.
121+ /// - `bytes`: Number of fallen bytes.
122+ /// - `allocator`: Allocator for the adjacency matrix.
123+ ///
124+ /// Returns:
125+ /// - The adjacency matrix of the graph.
100126 fn create_adjacency_matrix (self : RAM , bytes : usize , allocator : Allocator ) ! ArrayList (? u32 ) {
101127 const nodes = self .width * self .height ;
102128 var matrix = try self .create_safe_adjacency_matrix (allocator );
@@ -117,6 +143,15 @@ const RAM = struct {
117143 return matrix ;
118144 }
119145
146+ /// Create a graph representation of the RAM grid when no bytes have fallen
147+ /// yet.
148+ ///
149+ /// Arguments:
150+ /// - `self`: The RAM object.
151+ /// - `allocator`: Allocator for the adjacency matrix.
152+ ///
153+ /// Returns:
154+ /// - The adjacency matrix of the graph.
120155 fn create_safe_adjacency_matrix (self : RAM , allocator : Allocator ) ! ArrayList (? u32 ) {
121156 const nodes = self .width * self .height ;
122157 var matrix = ArrayList (? u32 ).init (allocator );
@@ -133,6 +168,15 @@ const RAM = struct {
133168 return matrix ;
134169 }
135170
171+ /// Check if a certain cell/node is a neighbour of another cell/node
172+ ///
173+ /// Arguments:
174+ /// - `self`: The RAM object.
175+ /// - `node1`: Position of the first cell/node.
176+ /// - `node2`: Position of the second cell/node.
177+ ///
178+ /// Returns:
179+ /// - True if the two cells/nodes are neighbours.
136180 fn is_neighbour_cell (self : RAM , node1 : usize , node2 : usize ) bool {
137181 const x1 = node1 % self .width ;
138182 const y1 = node1 / self .width ;
@@ -141,6 +185,11 @@ const RAM = struct {
141185 return (y1 == y2 and (x1 == x2 + 1 or x1 + 1 == x2 )) or (x1 == x2 and (y1 == y2 + 1 or y1 + 1 == y2 ));
142186 }
143187
188+ /// Print the current RAM grid.
189+ ///
190+ /// Arguments:
191+ /// - `self`: The RAM object.
192+ /// - `bytes`: Number of bytes that have fallen.
144193 fn print (self : RAM , bytes : usize ) void {
145194 for (0.. self .height ) | y | {
146195 for (0.. self .width ) | x | {
@@ -162,15 +211,16 @@ const RAM = struct {
162211 }
163212};
164213
165- /// Parse the file contents into a list of reports.
214+ /// Parse the file contents into a RAM grid of a crertain size and a list of
215+ /// positions of falling byte.
166216///
167217/// Arguments:
168218/// - `contents`: Input file contents.
169219/// - `allocator`: Allocator for the containers.
170220///
171221/// Returns:
172- /// - Array list of report objects .
173- fn parse (contents : string , allocator : Allocator ) ! RAM {
222+ /// - The RAM oject .
223+ fn parse_ram (contents : string , allocator : Allocator ) ! RAM {
174224 var ram = RAM .init (allocator );
175225
176226 var lines = std .mem .tokenize (u8 , contents , "\r \n " );
0 commit comments