I wondered if anyone has any ideas to make this cleaner or more efficient.  Mostly this was an exercise to generate the data once (So speed really isn't too important, but I'd love to see what techniques you could think of)This is an algorithm I derived and implemented without external guidance of any kind, so I'm asking for guidance now.This does give the output I am expecting, I validated it with a recursive implementation that I made first.I'm thinking this might be helpful in validating solutions, or in generating new boards.For the Sudoku table:--1 --- ------ 1-- ------ --- --1--- -1- ---1-- --- ------ --- 1----- --- -1---- --1 ----1- --- ---1 would be represented by the array: 238316751.  In the first 9 cell box, the 1 is at position 2 in the array of that box.///This outputs the valid pointers///for example 327742830 is valid, a number could be in pos 3 of cell 0, 2 in cell 1, etc///  So arrays are compatable when no columns have the same number in them///  A starting board with a high number of compatable arrays would be very difficult i believepublic IEnumerable<string> OutputArrayPoints(){    return OutputArrayPoints(new int[9]);}//Will contain the cell indexes that are not excluded by other cells alreadyint[][] ToCheck = new int[9][];//Pointers to the current cell indexes in useint[] ToCheckPointers = new int[9];//arrayPoints will contain the current value to return//Really it should be equal to loop through ToCheck[c][ToCheckPointers[c]]public IEnumerable<string> OutputArrayPoints(int[] arrayPoints){    //This loop is basically a depth first search    //ToCheck gets filled with possible values for each cell,    //  and the lowest pointer gets incremented until it runs out,    //  then moves up a cell to go down a different path    for (int c = 0; c >= 0; /*++c*/)    {        if (c == 8 && ToCheck[c] != null && ToCheckPointers[c] < ToCheck[c].Length)        {            //Should be a valid solution, yield it            yield return GetResult(arrayPoints);            ++ToCheckPointers[c];        }        else if (c < 9 && ToCheck[c] != null && ToCheckPointers[c] < ToCheck[c].Length)        {            //Fill this cell of arrayPointers, and move to the next            arrayPoints[c] = ToCheck[c][ToCheckPointers[c]];            ++c;        }        else if (ToCheck[c] != null && ToCheckPointers[c] == ToCheck[c].Length)        {            //ToCheck at this level has been fully processed, clear it out            ToCheck[c] = null;            //Step up a cell to start processing the next            --c;            //if c is less than 0, we have gone through every option            if (c == -1) yield break;            //Increase the pointer I'm pointing at            ++ToCheckPointers[c];        }        else if (c < 9 && ToCheck[c] == null)        {            //Fill any empty ones            ToCheck[c] = CellsToCheck(arrayPoints, c).ToArray();            ToCheckPointers[c] = 0;            //lazy? (could this be in a cleaner spot? or do I need to store arrayPoints at all?):            arrayPoints[c] = ToCheck[c][ToCheckPointers[c]];            if (c < 8) ++c;        }    }}//Return the cells that are possible given the other positions takenIEnumerable<int> CellsToCheck(int[] arrayPoints, int depth){    int rowSkip1 = (depth % 3) > 0 ? arrayPoints[depth - 1] / 3 : -1;    int rowSkip2 = (depth % 3) > 1 ? arrayPoints[depth - 2] / 3 : -1;    int colSkip1 = depth > 2 ? arrayPoints[depth - 3] % 3 : -1;    int colSkip2 = depth > 5 ? arrayPoints[depth - 6] % 3 : -1;    for (int i = 0; i < 3; ++i)    {        for (int j = 0; j < 3; ++j)        {            if ((rowSkip1 != i && rowSkip2 != i)                && (colSkip1 != j && colSkip2 != j)) yield return j + i*3;        }    }}//Return a string representationstring GetResult(IEnumerable<int> cells){    return string.Join(, cells.Select(i => i.ToString()).ToArray());}
Sudoku Valid Arangements Permutations Enumerator
c#;performance;algorithm;sudoku