免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
论坛 程序设计 Perl 数独
最近访问板块 发新帖
查看: 3894 | 回复: 5
打印 上一主题 下一主题

数独 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-07-22 00:31 |只看该作者 |倒序浏览
本帖最后由 午夜凋零 于 2012-07-22 00:31 编辑

前阵子看新闻看到一个人号称创出来最难的数独,当时就产生了个想法,将数独中已经提供的数字作为输入,得出所有的元素。
整了两三天的时间,终于用perl实现了,感觉自己好弱啊。{:2_169:}
另一方面,虽然感觉自己很弱,但是完成一项想法的感觉还是挺爽的。
下面是代码,欢迎各位批评指正,希望不会被拍的太厉害。。。。
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;

  4. my @goal = (
  5.              [[8], [ ], [ ], [ ], [ ], [ ], [ ], [ ], [ ]],
  6.              [[ ], [ ], [3], [6], [ ], [ ], [ ], [ ], [ ]],
  7.              [[ ], [7], [ ], [ ], [9], [ ], [2], [ ], [ ]],
  8.              [[ ], [5], [ ], [ ], [ ], [7], [ ], [ ], [ ]],
  9.              [[ ], [ ], [ ], [ ], [4], [5], [7], [ ], [ ]],
  10.              [[ ], [ ], [ ], [1], [ ], [ ], [ ], [3], [ ]],
  11.              [[ ], [ ], [1], [ ], [ ], [ ], [ ], [6], [8]],
  12.              [[ ], [ ], [8], [5], [ ], [ ], [ ], [1], [ ]],
  13.              [[ ], [9], [ ], [ ], [ ], [ ], [4], [ ], [ ]]
  14.            );

  15. for my $i ( 0..8 ) { # fill empty element with 1..9
  16.     for my $j ( 0..8 ) {
  17.         $goal[$i]->[$j] = [qw(1 2 3 4 5 6 7 8 9)] if @{$goal[$i]->[$j]} == 0;
  18.     }
  19. }
  20. for my $i ( 0..8 ) { # delete the impossible numbers from 1..9
  21.     for my $j ( 0..8 ) {
  22.         &delete_element(\@goal, $i, $j);
  23.     }
  24. }

  25. &print_shudu(\@goal);
  26. &process(\@goal, 0, 0);

  27. sub delete_element {
  28.     my ( $ref, $row, $col ) = @_;
  29.     if ( @{$ref->[$row][$col]} == 1 ) {
  30.         for my $i ( 0..8 ) {
  31.             return 0 if &remove( $ref, $row, $col, $row, $i ) == 0;
  32.             return 0 if &remove( $ref, $row, $col, $i, $col ) == 0;
  33.         }
  34.         my $row_b = $row - $row % 3;
  35.         my $col_b = $col - $col % 3;
  36.         for my $i ( $row_b, $row_b+1, $row_b+2 ) {
  37.             for my $j ( $col_b, $col_b+1, $col_b+2 ) {
  38.                 return 0 if &remove( $ref, $row, $col, $i, $j ) == 0;
  39.             }
  40.         }
  41.     }
  42.     return 1;
  43. }
  44. sub remove {
  45.     my ( $ref, $row, $col, $i, $j ) = @_;
  46.     return 1 if ( $row == $i and $col == $j );
  47.     my @a = @{$ref->[$i][$j]};
  48.     $ref->[$i][$j] = [];
  49.     foreach ( @a ) {
  50.         push @{$ref->[$i][$j]}, $_ if $_ != $ref->[$row][$col][0];
  51.     }
  52.     if ( @{$ref->[$i][$j]} == 0 ) {
  53.         return 0; # error
  54.     }
  55.     else {
  56.         return 1; # success
  57.     }
  58. }
  59. sub process {
  60.     my ( $ref, $row, $col ) = @_;
  61.     my ( $new_row, $new_col );
  62.     if ( $col < 8 ) {
  63.         $new_col = $col + 1;
  64.         $new_row = $row;
  65.     }
  66.     else {
  67.         if ( $row < 8 ) {
  68.             $new_col = 0;
  69.             $new_row = $row + 1;
  70.         }
  71.         else {
  72.             &print_shudu($ref);
  73.             exit;
  74.         }
  75.     }
  76.     print "$row, $col, $new_row, $new_col\n"; # debug
  77.     if ( @{$ref->[$row][$col]} == 1 ) {
  78.         return if &delete_element($ref, $row, $col) == 0;
  79.         &process($ref, $new_row, $new_col);
  80.     }
  81.     else {
  82.         foreach ( @{$ref->[$row][$col]} ) {
  83.             my $new = &cp_shudu($ref);
  84.             $new->[$row][$col] = [$_];
  85.             next if &delete_element($new, $row, $col) == 0;
  86.             &process($new, $new_row, $new_col);
  87.         }
  88.     }
  89. }
  90. sub print_shudu {
  91.     my $ref = shift;
  92.     for my $i ( 0..8 ) {
  93.         for my $j ( 0..8 ) {
  94.             print $ref->[$i][$j][$_] for 0..$#{$ref->[$i][$j]};
  95.             print "\t";
  96.         }
  97.         print "\n";
  98.     }
  99. }

  100. sub cp_shudu {
  101.     my $ref = shift;
  102.     my $new;
  103.     for my $i ( 0..8 ) {
  104.         for my $j ( 0..8 ) {
  105.             $new->[$i][$j] = [@{$ref->[$i][$j]}];
  106.         }
  107.     }
  108.     return $new;
  109. }
复制代码

论坛徽章:
2
CU大牛徽章
日期:2013-04-17 11:46:28CU大牛徽章
日期:2013-04-17 11:46:39
2 [报告]
发表于 2012-07-22 00:38 |只看该作者
  1. for (@goal) { # fill empty element with 1..9
  2.     for my $j ( 0..8 ) {
  3.         $_->[$j] = [qw(1 2 3 4 5 6 7 8 9)] if @{$_->[$j]} == 0;
  4.     }
  5. }
复制代码

论坛徽章:
0
3 [报告]
发表于 2012-07-22 11:15 |只看该作者
cdtits 发表于 2012-07-22 00:38


有理。我怎么没想到啊,思维有点固化了。。。
谢谢~~

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
4 [报告]
发表于 2014-01-04 06:33 |只看该作者
先收藏,再慢慢研究,谢谢了。
还要慢慢看~

论坛徽章:
0
5 [报告]
发表于 2014-01-04 18:55 |只看该作者
太强大了,看的头痛!{:2_179:}

论坛徽章:
5
丑牛
日期:2014-01-21 08:26:26卯兔
日期:2014-03-11 06:37:43天秤座
日期:2014-03-25 08:52:52寅虎
日期:2014-04-19 11:39:48午马
日期:2014-08-06 03:56:58
6 [报告]
发表于 2014-01-05 17:58 |只看该作者
太强大了, 小伙伴们, 这个高端奢华上档次。
{:2_168:}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP