http://www.perlmonks.org?node_id=11101105

Someone posted this challenge at work..
The country of Elbonia is standardizing its postal system to streamline its parcel service. All parcel boxes (many sizes available) now come with 10 preprinted rectangles on one side for stamps to be stuck into. Elbonia's stamp denominations are:
1c, 2c, 3c, 4c, 5c, 10c, 24c, 37c, 39c, 41c, 48c, 60c, 63c, 70c, 75c, 80c, 83c, 84c, 87c, \$1, \$3.85, \$4.05, \$4.60, \$5, \$14.40
Given an infinite supply of each denomination, what is the minimum postage amount that would REQUIRE 11 stamps and so not work with the streamlined service?

```my\$w={0=>1,1=>1,2=>2,3=>3,4=>4,5=>5,10=>
10,24=>24,37=>37,39=>39,41=>41,48=>48,60
=>60                               ,63=>
63,                70=>            70,75
=>75               ,80=>80         ,83=>
83,            84=>84,87=>87,      100=>
100,          385=>385,405=>405   ,460=>
460           ,500=>500,1440=>    1440};
my@a          =sort{\$a<=>\$b}keys  %{\$w};
for(          1..9){foreach my\$c  (keys
%{\$w}        ){foreach my \$v(@a)  {my \$n
=\$c+        \$v;if(!exists\$w->     {\$n})
{\$w          ->{\$n}=\$w->{\$c}.     "+".\$v
;}}}         }my@r=sort{\$a<=>    \$b}keys
%{\$w          };my\$h=pop@r;     for my\$i
(0..          \$h){if(exists       \$w->{\$
i}){              print"\$          i->".
\$w->              {\$i}."\n"        ;}###
else{              print"!\$i       \n";}
}###    #         ##########       #####
####    #        ############      #####
####    #       ##############     #####
####    #     ################     #####
####        ###################    #####
####         ##############        #####
####                               ## ##
########################################
##### # ########### ############## #####
########################################

Replies are listed 'Best First'.
Re: Stamp puzzle solution
by drpaz (Acolyte) on Jun 07, 2019 at 17:22 UTC
I should clarify this solution prints achievable amounts, with the breakdown of how it's achievable, one per line, and non-achievable numbers as !number, one per line, so to answer the original question: perl elbonian.pl | grep ^! | head -1
Re: Stamp puzzle solution
by Anonymous Monk on Jun 08, 2019 at 21:43 UTC
Some nitpicks if you allow. :)

You know, you could considerably speed up your algorithm by not looping over all results so far in foreach my \$c  (keys %{\$w}) but only those new from the last run. There is no point checking the smaller sums again and again.

And resorting to bash and grep to find the smallest result could be easily avoided by exiting Perl as soon as a sum is missing in %\$w

Furthermore, and this is more stylistic, using a hash-slice might be easier to read.

```my @w = qw(1 2 3  ...);
my \$w;
@\$w{@w} = @w;
\$w->{0} = 1; # start