Sort function for chunks of a slice

You can do it by using a Context object with pdqContext (or other sort functions of the *Context variant), it allows you to map the usize a and b indexes, which are passed to the lessThan and swap functions, in a way where these indexes represent the row that is currently being sorted.

const std = @import("std");

fn sort(matrix: []f32, n: usize) void {
    const Context = struct {
        items: []f32,
        columns: usize,

        pub fn lessThan(ctx: @This(), a: usize, b: usize) bool {
            const c = ctx.columns;
            const lhs = ctx.items[a*c..][0..c];
            const rhs = ctx.items[b*c..][0..c];
            return std.mem.indexOfNone(f32, lhs, &.{0}) orelse lhs.len <
                std.mem.indexOfNone(f32, rhs, &.{0}) orelse rhs.len;
        }

        pub fn swap(ctx: @This(), a: usize, b: usize) void {
            const c = ctx.columns;
            const lhs = ctx.items[a*c..][0..c];
            const rhs = ctx.items[b*c..][0..c];
            for(lhs, rhs) |*l, *r| std.mem.swap(f32, l, r);
        }
    };

    const rows = matrix.len / n;
    std.debug.assert(rows * n == matrix.len);
    std.sort.pdqContext(0, rows, Context{.items = matrix, .columns = n});
}

pub fn printMatrix(matrix:[]f32, n:usize) void {
    for(0..n) |i| {
        for(0..n) |j| {
            std.debug.print("{} ",.{matrix[4*i+j]});
        }
        std.debug.print("\n",.{});
    }
}

pub fn main() !void {
    var test_matrix = [_]f32{
        0.0, 0.0, 3.0, 0.0,
        0.0, 4.0, 0.0, 0.0,
        0.0, 0.0, 0.0, 2.0,
        7.0, 0.0, 0.0, 0.0,
    };

    printMatrix(&test_matrix, 4);
    std.debug.print("\n",.{});

    sort(&test_matrix, 4);

    std.debug.print("\n",.{});
    printMatrix(&test_matrix, 4);
}
2 Likes