[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[挑战]解数独程序与数独题目生成

本帖最后由 523066680 于 2017-9-24 16:14 编辑

以下是从某网站提取的5种难度的数独游戏(难度从1-5,循着网站是可以找到答案的):
001000008800010532750024090005302060670500004010780900098053406426179803537460219
503092000700000008006007310020600000065000730007043500000706102070000800400009000
700306000000000050060000018000081000000000000900000200000200900050400000080000007
030000001200806000000005000000000000000000650043070000600002080090000000000010003
010000200300800000000504000800090000000070120500000000000000000020130000400000005

写程序对这五个数独题目求解,并计算解每道题的时间消耗。
编程语言:不限

------------------------------------------ 2017-09-18补充 ------------------------------------------
如果解决上面五道题耗时不超过1秒,可以尝试批量解题库中的题,并统计时间消耗。

题库下载:http://523066680.ys168.com/
Perl/数独/数独题库200801-201709_含答案.zip

题库按键值对存储,key 是时间戳,value 中前81个字符是题目,后81个字符是唯一答案。
nd0 - nd4 表示不同的难度。

本帖最后由 523066680 于 2017-9-14 16:57 编辑

脚本,每填入一个数字,重新判断并缩小范围,第四道数独花了五百多秒 ……
  1. 2,6,1,9,3,5,7,4,8
  2. 8,4,9,6,1,7,5,3,2
  3. 7,5,3,8,2,4,6,9,1
  4. 9,8,5,3,4,2,1,6,7
  5. 6,7,2,5,9,1,3,8,4
  6. 3,1,4,7,8,6,9,2,5
  7. 1,9,8,2,5,3,4,7,6
  8. 4,2,6,1,7,9,8,5,3
  9. 5,3,7,4,6,8,2,1,9
  10. Game level: 1, time used: 0.000s
  11. 8,3,6,9,4,7,5,2,1
  12. 2,5,1,8,3,6,4,9,7
  13. 4,7,9,1,2,5,8,3,6
  14. 9,6,8,2,5,1,3,7,4
  15. 1,2,7,4,8,3,6,5,9
  16. 5,4,3,6,7,9,2,1,8
  17. 6,1,4,3,9,2,7,8,5
  18. 3,9,5,7,6,8,1,4,2
  19. 7,8,2,5,1,4,9,6,3
  20. Game level: 4, time used: 537.594s
复制代码
--------------- 2017-09-14 蜜汁 Trick ----------------
  1. 8,3,6,9,4,7,5,2,1
  2. 2,5,1,8,3,6,4,9,7
  3. 4,7,9,1,2,5,8,3,6
  4. 9,6,8,2,5,1,3,7,4
  5. 1,2,7,4,8,3,6,5,9
  6. 5,4,3,6,7,9,2,1,8
  7. 6,1,4,3,9,2,7,8,5
  8. 3,9,5,7,6,8,1,4,2
  9. 7,8,2,5,1,4,9,6,3
  10. [Finished in 2.2s]
复制代码

TOP

本帖最后由 523066680 于 2017-9-14 17:44 编辑

回复 3# CrLf

    也不是完全的暴力跑,前三项规则已经应用了,后两项还没有试过。题目的前两道数独秒出结果,第四道耗时很长。

TOP

本帖最后由 523066680 于 2017-9-15 09:53 编辑

回复 5# slore

题库在这个网站抓的 免费的在线数独
http://bbs.bathome.net/thread-45401-1-1.html

http://523066680.ys168.com/
Perl/数独/数独题库200801-201709_含答案.zip

难度分为 入门,初级,中级,高级,骨灰级。1楼的题来自每个等级的第一道题目。这个等级划分我也觉得有点问题……  
初级的比如:数独 - 2008年1月6日 - 初级
000600500001007000004000000050002000060000800000001007080900000000500001007000004
比同等级的其他题目明显数字要少,可选数字可能性更多。

TOP

Rosettacode 有一段 Perl 代码非常简短,不过这段代码因为简短而牺牲了性能,有很多冗余的循环。
http://rosettacode.org/wiki/Sudoku#Perl
1

评分人数

TOP

本帖最后由 523066680 于 2017-9-16 10:13 编辑

初始版本
  1. =info
  2.     解数独 初版
  3.     523066680 2017-09
  4. =cut
  5. use IO::Handle;
  6. use Time::HiRes qw/time/;
  7. STDOUT->autoflush(1);
  8. my @games =
  9. qw/
  10.     001000008800010532750024090005302060670500004010780900098053406426179803537460219
  11.     503092000700000008006007310020600000065000730007043500000706102070000800400009000
  12.     700306000000000050060000018000081000000000000900000200000200900050400000080000007
  13.     030000001200806000000005000000000000000000650043070000600002080090000000000010003
  14.     010000200300800000000504000800090000000070120500000000000000000020130000400000005
  15. /;
  16. our @unsolve;
  17. our $block = [];  #区块引用
  18. my $mat = [[]];
  19. my $level = 0;
  20. my $time_a;
  21. #创建区块引用,以便于操作
  22. make_block_refs( $block, $mat );
  23. while ( $level <= $#games )
  24. {
  25.     #字符串转矩阵
  26.     str_to_mat( $games[$level] , $mat );
  27.     $time_a = time();
  28.     #设置 @unsolve 数组,存储空缺元素的坐标
  29.     set_unsolve_array($mat);
  30.     solve($mat, 0);
  31.    
  32.     print_mat($mat);
  33.     printf "Game level: %d, time used: %.3fs\n\n", $level+1, time() - $time_a;
  34.     $level++;
  35. }
  36. sub solve
  37. {
  38.     my ($mat, $prev, $lv) = @_;
  39.     my @possible;
  40.     my ($row, $col);
  41.     my $current;
  42.     for my $i ( $prev .. $#unsolve )
  43.     {
  44.         ($row, $col) = @{$unsolve[$i]};
  45.         if ( $mat->[$row][$col] == 0 )
  46.         {
  47.             $current = $i;
  48.             @possible = get_possible_num( $mat, $row, $col );
  49.             last;
  50.         }
  51.     }
  52.     if ( not defined $current ) { return 1 }
  53.     else
  54.     {   
  55.         return 0 if ( $#possible < 0 )
  56.     }
  57.     my $res = 0;
  58.     for my $p ( @possible )
  59.     {
  60.         $mat->[ $row ][ $col ] = $p;
  61.         $res = solve($mat, $current+1, $lv+1);
  62.         last if ($res == 1);
  63.     }
  64.     #使对应单元恢复为0 否则影响递归判断
  65.     $mat->[$row][$col] = 0 if ($res == 0) ;
  66.     return $res;
  67. }
  68. sub get_possible_num
  69. {
  70.     our ($block, %hash);
  71.     my ($mat, $row, $col) = @_;
  72.     my %possible = (1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9);
  73.     #排除元素
  74.     for my $n ( 0 .. 8 )
  75.     {
  76.         delete $possible{ $mat->[$n][$col] };
  77.         delete $possible{ $mat->[$row][$n] };
  78.         delete $possible{ ${$block->[$row/3][$col/3][$n]} };
  79.     }
  80.     return sort keys %possible;
  81. }
  82. sub get_possible_num_2
  83. {
  84.     our ($block, %hash);
  85.     my ($mat, $row, $col) = @_;
  86.     my @possible = (0,1,2,3,4,5,6,7,8,9);
  87.     #区块坐标
  88.     my $blockrow = int($row/3);
  89.     my $blockcol = int($col/3);
  90.     #排除元素
  91.     for my $n ( 0 .. 9 )
  92.     {
  93.         $possible[ $mat->[$n][$col] ] = 0;
  94.         $possible[ $mat->[$row][$n] ] = 0;
  95.         $possible[ ${$block->[$blockrow][$blockcol][$n]} ] = 0;
  96.     }
  97.     return grep { $_ } @possible;
  98. }
  99. sub set_unsolve_array
  100. {
  101.     our ( @unsolve );
  102.     my ($mat) = @_;
  103.     @unsolve = ();
  104.     for my $row ( 0..8 )
  105.     {
  106.         for my $col ( 0..8 )
  107.         {
  108.             if ( $mat->[$row][$col] == 0 )
  109.             {
  110.                 push @unsolve, [ $row, $col, [get_possible_num( $mat, $row, $col )] ];
  111.             }
  112.         }
  113.     }
  114.     #根据可选数字的数量由少到多排序
  115.     #@unsolve = sort { $#{$a->[2]} <=> $#{$b->[2]} } @unsolve;
  116. }
  117. sub make_block_refs
  118. {
  119.     my ($block, $mat) = @_;
  120.     #将数独的九个宫对应的引用分组保存
  121.     for my $r ( 0..2 )
  122.     {
  123.         for my $c ( 0..2 )
  124.         {
  125.             for my $rr ( $r*3 .. $r*3+2 )
  126.             {
  127.                 for my $cc ( $c*3 .. $c*3+2 )
  128.                 {
  129.                     push @{ $block->[$r][$c] }, \$mat->[$rr][$cc];
  130.                 }
  131.             }
  132.         }
  133.     }
  134. }
  135. sub str_to_mat
  136. {
  137.     my ( $str, $mat ) = @_;
  138.     my $idx = 0;
  139.     for my $row ( 0 .. 8 )
  140.     {
  141.         for my $col ( 0 .. 8 )
  142.         {
  143.             $mat->[$row][$col] = substr( $str, $idx++, 1 );
  144.         }
  145.     }
  146. }
  147. sub print_mat
  148. {
  149.     my ($mat) = @_;
  150.     grep { print join(",", @{$mat->[$_]} ),"\n" } ( 0..8 );
  151. }
复制代码
Game level: 1, time used: 0.001s
Game level: 2, time used: 0.002s
Game level: 3, time used: 11.373s
Game level: 4, time used: 432.737s
Game level: 5, time used: 24.571s

结果相当难看,有空试试 Dancing Links

TOP

本帖最后由 523066680 于 2017-9-18 16:27 编辑

最近换了个方案,遇到难度高的题目时比原来的方案快得多(但还是没有Rubyish @Chinaunix 的代码快)

给定一个题目,判断 1-9 每个数字的全局分布情况(可能性)。
比如1可能分布的情况有6种,测试每一种,把9个1全部填入数独,然后继续测试其他数字的分布。

题目
140968000000000900600057300000000007300000840000196500070000405406010030000000000

数字1的可能分布情况
140968000000001900600057310010000007300000841000196500071000405406010030000000100
140968000000001900600057310000000107310000840000196500071000405406010030000000001
140968000000001900600057301000000107310000840000196500071000405406010030000000010
140968000000001900600057301000000107310000840000196500070000415406010030001000000
140968000000001900600057301000000107301000840000196500070000415406010030010000000
140968000000001900600057301000000017310000840000196500071000405406010030000000100

完整代码:
  1. =info
  2.     方案 - 遍历数字分布情况
  3.     523066680 2017-09
  4. =cut
  5. use File::Slurp;
  6. use IO::Handle;
  7. STDOUT->autoflush(1);
  8. # my $gamedata = eval read_file("../sudoku_nd1.txt");
  9. # grep { push @games, $gamedata->{$_} } sort keys %$gamedata;
  10. @games =
  11. qw/
  12.     001000008800010532750024090005302060670500004010780900098053406426179803537460219
  13.     503092000700000008006007310020600000065000730007043500000706102070000800400009000
  14.     700306000000000050060000018000081000000000000900000200000200900050400000080000007
  15.     030000001200806000000005000000000000000000650043070000600002080090000000000010003
  16.     010000200300800000000504000800090000000070120500000000000000000020130000400000005
  17. /;
  18. our @order;
  19. our $answer_mat = [[]];
  20. my $mat;
  21. my $res;
  22. my $allcase;
  23. my $answer_str;
  24. #坐标对应区块位置的表
  25. our @blk = map { int($_ / 3) } ( 0..8 );
  26. while ( $index <= $#games )
  27. {
  28.     $mat = [[]];
  29.     $time_a = time();
  30.     str_to_mat( $games[$index] , $mat );
  31.     $allcase = [ map { [] } (0..9) ];
  32.     grep { possible_mat($mat, $_, $allcase->[$_], 0) } (1..9);
  33.     @order = sort { $#{$allcase->[$a]} <=> $#{$allcase->[$b]} } ( 0 .. 9 );
  34.     $res = recursive( $mat, 1 ); #起点为1,下标 0占位
  35.     if ($res == 1)
  36.     {
  37.         print_mat_inline( $answer_mat );
  38.     }
  39.     else { die "false\n" }
  40.     printf "Game index: %d, time used: %.3fs\n\n", $index, time() - $time_a;
  41.     $index++;
  42. }
  43. sub recursive
  44. {
  45.     our (@order, $answer_mat);
  46.    
  47.     my ( $mat, $lv ) = @_;
  48.     my @case;
  49.     if ( $lv > 9 )
  50.     {
  51.         $answer_mat = $mat;
  52.         return 1;
  53.     }
  54.     $target = $order[$lv];
  55.     possible_mat($mat, $target, \@case, 0);
  56.     my $t_mat = [[]];
  57.     my $res = 0;
  58.     for my $s ( @case )
  59.     {
  60.         str_to_mat( $s, $t_mat );
  61.         $res = recursive( $t_mat, $lv+1 );
  62.         last if ($res == 1);
  63.     }
  64.     return $res;
  65. }
  66. sub possible_mat
  67. {
  68.     my ( $mat, $target, $aref, $lv ) = @_;
  69.     # level means row
  70.     my $str;
  71.     if ($lv == 9)
  72.     {
  73.         $count++;
  74.         push @$aref, mat_to_str($mat);
  75.         return 1;
  76.     }
  77.     my @cols = get_possible_column( $mat, $lv, $target );
  78.     my $res = 0;
  79.     my $ever;
  80.     for my $c ( @cols )
  81.     {
  82.         $ever = $mat->[$lv][$c];
  83.         $mat->[$lv][$c] = $target;
  84.         $res = possible_mat( $mat, $target, $aref, $lv+1 );
  85.         $mat->[$lv][$c] = $ever;
  86.     }
  87.     return $res;
  88. }
  89. sub get_possible_column
  90. {
  91.     our @blk;
  92.     my ( $mat, $row, $target ) = @_;
  93.     my @cols = ( 0..8 );
  94.     for my $c ( 0..8 )
  95.     {
  96.         #如果当前行已经存在这个数字,则直接返回这个数字的位置。
  97.         if ( $mat->[$row][$c] == $target )
  98.         {
  99.             return ( $c );
  100.         }
  101.         elsif ( $mat->[$row][$c] != 0 )
  102.         {
  103.             $cols[$c] = -1;
  104.         }
  105.         for my $r ( 0..8 )
  106.         {
  107.             if ( $mat->[$r][$c] == $target )
  108.             {
  109.                 $cols[$c] = -1;
  110.                 if ( $blk[$r] == $blk[$row] )
  111.                 {
  112.                     $cols[ $blk[$c] * 3 + 0] = -1;
  113.                     $cols[ $blk[$c] * 3 + 1] = -1;
  114.                     $cols[ $blk[$c] * 3 + 2] = -1;
  115.                 }
  116.             }
  117.         }
  118.     }
  119.     return grep { $_ != -1 } @cols;
  120. }
  121. sub str_to_mat
  122. {
  123.     my ( $str, $mat ) = @_;
  124.     my $idx = 0;
  125.     for my $row ( 0 .. 8 )
  126.     {
  127.         for my $col ( 0 .. 8 )
  128.         {
  129.             $mat->[$row][$col] = substr( $str, $idx++, 1 );
  130.         }
  131.     }
  132. }
  133. sub mat_to_str
  134. {
  135.     my ( $mat ) = @_;
  136.     return join("", map { join("", @{$mat->[$_]} ) } (0..8));
  137. }
  138. sub print_mat
  139. {
  140.     my ($mat) = @_;
  141.     grep { print join(",", @{$mat->[$_]} ),"\n" } ( 0..8 );
  142. }
  143. sub print_mat_inline
  144. {
  145.     my ($mat) = @_;
  146.     grep { print join("", @{$mat->[$_]} ),"" } ( 0..8 );
  147.     print "\n";
  148. }
复制代码
261935748849617532753824691985342167672591384314786925198253476426179853537468219
Game index: 0, time used: 0.000s

513892467749361258286457319324675981165928734897143526958736142672514893431289675
Game index: 1, time used: 0.000s

718356492492817653563924718624781539835692174971543286147238965356479821289165347
Game index: 2, time used: 0.000s

836947521251836497479125836968251374127483659543679218614392785395768142782514963
Game index: 3, time used: 0.000s

718963254354827961296514873872391546943675128561248739187456392625139487439782615
Game index: 4, time used: 1.000s


跑完 sudoku_nd0.txt 三千多道题需要十多秒,跑完 sudoku_nd4.txt 大约六百秒。
CU Rubyish 的代码,跑完 nd0 零点几秒,nd4 一百多秒

TOP

回复 11# slore

    线程的方案留到最后,单线程仍然有更快的算法,快到解 sudoku_nd4.txt 所有题只要十多秒。

TOP

本帖最后由 523066680 于 2017-9-20 20:34 编辑

回复 15# slore

对于回溯法,有一个优化很有效果。示意图(注意除了中间有个独立的候选数字2,右上角还有个框选的数字8):


程序给定的单元候选数字中,大多单元格有多个可选数字,但是可以进一步排除。例如:
如果累计一行中的所有候选数,某个数字只出现一次,那么这个数字就是必选数字。同样,一列、一宫(3x3 block)的区域内也是如此。

我为程序增加了一个while 循环,反复筛选并填充唯一的数字,直到再也没有,然后才开始递归解题。

Sudoku:
3,0,0,0,1,0,0,0,0
0,0,0,0,0,0,0,9,0
0,8,0,2,0,0,0,0,6
0,0,0,0,7,0,3,4,0
0,5,6,0,0,0,0,0,0
0,0,0,0,0,0,0,0,0
0,0,0,5,0,0,0,0,0
0,0,0,6,0,8,0,0,2
1,0,0,0,0,0,0,3,0

Fill only one possible cells
R:1 C:8 Fill:3
R:3 C:5 Fill:6
R:3 C:8 Fill:5
R:6 C:5 Fill:1
R:0 C:1 Fill:6
R:1 C:4 Fill:6
R:6 C:0 Fill:6
R:8 C:6 Fill:6
R:5 C:7 Fill:6
R:8 C:2 Fill:5
R:8 C:8 Fill:8
R:6 C:2 Fill:8
R:6 C:7 Fill:7

Result:
3,6,0,0,1,0,0,0,0
0,0,0,0,6,0,0,9,3
0,8,0,2,0,0,0,0,6
0,0,0,0,7,6,3,4,5
0,5,6,0,0,0,0,0,0
0,0,0,0,0,0,0,6,0
6,0,8,5,0,1,0,7,0
0,0,0,6,0,8,0,0,2
1,0,5,0,0,0,6,3,8

Solve:
3,6,9,4,1,5,2,8,7
2,4,1,8,6,7,5,9,3
5,8,7,2,9,3,4,1,6
8,1,2,9,7,6,3,4,5
9,5,6,3,8,4,7,2,1
4,7,3,1,5,2,8,6,9
6,3,8,5,2,1,9,7,4
7,9,4,6,3,8,1,5,2
1,2,5,7,4,9,6,3,8
time used: 0.211s

TOP

本帖最后由 523066680 于 2017-9-24 16:09 编辑

回复 19# bbaa

      对于题目和结果判断,你先用现成的题库弄上网站跑跑看?我前面发的题库分为5种难度等级,你可以随机抽取。
这些题只有一种答案,也都在文件里了,检验方便。(虽然这样提供了作弊条件,可以直接POST现有答案,不过也就是试试效果)

TOP

RE: [挑战]解数独程序与数独题目生成 —— Dancing Links 算法

本帖最后由 523066680 于 2017-10-10 14:25 编辑

Rosettacode 上面有一段js的示例,代码较长不粘贴了
http://rosettacode.org/wiki/Sudoku#JavaScript
效率是很高,但是实现细节有问题,某些题型会崩溃
  1. sudoku_nd3.txt
  2. //'7.56...19........89....8.....81.2.7...13..4.237...5.9.8.3..1.25...5....41........',
  3. //'.....4...7.......2.....61.....2.......4...3..8..79.6....78....9.36........1......',
  4. //'...3.1...49......638.......1.5..7.......9...8.........6...4...........5...3...71.',
  5. sudoku_nd4.txt
  6. //'......3......2.1..1.84.9.....7....2..3.6...7...6.7...8....5846.2........9..1.....',
  7. //'.....53..6.....5.8...1...2.45.8...1.3.....4.5..2.........2.18....7.3..6..2...4...',
  8. //'....9..3...5..2.4.7.94....13.1....98.4.9........8..6..2...13..7..36...151....9...',
复制代码
开始我以为是 js 限制递归层数太少,用Perl和C分别实现后发现主要还是和实现有关,递归回溯过程的数据处理写对了就不会有崩溃的情况。

顺便贴一些相关的:
Python 版DLX实现
http://www.cs.mcgill.ca/~aassaf9/python/algorithm_x.html
  1. #!/usr/bin/env python3
  2. # http://www.cs.mcgill.ca/~aassaf9/python/algorithm_x.html
  3. # Author: Ali Assaf <ali.assaf.mail@gmail.com>
  4. # Copyright: (C) 2010 Ali Assaf
  5. # License: GNU General Public License <http://www.gnu.org/licenses/>
  6. from itertools import product
  7. def solve_sudoku(size, grid):
  8.     R, C = size
  9.     N = R * C
  10.     X = ([("rc", rc) for rc in product(range(N), range(N))] +
  11.          [("rn", rn) for rn in product(range(N), range(1, N + 1))] +
  12.          [("cn", cn) for cn in product(range(N), range(1, N + 1))] +
  13.          [("bn", bn) for bn in product(range(N), range(1, N + 1))])
  14.     Y = dict()
  15.     for r, c, n in product(range(N), range(N), range(1, N + 1)):
  16.         b = (r // R) * R + (c // C) # Box number
  17.         Y[(r, c, n)] = [
  18.             ("rc", (r, c)),
  19.             ("rn", (r, n)),
  20.             ("cn", (c, n)),
  21.             ("bn", (b, n))]
  22.     X, Y = exact_cover(X, Y)
  23.     for i, row in enumerate(grid):
  24.         for j, n in enumerate(row):
  25.             if n:
  26.                 select(X, Y, (i, j, n))
  27.     for solution in solve(X, Y, []):
  28.         for (r, c, n) in solution:
  29.             grid[r][c] = n
  30.         yield grid
  31. def exact_cover(X, Y):
  32.     X = {j: set() for j in X}
  33.     for i, row in Y.items():
  34.         for j in row:
  35.             X[j].add(i)
  36.     return X, Y
  37. def solve(X, Y, solution):
  38.     if not X:
  39.         yield list(solution)
  40.     else:
  41.         c = min(X, key=lambda c: len(X[c]))
  42.         for r in list(X[c]):
  43.             solution.append(r)
  44.             cols = select(X, Y, r)
  45.             for s in solve(X, Y, solution):
  46.                 yield s
  47.             deselect(X, Y, r, cols)
  48.             solution.pop()
  49. def select(X, Y, r):
  50.     cols = []
  51.     for j in Y[r]:
  52.         for i in X[j]:
  53.             for k in Y[i]:
  54.                 if k != j:
  55.                     X[k].remove(i)
  56.         cols.append(X.pop(j))
  57.     return cols
  58. def deselect(X, Y, r, cols):
  59.     for j in reversed(Y[r]):
  60.         X[j] = cols.pop()
  61.         for i in X[j]:
  62.             for k in Y[i]:
  63.                 if k != j:
  64.                     X[k].add(i)
  65. grid = [
  66.     [0,0,0,4,0,2,0,0,0],
  67.     [0,0,0,0,0,5,0,0,3],
  68.     [1,0,0,0,7,0,0,9,6],
  69.     [6,0,0,0,3,0,0,0,0],
  70.     [0,0,0,0,0,0,2,0,0],
  71.     [0,0,4,0,0,0,7,0,0],
  72.     [0,0,0,0,9,0,0,0,0],
  73.     [0,0,0,0,0,0,0,0,1],
  74.     [0,0,5,7,0,4,0,0,0]]
  75. for solution in solve_sudoku((3, 3), grid):
  76.     print(*solution, sep='\n')
复制代码
跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题
算法实践——舞蹈链(Dancing Links)算法求解数独

17提示数的题库资源
四万多道17提示数的数独题
用C链表实现的DLX算法,加-O2编译优化,i7 CPU,printf不计入,解这四万多题只要3-6秒。
(参考算法实践——舞蹈链(Dancing Links)算法求解数独 最后一个评论,这个人用C重新实现,也是3秒。)
1

评分人数

TOP

本帖最后由 523066680 于 2017-10-17 11:00 编辑

正在学着用 github,代码已提交
https://github.com/vicyang/Sudoku/tree/master/Solver/DancingLinks

ChinaUnix 的rubyish把他的方案也写成了C版本,我在上面套了 fill_one_possible_num 函数 后,解sudoku17.txt 也是6秒,
在 i7 cpu 主机上面,3秒


Rubyish/solve_multiGame.c

TOP

返回列表