Windows19
发表于 2017-06-29 20:14
赞
sunzhiguolu
发表于 2017-06-29 21:58
回复 31# Windows19
谢谢诸位大神,包括楼上打酱油的 。说过的话一定会兑现,等我消化消化。。。
jason680
发表于 2017-07-02 20:15
回复 23# sunzhiguolu
http://bbs.chinaunix.net/thread-4263652-1-1.html
zhouzhen1
发表于 2017-07-10 21:20
回复 14# 523066680
Algorithm::Permute版本 <= 0.12的话在Perl 5.24及以上是build不出来的。这是因为Perl 5.24有一个称为Context rework的工作,提高了函数调用的速度,但是一些原来非公开的内部API被改了,当时造成了一批XS package break。
我前两天因为单位里工作的原因,刚好把Algorithm::Permute修了一下,现在最新的版本是0.14,你可以再试试。
523066680
发表于 2017-07-11 10:05
回复 34# zhouzhen1
厉害了。高性能。
rubyish
发表于 2017-07-24 01:20
v3:
real 0m0.030s
#!/usr/bin/perl
# version 26, subversion 0 (v5.26.0)
use 5.010;
explore();
# ______________________ SUB ______________________
sub explore { E_(0) }
sub E_ {
my $n = shift;
state $b = [ (0) x 4 ];
state $has = [ (0) x 10 ];
state $in= [ [ 0, 1 ], [ 2, 3 ], [ 0, 2 ], [ 1, 3 ], [ 0, 3 ] ];
if ( $n == 3 ) {
# b3 = 15 - (15 - b0 - b1) - (15 - b0 - b2)
my $b3 = $b-> + $b-> + $b-> + $b-> - 15;
return if $b3 < 1 or $b3 > 9;
$b-> = $b3;
my ( @test, @x ) = (0) x 10;
$test[$_]++ and return for @$b;
for my $i (@$in) {
my $it = $b->[ $i-> ] + $b->[ $i-> ];
return if $it < 6 or $it > 14;
$it = 15 - $it;
return if $test[$it]++;
push @x, $it;
}
say join ' ', @$b[ 0, 1 ], $x;
say join ' ', @$b[ 2, 3 ], $x;
say join ' ', @x[ 2, 3, 4 ];
say '-----';
return;
}
for my $it ( 1 .. 9 ) {
next if $has->[$it];
$has->[$it]++;
$b->[$n] = $it;
E_( $n + 1 );
$has->[$it]--;
}
}
__DATA__
$_
jason680
发表于 2017-07-24 12:54
回复 32# sunzhiguolu
>> ...说过的话一定会兑现,等我消化消化。。。
消化消化
帖子都快消失,还不出来说说话...
aef25u
发表于 2020-07-30 00:11
最近在看《七周七语言》,这类题用prolog是最合适的,而perl有AI::Prolog,写了个代码,因为要完成穷举和满足所有条件,运行时间会有点久。
fd_domain与fd_all_diff函数都是自己写的,另个解决问题的方式是通过递归来实现的。
use AI::Prolog;
use Data::Dumper;
$Data::Dumper::Indent = 0;
my $prolog;
# If reading from DATA, we need a CHECK block to ensure that
# DATA is available by the time the constructor is called
CHECK {
$prolog = AI::Prolog->new(
do { local $/; <DATA> }
);
}
#[4, 9,2,
# 3,5,7,
# 8, 1,6]
$prolog->query("sudoku(, Solution).");
#显示执行过程
#$prolog->trace(1);
while ( my $results = $prolog->results ) {
#print "@$results\n";
print Dumper $results;
}
__DATA__
member(X, [ X | _ ]).
member(X, [ _ | TAIL ]) :-
member(X, TAIL).
fd_domain([],_).
fd_domain([ HEAD | TAIL ],L) :-
member(HEAD,L),
fd_domain(TAIL,L).
fd_all_diff([]).
fd_all_diff([ HEAD | TAIL ]) :-
not(member(HEAD,TAIL)),
fd_all_diff(TAIL).
sum([], 0).
sum(,Total) :-
sum(Tail,Sum),
Total is Head + Sum.
valid([]).
valid() :-
sum( HEAD , Total),
eq(15,Total),
valid(TAIL).
sudoku(Puzzle, Solution) :-
Solution = Puzzle,
eq(Puzzle, ),
fd_domain(Solution, ),
eq(Row1,),
eq(Row2,),
eq(Row3,),
eq(Col1,),
eq(Col2,),
eq(Col3,),
eq(ObjLineL,),
eq(ObjLineR, ),
fd_all_diff(Solution),
valid().