Re: [QUIZ] Perl 'Medium' Quiz of the Whatever #2008-02-28 - Kakuro Digit Sums
Shlomi Fish <shlomif-ik1l9ssToec+JF/[email protected]> Mon, 03 Mar 2008 17:04:36 +0200
| Newsgroups | gmane.comp.lang.perl.qotw.discuss |
|---|---|
| Message-ID | <[email protected]> |
On Thursday 28 February 2008, Shlomi Fish wrote: > IMPORTANT: Please do not post solutions, hints, or other spoilers > until at least 60 hours after the date of this message. Thanks. > > Kakuro (a.k.a Cross-sums) is a kind of puzzle game: > > http://en.wikipedia.org/wiki/Kakuro > > In it, one fills in squares in a crossword-like grid that sum to their > sums. One can fill in the digits from 1 to 9, and no digit can be repeated > twice. > > Your object is to find all posssible combinations for a given sum and a > given number of squares. You'll write a function get_digits_sum($sum, > $num_places), that will return an array reference of array references, each > one containing an possible solution (in ascending order). The solutions > themselves should be in ascending order too, starting from the lowest > numbers. Here are some examples: > > get_digits_sum(7, 3) => returns [[1,2,4]]. > > get_digits_sum(7, 2) => returns [[1,6],[2,5],[3,4]]; > > The daily puzzle in http://www.kakuro.com/index.php#daily (requires Flash) > has a feature to display the permutations in a similar manner. > > Regards, > > Shlomi Fish > > --------------------------------------------------------------------- > Shlomi Fish shlomif-ik1l9ssToec+JF/[email protected] > Homepage: http://www.shlomifish.org/ > > I'm not an actor - I just play one on T.V. Here is my solution, which is recursive: <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< use strict; use warnings; use Test::More tests => 5; my $max_digit = 9; my $min_digit = 1; sub _digits_sum_from { my ($start, $sum, $num_places) = @_; if ($num_places == 1) { if (($sum >= $start) && ($sum <= $max_digit)) { return [[$sum]]; } else { return []; } } my @results; FIRST_LOOP: foreach my $first ($start .. $max_digit) { if ($sum-$first <= 0) { last FIRST_LOOP; } push @results, (map { [$first,@$_] } @{_digits_sum_from($first+1, $sum-$first, $num_places-1)} ); } return \@results; } sub get_digits_sum { my ($sum, $num_places) = @_; return _digits_sum_from($min_digit, $sum, $num_places); } # TEST is_deeply(get_digits_sum(3,2), [[1,2]], "3 over 2"); # TEST is_deeply(get_digits_sum(7,3), [[1,2,4]], "7 over 3"); # TEST is_deeply(get_digits_sum(15,5), [[1,2,3,4,5]], "15 over 5"); # TEST is_deeply(get_digits_sum(25,5), [ [1,2,5,8,9], [1,2,6,7,9], [1,3,4,8,9], [1,3,5,7,9], [1,3,6,7,8], [1,4,5,6,9], [1,4,5,7,8], [2,3,4,7,9], [2,3,5,6,9], [2,3,5,7,8], [2,4,5,6,8], [3,4,5,6,7], ], "25 over 5", ); # TEST is_deeply(get_digits_sum(14,2), [[5,9],[6,8],], "14 over 2",); >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> --------------------------------------------------------------------- Shlomi Fish shlomif-ik1l9ssToec+JF/[email protected] Homepage: http://www.shlomifish.org/ I'm not an actor - I just play one on T.V.