@@ -22,70 +22,70 @@ pub fn sort(comptime T: type, A: []T, B: []T) void {
2222 // Preconditions - assert all inputs
2323 assert (A .len == B .len );
2424 assert (A .len <= MAX_ARRAY_SIZE );
25-
25+
2626 const n : u32 = @intCast (A .len );
27-
27+
2828 // Handle trivial cases
2929 if (n <= 1 ) {
3030 // Postcondition: trivial arrays are already sorted
3131 return ;
3232 }
33-
33+
3434 // Copy A to B for initial pass
3535 copyArray (T , A , 0 , n , B );
36-
36+
3737 // Bottom-up iterative merge sort
3838 // No recursion! Loop bound: log2(n) iterations
3939 var width : u32 = 1 ;
4040 var iteration : u32 = 0 ;
4141 const max_iterations : u32 = 32 ; // log2(MAX_ARRAY_SIZE) = ~20, use 32 for safety
42-
42+
4343 while (width < n ) : (iteration += 1 ) {
4444 // Assert bounded loop
4545 assert (iteration < max_iterations );
4646 assert (width > 0 );
4747 assert (width <= n );
48-
48+
4949 // Merge subarrays of size 'width'
5050 var i : u32 = 0 ;
5151 const merge_count_max = n / width + 1 ; // Upper bound on merges this iteration
5252 var merge_count : u32 = 0 ;
53-
53+
5454 while (i < n ) : (merge_count += 1 ) {
5555 // Assert bounded inner loop
5656 assert (merge_count <= merge_count_max );
5757 assert (i < n );
58-
58+
5959 const left = i ;
6060 const middle = @min (i + width , n );
6161 const right = @min (i + 2 * width , n );
62-
62+
6363 // Invariants
6464 assert (left < middle );
6565 assert (middle <= right );
6666 assert (right <= n );
67-
67+
6868 // Merge on alternating passes
6969 if (iteration % 2 == 0 ) {
7070 merge (T , B , left , middle , right , A );
7171 } else {
7272 merge (T , A , left , middle , right , B );
7373 }
74-
74+
7575 i = right ;
7676 }
77-
77+
7878 width = width * 2 ;
79-
79+
8080 // Postcondition: width increased
8181 assert (width > 0 ); // Check for overflow
8282 }
83-
83+
8484 // If even number of iterations, result is in B, copy back to A
8585 if (iteration % 2 == 0 ) {
8686 copyArray (T , B , 0 , n , A );
8787 }
88-
88+
8989 // Postcondition: array is sorted (verified in tests)
9090}
9191
@@ -106,15 +106,15 @@ fn merge(
106106 assert (end <= B .len );
107107 assert (A .len <= MAX_ARRAY_SIZE );
108108 assert (B .len <= MAX_ARRAY_SIZE );
109-
110- var i : u32 = begin ; // Index for left subarray
111- var j : u32 = middle ; // Index for right subarray
112- var k : u32 = begin ; // Index for output
113-
109+
110+ var i : u32 = begin ; // Index for left subarray
111+ var j : u32 = middle ; // Index for right subarray
112+ var k : u32 = begin ; // Index for output
113+
114114 // Merge with explicit bounds
115115 const iterations_max = end - begin ;
116116 var iterations : u32 = 0 ;
117-
117+
118118 while (k < end ) : ({
119119 k += 1 ;
120120 iterations += 1 ;
@@ -123,7 +123,7 @@ fn merge(
123123 assert (iterations <= iterations_max );
124124 assert (k < end );
125125 assert (k < B .len );
126-
126+
127127 // Choose from left or right subarray
128128 if (i < middle and (j >= end or A [i ] <= A [j ])) {
129129 // Take from left
@@ -137,12 +137,12 @@ fn merge(
137137 B [k ] = A [j ];
138138 j += 1 ;
139139 }
140-
140+
141141 // Invariants
142142 assert (i <= middle );
143143 assert (j <= end );
144144 }
145-
145+
146146 // Postconditions
147147 assert (k == end );
148148 assert (i == middle or j == end ); // One subarray exhausted
@@ -162,11 +162,11 @@ fn copyArray(
162162 assert (end <= B .len );
163163 assert (A .len <= MAX_ARRAY_SIZE );
164164 assert (B .len <= MAX_ARRAY_SIZE );
165-
165+
166166 var k : u32 = begin ;
167167 const iterations_max = end - begin ;
168168 var iterations : u32 = 0 ;
169-
169+
170170 while (k < end ) : ({
171171 k += 1 ;
172172 iterations += 1 ;
@@ -175,30 +175,30 @@ fn copyArray(
175175 assert (iterations <= iterations_max );
176176 assert (k < A .len );
177177 assert (k < B .len );
178-
178+
179179 B [k ] = A [k ];
180180 }
181-
181+
182182 // Postcondition
183183 assert (k == end );
184184}
185185
186186/// Verify array is sorted in ascending order
187187fn isSorted (comptime T : type , array : []const T ) bool {
188188 assert (array .len <= MAX_ARRAY_SIZE );
189-
189+
190190 if (array .len <= 1 ) return true ;
191-
191+
192192 const n : u32 = @intCast (array .len );
193193 var i : u32 = 1 ;
194-
194+
195195 while (i < n ) : (i += 1 ) {
196196 assert (i < array .len );
197197 if (array [i - 1 ] > array [i ]) {
198198 return false ;
199199 }
200200 }
201-
201+
202202 return true ;
203203}
204204
@@ -209,28 +209,28 @@ fn isSorted(comptime T: type, array: []const T) bool {
209209test "sort: empty array" {
210210 const array : []i32 = &.{};
211211 const work : []i32 = &.{};
212-
212+
213213 sort (i32 , array , work );
214-
214+
215215 try testing .expect (isSorted (i32 , array ));
216216}
217217
218218test "sort: single element" {
219219 var array : [1 ]i32 = .{42 };
220220 var work : [1 ]i32 = .{0 };
221-
221+
222222 sort (i32 , & array , & work );
223-
223+
224224 try testing .expect (isSorted (i32 , & array ));
225225 try testing .expectEqual (@as (i32 , 42 ), array [0 ]);
226226}
227227
228228test "sort: two elements sorted" {
229229 var array : [2 ]i32 = .{ 1 , 2 };
230230 var work : [2 ]i32 = .{0 } ** 2 ;
231-
231+
232232 sort (i32 , & array , & work );
233-
233+
234234 try testing .expect (isSorted (i32 , & array ));
235235 try testing .expectEqual (@as (i32 , 1 ), array [0 ]);
236236 try testing .expectEqual (@as (i32 , 2 ), array [1 ]);
@@ -239,9 +239,9 @@ test "sort: two elements sorted" {
239239test "sort: two elements reversed" {
240240 var array : [2 ]i32 = .{ 2 , 1 };
241241 var work : [2 ]i32 = .{0 } ** 2 ;
242-
242+
243243 sort (i32 , & array , & work );
244-
244+
245245 try testing .expect (isSorted (i32 , & array ));
246246 try testing .expectEqual (@as (i32 , 1 ), array [0 ]);
247247 try testing .expectEqual (@as (i32 , 2 ), array [1 ]);
@@ -250,9 +250,9 @@ test "sort: two elements reversed" {
250250test "sort: already sorted" {
251251 var array : [10 ]i32 = .{ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 };
252252 var work : [10 ]i32 = .{0 } ** 10 ;
253-
253+
254254 sort (i32 , & array , & work );
255-
255+
256256 try testing .expect (isSorted (i32 , & array ));
257257 for (array , 0.. ) | value , i | {
258258 try testing .expectEqual (@as (i32 , @intCast (i + 1 )), value );
@@ -262,9 +262,9 @@ test "sort: already sorted" {
262262test "sort: reverse order" {
263263 var array : [10 ]i32 = .{ 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 };
264264 var work : [10 ]i32 = .{0 } ** 10 ;
265-
265+
266266 sort (i32 , & array , & work );
267-
267+
268268 try testing .expect (isSorted (i32 , & array ));
269269 for (array , 0.. ) | value , i | {
270270 try testing .expectEqual (@as (i32 , @intCast (i + 1 )), value );
@@ -274,9 +274,9 @@ test "sort: reverse order" {
274274test "sort: duplicates" {
275275 var array : [8 ]i32 = .{ 5 , 2 , 8 , 2 , 9 , 1 , 5 , 5 };
276276 var work : [8 ]i32 = .{0 } ** 8 ;
277-
277+
278278 sort (i32 , & array , & work );
279-
279+
280280 try testing .expect (isSorted (i32 , & array ));
281281 // Verify specific values
282282 try testing .expectEqual (@as (i32 , 1 ), array [0 ]);
@@ -287,9 +287,9 @@ test "sort: duplicates" {
287287test "sort: all same elements" {
288288 var array : [10 ]i32 = .{7 } ** 10 ;
289289 var work : [10 ]i32 = .{0 } ** 10 ;
290-
290+
291291 sort (i32 , & array , & work );
292-
292+
293293 try testing .expect (isSorted (i32 , & array ));
294294 for (array ) | value | {
295295 try testing .expectEqual (@as (i32 , 7 ), value );
@@ -299,9 +299,9 @@ test "sort: all same elements" {
299299test "sort: negative numbers" {
300300 var array : [6 ]i32 = .{ -5 , -1 , -10 , 0 , -3 , -7 };
301301 var work : [6 ]i32 = .{0 } ** 6 ;
302-
302+
303303 sort (i32 , & array , & work );
304-
304+
305305 try testing .expect (isSorted (i32 , & array ));
306306 try testing .expectEqual (@as (i32 , -10 ), array [0 ]);
307307 try testing .expectEqual (@as (i32 , 0 ), array [5 ]);
@@ -310,14 +310,14 @@ test "sort: negative numbers" {
310310test "sort: large array power of 2" {
311311 var array : [256 ]i32 = undefined ;
312312 var work : [256 ]i32 = undefined ;
313-
313+
314314 // Initialize with reverse order
315315 for (& array , 0.. ) | * elem , i | {
316316 elem .* = @intCast (255 - i );
317317 }
318-
318+
319319 sort (i32 , & array , & work );
320-
320+
321321 try testing .expect (isSorted (i32 , & array ));
322322 for (array , 0.. ) | value , i | {
323323 try testing .expectEqual (@as (i32 , @intCast (i )), value );
@@ -327,46 +327,46 @@ test "sort: large array power of 2" {
327327test "sort: large array non-power of 2" {
328328 var array : [1000 ]i32 = undefined ;
329329 var work : [1000 ]i32 = undefined ;
330-
330+
331331 // Initialize with pseudorandom pattern
332332 for (& array , 0.. ) | * elem , i | {
333333 elem .* = @intCast ((i * 7919 ) % 1000 );
334334 }
335-
335+
336336 sort (i32 , & array , & work );
337-
337+
338338 try testing .expect (isSorted (i32 , & array ));
339339}
340340
341341test "sort: stress test - verify no recursion stack overflow" {
342342 // This would overflow stack with recursive implementation
343343 var array : [10000 ]i32 = undefined ;
344344 var work : [10000 ]i32 = undefined ;
345-
345+
346346 // Worst case: reverse sorted
347347 for (& array , 0.. ) | * elem , i | {
348348 elem .* = @intCast (9999 - i );
349349 }
350-
350+
351351 sort (i32 , & array , & work );
352-
352+
353353 try testing .expect (isSorted (i32 , & array ));
354354}
355355
356356test "sort: different types - u32" {
357357 var array : [5 ]u32 = .{ 5 , 2 , 8 , 1 , 9 };
358358 var work : [5 ]u32 = .{0 } ** 5 ;
359-
359+
360360 sort (u32 , & array , & work );
361-
361+
362362 try testing .expect (isSorted (u32 , & array ));
363363}
364364
365365test "sort: different types - u64" {
366366 var array : [5 ]u64 = .{ 5 , 2 , 8 , 1 , 9 };
367367 var work : [5 ]u64 = .{0 } ** 5 ;
368-
368+
369369 sort (u64 , & array , & work );
370-
370+
371371 try testing .expect (isSorted (u64 , & array ));
372372}
0 commit comments