Subsection of array of arrays?

I have a struct containing a [[Cell; 9]; 9] representing a Sudoku grid, and I'd like this function to return the 3 by 3 subsection that a Cell belongs to, or at least an iterator that iterates over all the Cells in a subsection. The purpose of this is to provide an easy way to iterate through the subsection to enforce the Sudoku rules. I'm stuck fighting the borrow checker on this though. How can I do this?

fn section(&mut self, x: usize, y: usize) -> [[&mut Cell; 3]; 3] {
    let x = x - x%3;
    let y = y - y%3;
    // (0..3).into_iter().map(|n| self.grid[&x + n][y..y+3]).collect()
    [[&mut self.grid[x][y], &mut self.grid[x+1][y], &mut self.grid[x+2][y]],
     [&mut self.grid[x][y+1], &mut self.grid[x+1][y+1], &mut self.grid[x+2][y+1]],
     [&mut self.grid[x][y+2], &mut self.grid[x+1][y+2], &mut self.grid[x+2][y+2]]]
}

Use the matrix from nalgebra.

1 Like

So many neat helper APIs still unstable :neutral_face:

#![feature(array_methods)]
#![feature(slice_as_chunks)]

struct S {
    grid: [[Cell; 9]; 9],
}
impl S {
    // this returns a slightly different type, cutting down on the number of references
    // (array of reference to array of cells)
    fn section_version1(&mut self, x: usize, y: usize) -> [&mut [Cell; 3]; 3] {
        let x = x / 3;
        let y = y / 3;

        self.grid.as_chunks_mut().0[x]
            .each_mut()
            .map(|row| &mut row.as_chunks_mut().0[y])
    }
    // this returns the exact type as in the question
    // (array of array of references to single cells)
    fn section_version2(&mut self, x: usize, y: usize) -> [[&mut Cell; 3]; 3] {
        let x = x / 3;
        let y = y / 3;

        self.grid.as_chunks_mut().0[x]
            .each_mut()
            .map(|row| row.as_chunks_mut().0[y].each_mut())
    }
}

Edit: Of course, stable ways do exist, too :slight_smile:

struct S {
    grid: [[Cell; 9]; 9],
}
impl S {
    // this returns a slightly different type, cutting down on the number of references
    // (array of reference to array of cells)
    fn section_version1(&mut self, x: usize, y: usize) -> [&mut [Cell; 3]; 3] {
        let x = x - x % 3;
        let y = y - y % 3;
        let [r1, r2, r3] = &mut self.grid[x..][..3] else {
            unreachable!()
        };
        [r1, r2, r3].map(|r| (&mut r[y..][..3]).try_into().unwrap())
    }
    // this returns the exact type as in the question
    // (array of array of references to single cells)
    fn section_version2(&mut self, x: usize, y: usize) -> [[&mut Cell; 3]; 3] {
        let x = x - x % 3;
        let y = y - y % 3;
        let [r1, r2, r3] = &mut self.grid[x..][..3] else {
            unreachable!()
        };
        [r1, r2, r3].map(|r| {
            let [c1, c2, c3] = &mut r[y..][..3] else {
                unreachable!()
            };
            [c1, c2, c3]
        })
    }
}
2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.