【发布时间】:2009-01-26 20:29:50
【问题描述】:
在我工作的地方,我们仍然使用 .Net 2.0,但我对 3.0/3.5 的东西有点熟悉。我想在 C# 中使用 linq/lambda 表达式进行一些练习,所以我编写了一个简单的数独求解器,使用了很多通用的 List<T> 和 lambda 表达式以及它提供的聚合方法。
在我的求解器中,我在求解器算法的顶部有这个:
private Puzzle RecursiveSolve(Puzzle p, int idx)
{
// start with simple filter to narrow down recursive paths
// puzzle is still solved without this line, but it takes at least 20x longer
while( p.board.Any(cell => cell.FilterPossibles()) ); // while(); <- empty while loop is intentional
您可能会说,这是一个简单的递归算法,但我确实对其进行了一些优化以将运行时间降低到合理的水平(我在 google 上找到的最难的谜题是 3.6 秒)。
要理解sn-p,Puzzle.board 是List<Cell>,Cell.FilterPossibles() 将每个单元格的可能值与同一行、列和 3x3 框中的其他单元格的值进行比较,看看它是否可以消除任何。如果它下降到一种可能,它会设置单元格的值并返回 true。否则返回false。这样,只要电路板上至少有一个单元在上一次迭代中发生变化(已解决),while 循环就会运行。
我担心的是 while 循环是空的。它相当于一种代码气味,并告诉我我可能遗漏了一些东西。有没有办法可以把它写成一个语句,而不是一个循环?
作为这个项目的结果,我实际上有一大堆问题:(我是否在不知不觉中实现了一些我可以告诉编译器的接口?我的函数选择通常合适吗?我有很多布尔方法来简化表达式:这怎么可能更好?我怎样才能更好地构建它以使用不可变的 Puzzle/Cell 对象?)但这是目前最困扰我的一个。
【问题讨论】: