http://paperlined.org/dev/src/pl/kenken/iterate.pl
#!/usr/bin/perl
# <short description of program>
use strict;
use warnings;
use Data::Dumper;
use List::Util qw[reduce max min];
my $num_cells = 3;
my $result = 8;
my $operation = 'add';
# ^ first three letters
# ^ first letter: (A)dd (S)ub (D)iv (M)ul
my $max_val = 6;
$operation = 'sub' if ($operation eq 'min'); # 'min'us => 'sub'tract
my @cells = 1..$num_cells;
# iterate through all possible cell values
my %union;
my $total_iter = $max_val ** $num_cells;
for (my $ctr=0; $ctr<$total_iter; $ctr++) {
my $dist = $ctr;
my $last = 0;
for (my $pos=0; $pos<$num_cells; $pos++) {
$cells[$pos] = ($dist % $max_val) + 1;
if ($cells[$pos] < $last) {
$last = -1;
last;
}
$last = $cells[$pos];
$dist = int($dist / $max_val);
}
#next if (($operation eq 'add' || $operation eq 'mul') && $last == -1); # skip this sequence if it's out of order
next if ($last == -1); # skip this sequence if it's out of order
do_operation(@cells);
}
print "\n\nyes: ", join(" ", sort {$a <=> $b} keys %union), "\n";
print "no: ", join(" ", grep {!$union{$_}} 1..$max_val), "\n";
sub do_operation {
my $r = 0;
if ($operation eq 'add') {
$r = reduce {$a + $b} @_;
} elsif ($operation eq 'sub') {
$r = max(@_) - min(@_); # due to commutivity, there can only be two operands
} elsif ($operation eq 'mul') {
$r = reduce {$a * $b} @_;
} elsif ($operation eq 'div') {
$r = max(@_) / min(@_); # due to commutivity, there can only be two operands
}
if ($r == $result) {
print join(" ", @_), "\n";
foreach my $u (@_) {
$union{$u}++;
}
}
}
Generated by GNU enscript 1.6.4.