Just saw this post. Tried to comment there, but it failed.
As I understand it, Perl 6 is supposed to have a memoizer built-in, something like sub fact is cached ($n)
. But that definitely isn’t implemented in Rakudo yet.
There is an interesting way to do this that does work in Rakudo:
> my $fact = gather { take 1; my $a = 1; for 1..* { $a *= $_; take $a + 0 } }; say $fact[3]; 6 > say $fact[3] 6 > say $fact[4] 24 > say $fact[10] 3628800 > say $fact.munch(20).perl (1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6.402373705728e+15, 1.21645100408832e+17)
That defines $fact
as a lazy list of the factorials, which you can then access as, say, $fact[10]
(for 10!). The list will only contain actual values for the factorials you have asked for (and any others needed to compute those).
Edited to add: Just realized there is (almost?) an easier way of doing this.
> my $fact = [\*] 1..*; say $fact[3] 24 > $fact.munch(20).perl (1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6.402373705728e+15, 1.21645100408832e+17, 2.43290200817664e+18)
As you can see, this is a much cleaner way of generating the list, but the indices are now off by one.
August 10, 2010 at 4:32 pm |
I don’t have perl6 installed at work. Would the following work?
my $fact = 1, [\*] 1..*;
August 10, 2010 at 4:41 pm |
I tried that first and it failed. 😦
August 11, 2010 at 7:00 am |
Note that it would need to be parenthesized, because of item assignment:
my $fact = (1, [\*] 1..*);
It still doesn’t work (yet?), because itemizing the Parcel tends to make it eager, so we end up evaluating an infinite list. But the following does work:
my $fact = (1, [\*] 1..100);
which at least gets you to 100 factorial, and doesn’t take forever to do it. 🙂
Pm
August 11, 2010 at 7:45 am |
This works for me:
my $fact = [\*] 1,1..*;
say $fact.munch(20).perl;
(1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6.402373705728e+15, 1.21645100408832e+17)
August 11, 2010 at 8:31 am |
Brill!
August 17, 2010 at 7:00 pm |
Also
my $fact := (1, [\*] 1..*);
say $fact[0..10].perl;
(1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800)