- 论坛徽章:
- 0
|
本帖最后由 午夜凋零 于 2012-07-22 00:31 编辑
前阵子看新闻看到一个人号称创出来最难的数独,当时就产生了个想法,将数独中已经提供的数字作为输入,得出所有的元素。
整了两三天的时间,终于用perl实现了,感觉自己好弱啊。{:2_169:}
另一方面,虽然感觉自己很弱,但是完成一项想法的感觉还是挺爽的。
下面是代码,欢迎各位批评指正,希望不会被拍的太厉害。。。。- #!/usr/bin/perl
- use warnings;
- use strict;
- my @goal = (
- [[8], [ ], [ ], [ ], [ ], [ ], [ ], [ ], [ ]],
- [[ ], [ ], [3], [6], [ ], [ ], [ ], [ ], [ ]],
- [[ ], [7], [ ], [ ], [9], [ ], [2], [ ], [ ]],
- [[ ], [5], [ ], [ ], [ ], [7], [ ], [ ], [ ]],
- [[ ], [ ], [ ], [ ], [4], [5], [7], [ ], [ ]],
- [[ ], [ ], [ ], [1], [ ], [ ], [ ], [3], [ ]],
- [[ ], [ ], [1], [ ], [ ], [ ], [ ], [6], [8]],
- [[ ], [ ], [8], [5], [ ], [ ], [ ], [1], [ ]],
- [[ ], [9], [ ], [ ], [ ], [ ], [4], [ ], [ ]]
- );
- for my $i ( 0..8 ) { # fill empty element with 1..9
- for my $j ( 0..8 ) {
- $goal[$i]->[$j] = [qw(1 2 3 4 5 6 7 8 9)] if @{$goal[$i]->[$j]} == 0;
- }
- }
- for my $i ( 0..8 ) { # delete the impossible numbers from 1..9
- for my $j ( 0..8 ) {
- &delete_element(\@goal, $i, $j);
- }
- }
- &print_shudu(\@goal);
- &process(\@goal, 0, 0);
- sub delete_element {
- my ( $ref, $row, $col ) = @_;
- if ( @{$ref->[$row][$col]} == 1 ) {
- for my $i ( 0..8 ) {
- return 0 if &remove( $ref, $row, $col, $row, $i ) == 0;
- return 0 if &remove( $ref, $row, $col, $i, $col ) == 0;
- }
- my $row_b = $row - $row % 3;
- my $col_b = $col - $col % 3;
- for my $i ( $row_b, $row_b+1, $row_b+2 ) {
- for my $j ( $col_b, $col_b+1, $col_b+2 ) {
- return 0 if &remove( $ref, $row, $col, $i, $j ) == 0;
- }
- }
- }
- return 1;
- }
- sub remove {
- my ( $ref, $row, $col, $i, $j ) = @_;
- return 1 if ( $row == $i and $col == $j );
- my @a = @{$ref->[$i][$j]};
- $ref->[$i][$j] = [];
- foreach ( @a ) {
- push @{$ref->[$i][$j]}, $_ if $_ != $ref->[$row][$col][0];
- }
- if ( @{$ref->[$i][$j]} == 0 ) {
- return 0; # error
- }
- else {
- return 1; # success
- }
- }
- sub process {
- my ( $ref, $row, $col ) = @_;
- my ( $new_row, $new_col );
- if ( $col < 8 ) {
- $new_col = $col + 1;
- $new_row = $row;
- }
- else {
- if ( $row < 8 ) {
- $new_col = 0;
- $new_row = $row + 1;
- }
- else {
- &print_shudu($ref);
- exit;
- }
- }
- print "$row, $col, $new_row, $new_col\n"; # debug
- if ( @{$ref->[$row][$col]} == 1 ) {
- return if &delete_element($ref, $row, $col) == 0;
- &process($ref, $new_row, $new_col);
- }
- else {
- foreach ( @{$ref->[$row][$col]} ) {
- my $new = &cp_shudu($ref);
- $new->[$row][$col] = [$_];
- next if &delete_element($new, $row, $col) == 0;
- &process($new, $new_row, $new_col);
- }
- }
- }
- sub print_shudu {
- my $ref = shift;
- for my $i ( 0..8 ) {
- for my $j ( 0..8 ) {
- print $ref->[$i][$j][$_] for 0..$#{$ref->[$i][$j]};
- print "\t";
- }
- print "\n";
- }
- }
- sub cp_shudu {
- my $ref = shift;
- my $new;
- for my $i ( 0..8 ) {
- for my $j ( 0..8 ) {
- $new->[$i][$j] = [@{$ref->[$i][$j]}];
- }
- }
- return $new;
- }
复制代码 |
|