C# 数独中裸三元组的求解

C# 数独中裸三元组的求解,c#,.net,math,sudoku,C#,.net,Math,Sudoku,我希望我在大学时多注意数学课。:) 如何实现裸三元组的这个数学公式 裸三元组 取三个单元C={c1,c2,c3},它们共享一个单位U。取三个数字 N={n1,n2,n3}。如果C中的每个单元格都有一个候选ci⊆ N然后我们可以删除所有 镍∈ N来自U中的其他细胞** 我有一个方法,它以一个单位(例如一个框、一行或一列)作为参数。 该单元包含9个单元格,因此我需要一次比较3个单元格的所有组合,可能需要将它们放入堆栈或集合中进行进一步计算 下一步是将这些3个细胞的组合一个接一个地进行,并将它们的候选

我希望我在大学时多注意数学课。:)

如何实现裸三元组的这个数学公式

裸三元组
取三个单元C={c1,c2,c3},它们共享一个单位U。取三个数字 N={n1,n2,n3}。如果C中的每个单元格都有一个候选ci⊆ N然后我们可以删除所有 镍∈ N来自U中的其他细胞**

我有一个方法,它以一个单位(例如一个框、一行或一列)作为参数。 该单元包含9个单元格,因此我需要一次比较3个单元格的所有组合,可能需要将它们放入堆栈或集合中进行进一步计算

下一步是将这些3个细胞的组合一个接一个地进行,并将它们的候选者与3个数字进行比较。同样,这3个数字可以是1到9之间的任意可能组合。这就是我所需要的

但是我该怎么做呢?我会得到多少个组合?对于单元格,我是否得到3 x 9=27个组合,然后对于数字(N)得到相同的组合

在经典的C#循环中,您将如何解决这个问题?请不要用Lambda表达,我已经够糊涂了:)

代码: 为了在这里代表他们,我不得不缩短课程

public class Cell : INotifyPropertyChanged
    {

public ObservableCollection<ObservableCollection<Candidate>> CandidateActual {...}

public int Id { ... }

//Position of the Cell inside a box if applicable
public int CellBoxPositionX { get; private set; }  
public int CellBoxPositionY { get; private set; }

//Position of the Cell inside the game board
public int CellBoardPositionX { get; private set; }
public int CellBoardPositionY { get; private set; }

//Position of the Box inside the game board
public int BoxPositionX { get; private set; }
public int BoxPositionY { get; private set; }

public int CountCandidates { ... }    
public int? Value { ...}

public Candidate this[int number]
        {
            get
            {
                if (number < 1 || number > PossibleValues.Count)
                {
                    throw new ArgumentOutOfRangeException("number", number, "Invalid Number Index");
                }

                switch (number)
                {
                    case 1:
                        return CandidateActual[0][0];
                    case 2:
                        return CandidateActual[0][1];
                    case 3:
                        return CandidateActual[0][2];
                    case 4:
                        return CandidateActual[1][0];
                    case 5:
                        return CandidateActual[1][1];
                    case 6:
                        return CandidateActual[1][2];
                    case 7:
                        return CandidateActual[2][0];
                    case 8:
                        return CandidateActual[2][1];
                    case 9:
                        return CandidateActual[2][2];
                    default:
                        return null;
                }
            }
        }
}
框:

public class Box : INotifyPropertyChanged
    {

public ObservableCollection<ObservableCollection<Cell>> BoxActual { ... }

public Cell this[int row, int column]
        {
            get
            {
                if(row < 0 || row >= BoxActual.Count)
                {
                    throw new ArgumentOutOfRangeException("row", row, "Invalid Row Index");
                }
                if(column < 0 || column >= BoxActual.Count)
                {
                    throw new ArgumentOutOfRangeException("column", column, "Invalid Column Index");
                }
                return BoxActual[row][column];
            }
        }
}
公共类框:INotifyPropertyChanged
{
公共可见收集框实际{…}
公共单元格此[int行,int列]
{
得到
{
if(行<0 | |行>=BoxActual.Count)
{
抛出新ArgumentOutOfRangeException(“行”,行,“无效行索引”);
}
if(列<0 | |列>=BoxActual.Count)
{
抛出新ArgumentOutOfRangeException(“列”,列,“无效列索引”);
}
返回框实际[行][列];
}
}
}
董事会

public class Board : INotifyPropertyChanged 
    {

 public ObservableCollection<ObservableCollection<Box>> GameBoard {...}

public Cell this[int boardRowPosition, int boardColumnPosition]
        {
            get
            {
                int totalSize = GameBoard.Count*GameBoard.Count();
                if (boardRowPosition < 0 || boardRowPosition >= totalSize) 
                    throw new ArgumentOutOfRangeException("boardRowPosition", boardRowPosition, "Invalid boardRowPosition index");
                if (boardColumnPosition < 0 || boardColumnPosition >= totalSize)
                    throw new ArgumentOutOfRangeException("boardColumnPosition", boardColumnPosition, "Invalid boardColumnPosition index");
                return
                    GameBoard[boardRowPosition/GameBoard.Count][boardColumnPosition/GameBoard.Count][
                        boardRowPosition%GameBoard.Count, boardColumnPosition%GameBoard.Count];
            }
        }



        public Box this[int boardRowPosition, int boardColumnPosition, bool b]
        {
            get
            {
                int totalSize = GameBoard.Count * GameBoard.Count();
                if (boardRowPosition < 0 || boardRowPosition >= totalSize)
                    throw new ArgumentOutOfRangeException("boardRowPosition", boardRowPosition, "Invalid boardRowPosition index");
                if (boardColumnPosition < 0 || boardColumnPosition >= totalSize)
                    throw new ArgumentOutOfRangeException("boardColumnPosition", boardColumnPosition, "Invalid boardColumnPosition index");
                return
                    GameBoard[boardRowPosition / GameBoard.Count][boardColumnPosition / GameBoard.Count];
            }
        }
}
公共类板:INotifyPropertyChanged
{
公共可观测收集游戏板{…}
公共单元格此[int boardRowPosition,int boardColumnPosition]
{
得到
{
int totalSize=GameBoard.Count*GameBoard.Count();
如果(boardRowPosition<0 | | boardRowPosition>=总尺寸)
抛出新ArgumentOutOfRangeException(“boardRowPosition”,boardRowPosition,“无效的boardRowPosition索引”);
if(boardColumnPosition<0 | | boardColumnPosition>=总大小)
抛出新ArgumentOutOfRangeException(“boardColumnPosition”,boardColumnPosition,“无效的boardColumnPosition索引”);
返回
GameBoard[boardRowPosition/GameBoard.Count][boardColumnPosition/GameBoard.Count][
boardRowPosition%GameBoard.Count,boardColumnPosition%GameBoard.Count];
}
}
公共框此[int boardRowPosition,int boardColumnPosition,bool b]
{
得到
{
int totalSize=GameBoard.Count*GameBoard.Count();
如果(boardRowPosition<0 | | boardRowPosition>=总尺寸)
抛出新ArgumentOutOfRangeException(“boardRowPosition”,boardRowPosition,“无效的boardRowPosition索引”);
if(boardColumnPosition<0 | | boardColumnPosition>=总大小)
抛出新ArgumentOutOfRangeException(“boardColumnPosition”,boardColumnPosition,“无效的boardColumnPosition索引”);
返回
GameBoard[boardRowPosition/GameBoard.Count][boardColumnPosition/GameBoard.Count];
}
}
}

非常感谢您的帮助,

Psuedo代码算法;我的C有点生锈了

我建议从候选值中找出所有可能的三个数字组合。根据您有多少候选人(由n!/(3!*(n-3)!)给出),可以有6到504个这样的组合

对于每个单元,循环检查单元中的所有单元,看看它们是否符合组合中没有数字的条件。如果某个组合有三个或更多,则可以应用它

combos = (array containing 3-long combination of candidates)
for each combo in combos                 # iterate through every combo
  matches = new array                    # initialize a blank array
  for each cell in unit
    if (cell does not contain candidates other than the ones in your current combo)
      matches.add(cell)                  # this is a match!
    end
  end

  if matches.size >= 3                   # naked triple found! (three matches for given combo)
    for each cell in unit
      if (cell is not in matches)
        (delete every candidate in current combo in this cell)
      end
    end
  end
  delete matches                         # clear up memory
end
希望这有帮助!如果你需要的话,我会把这段代码C-ify;我一直想复习一下我的C

另外,如果你还不知道的话,有一种更简单的方法可以用计算机来解决数独难题,它不涉及任何逻辑中的手动编程。但我认为你这样做是很高尚的


生成所有可能组合的数组

有很多方法可以做到这一点,也许有最好的方法;我自己也没有做过任何认真的研究。我推荐谷歌:。。。我真的找到了自己


一定要包括一个检查,以确保您的候选人人数是适当的。对于n=3,只有一个可能的候选组合,您的算法应该为您找到它。对于n=1和n=2,裸三元组甚至不适用。

您的问题不完整。我们需要更多地了解您现有的代码(例如,单元和单元的类定义,以及如何维护候选代码等)。否则,这只是一个逻辑难题,根本不是一个真正的编程问题。希望我的代码片段能有所帮助。谢谢你,编程是一个挑战;o) 您的
switch
语句可以简化为
returncandidateActual[(number-1)/3][(number-1)%3]谢谢Gabe,这也是一个很好的提示。您是如何想到%3的?:)非常感谢您提供了这段优秀的伪代码。这很有道理,帮助我理解。尤其是阶乘的使用非常好。我仍然很难理解这一步:combos=(包含3个候选组合的数组)我还不知道一种有效的方法。你能详细说明一下吗?非常感谢你/(c-3)!,它是否适用于单位内所有可能的候选人?但是
combos = (array containing 3-long combination of candidates)
for each combo in combos                 # iterate through every combo
  matches = new array                    # initialize a blank array
  for each cell in unit
    if (cell does not contain candidates other than the ones in your current combo)
      matches.add(cell)                  # this is a match!
    end
  end

  if matches.size >= 3                   # naked triple found! (three matches for given combo)
    for each cell in unit
      if (cell is not in matches)
        (delete every candidate in current combo in this cell)
      end
    end
  end
  delete matches                         # clear up memory
end