在Sudoku中解决裸体三重奏

Hou*_*man 5 .net c# math sudoku

我希望我更加关注Uni的数学课程.:)

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

Naked Triples
取三个单元格C = {c1,c2,c3}共享一个单位U.取三个数字N = {n1,n2,n3}.如果C中的每个单元都有候选ci⊆N那么我们就可以从U中的其他单元中删除所有的ni∈N.**

我有一个方法,取一个单位(例如一个Box,一行或一列)作为参数.该单元包含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;
                }
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

候选人

public class Candidate : INotifyPropertyChanged
    {

        private int? _value;

        public int? Value { ... }

    }
Run Code Online (Sandbox Code Playgroud)

框:

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];
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

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];
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

非常感谢您的帮助,

Jus*_* L. 2

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

我建议从候选值中找到所有可能的三数组合。可以有 6 到 504 个这样的组合,具体取决于您有多少候选者(由 n!/(3!*(n-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
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!如果您需要的话,我将 C-ify 这段代码;反正我一直想温习一下我的C。

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


生成所有可能组合的数组

有很多方法可以做到这一点,并且可能有一种最好的方法;我自己还没有对此进行过认真的研究。我推荐谷歌:组合算法......我自己实际上在C中找到了一种解决方案

请务必附上支票,以确保您的候选人数量合适。对于 n=3,只有一种可能的候选组合,您的算法应该为您找到它。对于 n=1 和 n=2,裸三元组甚至不适用。