($amt, @dens).reduce({
my $x = 0;
if $^b <= $^a {
$x = ($a/$b).floor;
say "$b:\t$x";
}
$a - $b * $x;
});
Name:
Anonymous2010-11-24 19:35
>>14
Tip: don't use auto quoting for arrays of numbers. You will end up with strings that numify at runtime, often to floats (with current Rakudo at least.) If you use actual numbers, you'll consistently get Rats which are precise in cases like this.
Nice shiny nickel for explanation why this one prints out 4 nickels for 5670.45 whereas OP's program prints out 3 nickels.
import Data.Fixed
import System.Environment
import Numeric
denom = [1000, 500, 200, 100, 50, 20, 10, 0.25, 0.05] :: [Fixed E2]
makeChange (d:ds) x = let (n, y) = x `divMod'` d in (n, d) : makeChange ds y
makeChange _ _ = []
showPair (n, c) = showFixed True c ++ ": " ++ show n
main = do ((x,_):_) <- getLine >>= return . readFloat
mapM_ (putStrLn . showPair) $ makeChange denom x
Nice shiny nickel for explanation why this one prints out 4 nickels for 5670.45 whereas OP's program prints out 3 nickels.
That's been covered by a number of posts already.
.reduce is a list method which takes a coderef. Each pass it eats &code.arity (here 2) elements from a copy of the list, and puts the return value back onto the head of the copy. It does this until there's only one element left in the list copy, which is the reduced answer. So @list.reduce({$^a+$^b}); is the same as a simple summation reduction, [+] @list; ($^a etc simply introduce $a as the a-th argument and can be used to calculate arity.)
The logic in the closure is to propagate the first element as the amount (less the value of denominations printed out) down the list until it runs out of denominations. So, in reduce, the head is always the current $amt, and the tail is the list of remaining denominations to be evaluated. (If a denomination is greater than the amount, $x remains at zero, so $a (the current amount) is propagated unaltered.)
In this code "return" can't be used because the closure will return from the enclosing context so implicit returns (which are different) are used instead. A sub could have been used instead, and returns would have been okay. (IIRC there's also a keyword which will do the same as the implicit return in this case.)
Name:
Anonymous2010-11-24 22:02
thanks for the reply..
i guess i need to study more and LURk more..
>>22-23
I'm not >>21, but sure, if >>1,21 is interested he is welcome to go there as well.
Thank you so much for your explanation, >>20. Would you happen to have some links, or at least search terms, for Perl coderefs and the related syntax $^a?
If you know Perl 5, check out http://perlgeek.de/en/article/5-to-6 ($^a is covered under "twigils"). Rakudo Star includes a book, I can't remember where to find the book outside of that distribution.
http://perl6.org/ is a good place to start. http://perlcabal.org/ has links to the official documentation, but it's littered with historical things, and sometimes it can be confusing since Rakudo doesn't implement everything yet (Perl 6 is fairly large, the existing core is quite usable.)
http://try.rakudo.org/ is a great place to test out stuff if you don't want to install anything, it has a multiline REPL.
>>1
Sorry for shitting up your thread with all the Perl 6 promotions. C is a fine language.
>>15,20,22-23,26
I have no idea why a gentleman like you would hang out in /prog/, for you are a much better person than most of us put together. I tip my hat to you, sir. Or perhaps it's just that this board's been shit lately, which of course does not remove any of your merit, actually quite the contrary).
>>27
I'm usually as bad as all of us, I just... er... I'm just wearing my Sussman hat?
>>30
Just guessing, but: partly for map/reduce cred. Partly because 5 already has some things named reduce and partly because there is no foldr (so the folding concept isn't so strong.) You can @list.reverse.reduce({...}); instead, and swap $^a and $^b in the closure.
A cute thing about Perl 6 is that map was made a little better, but I use it less often. In many cases where map is appropriate, factoring the problem a little differently without map is just as good or better.
Name:
Anonymous2010-11-26 12:21
>>15 ($amt, @dens).reduce: {
my $x = 0;
if $^b <= $^a {
$x = ($a/$b).floor;
say "$b:\t$x";
}
$a - $b * $x;
};
The colon form helps take the pain out of supplying closures to methods.
>>13
I don't really know C. "x = 0.05000; x >= 0.05" being false is bullshit, though. Subtracting in a loop might've made more sense to >>1 and I don't know if C has a divmod function.