Skip to content

Commit 1770304

Browse files
committed
Implement function to reorder numbers in slice
1 parent be10d73 commit 1770304

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

src/utils.zig

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,31 @@ pub fn bitReverseNumber(number: i64, width: i64) i64 {
200200
return result;
201201
}
202202

203+
/// Reorders numbers in slice using the bit reverse value of the slice indexes.
204+
/// The numbers [0, 1, 2, 3] would become [0, 2, 1, 3] because 0 = 0b00 reversed
205+
/// is 0b00 = 0, 1 = 0b01 reversed is 0b10 = 2, 2 = 0b10 reversed is 0b01 = 1
206+
/// and 3 = 0b11 reversed is 0b11 = 3.
207+
/// The caller owns the returned memory.
208+
pub fn bitReverseSlice(allocator: Allocator, numbers: []const i64) ![]const i64 {
209+
// Length of numbers must be a power of 2.
210+
if (!isPowerOfTwo(@intCast(numbers.len))) {
211+
return error.LengthNotPowerOfTwo;
212+
}
213+
214+
const n = numbers.len;
215+
const log2_n = std.math.log2_int(usize, @intCast(n));
216+
217+
const result = try allocator.alloc(i64, n);
218+
219+
for (0..n) |i| {
220+
const reversed_i = bitReverseNumber(@intCast(i), log2_n);
221+
const idx: usize = @intCast(reversed_i);
222+
result[i] = numbers[idx];
223+
}
224+
225+
return result;
226+
}
227+
203228
test "findRootOfUnity - core" {
204229
var n: i64 = undefined;
205230
var m: i64 = undefined;
@@ -454,3 +479,60 @@ test "bitReverseNumber" {
454479
try testing.expectEqual(expected_2, result_2);
455480
}
456481
}
482+
483+
test "bitReverseSlice" {
484+
const allocator = testing.allocator;
485+
486+
{
487+
const input = [_]i64{ 0, 1, 2, 3, 4, 5 };
488+
const expected = error.LengthNotPowerOfTwo;
489+
490+
const result = bitReverseSlice(allocator, &input);
491+
try testing.expectError(expected, result);
492+
}
493+
494+
{
495+
const input = [_]i64{ 0, 1, 2, 3, 4, 5, 6, 7 };
496+
const expected = [_]i64{ 0, 4, 2, 6, 1, 5, 3, 7 };
497+
498+
const result = try bitReverseSlice(allocator, &input);
499+
defer allocator.free(result);
500+
501+
try testing.expectEqualSlices(i64, &expected, result);
502+
}
503+
504+
{
505+
const input = [_]i64{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
506+
const expected = [_]i64{ 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 };
507+
508+
const result = try bitReverseSlice(allocator, &input);
509+
defer allocator.free(result);
510+
511+
try testing.expectEqualSlices(i64, &expected, result);
512+
}
513+
514+
{
515+
const input = [_]i64{ 0, 1, 4, 5 };
516+
const expected = [_]i64{ 0, 4, 1, 5 };
517+
518+
const result = try bitReverseSlice(allocator, &input);
519+
defer allocator.free(result);
520+
521+
try testing.expectEqualSlices(i64, &expected, result);
522+
}
523+
524+
{
525+
const input = [_]i64{ 11, 22, 33, 44, 55, 66, 77, 88 };
526+
const expected = input;
527+
528+
const input_1 = input;
529+
const result_1 = try bitReverseSlice(allocator, &input_1);
530+
defer allocator.free(result_1);
531+
532+
const input_2 = result_1;
533+
const result_2 = try bitReverseSlice(allocator, input_2);
534+
defer allocator.free(result_2);
535+
536+
try testing.expectEqualSlices(i64, &expected, result_2);
537+
}
538+
}

0 commit comments

Comments
 (0)