#!/usr/bin/perl use strict; use warnings; use Getopt::Long; GetOptions 'digits=i' => \my \$digits, # Number of digits. 'min=i' => \my \$min, # Minimum sum. 'max=i' => \my \$max, # Maximum sum. 'terms=i' => \my \$terms, # Minimum number of terms in sum. ; \$digits ||= 3; \$min ||= 0; \$max ||= 0x7FFFFFFF; \$terms ||= 6; # # Return all permutations of a set. # sub perms; sub perms { @_ ? map {my \$i = \$_; map {[\$_ [\$i] => @\$_]} perms @_ [0 .. \$i - 1, \$i + 1 .. \$#_]} 0 .. \$#_ : []; } # # Return the powerset of a set. # sub power_set; sub power_set { @_ ? do {my @r = power_set @_ [1 .. \$#_]; [\$_ [0]] => @r => map {[\$_ [0] => @\$_]} @r} : () } my %answers; sub try { local \$" = " + "; foreach my \$set (power_set @_) { my \$sum = eval "@\$set"; push @{\$answers {\$sum}} => \$set; } } OUTER: foreach (("0" x \$digits) .. ("9" x \$digits)) { my @digits = split //; for (my \$i = 1; \$i < @digits; \$i ++) { next OUTER if \$digits [\$i] < \$digits [\$i - 1] } my %seen; try grep {!\$seen {\$_} ++} map {\$_ = join "" => @\$_; s/^0*(?=\d)//; \$_} perms @digits; } foreach my \$sum (sort {\$a <=> \$b} keys %answers) { next unless \$sum >= \$min && \$sum < \$max; next unless @{\$answers {\$sum}} == 1; next unless @{\$answers {\$sum} [0]} >= \$terms; local \$" = " + "; print "\$sum == @{\$answers{\$sum}[0]}\n"; } __END__