This golf requires a factorial calculation be split up among multiple threads or processes.
Some languages make this easier to coordinate than others, so it is lang agnostic. Ungolfed example code is provided, but you should develop your own algorithm.
The goal of the contest is to see who can come up with the shortest (in bytes, not seconds) multicore factorial algorithm for calculating N! as measured by votes when the contest closes. There should be a multicore advantage, so we'll require that it should work for N ~ 10,000. Voters should vote down if the author fails to provide a valid explanation of how it spreads out the work among processors/cores and vote up based on golf conciseness.
For curiosity, please post some performance numbers. There may be a performance vs golf score tradeoff at some point, go with golf so long as it meets the requirements. I'd be curious to know when this occurs.
You may use normally available single core big integer libraries. For instance, perl is usually installed with bigint. However, note that simply calling a system provided factorial function won't normally split the work across multiple cores.
You must accept from STDIN or ARGV the input N and output to STDOUT the value of N!. You may optionally use a 2nd input parameter to also provide the number of processors/cores to the program so it doesn't do what you'll see below :-) Or you may design explicitly for 2, 4, whatever you have available.
I will post my own oddball perl example below, previously submitted on Stack Overflow under Factorial Algorithms in Different Languages. It is not golf. Numerous other examples were submitted, many of them golf but many not. Because of share-alike licensing, feel free to use the code in any examples in the link above as a starting point.
Performance in my example is lackluster for a number of reasons: it uses too many processes, too much string/bigint conversion. As I said it is an intentionally oddball example. It will calculate 5000! in under 10 seconds on a 4 core machine here. However, a more obvious two liner for/next loop can do 5000! on one of the four processors in 3.6s.
You'll definitely have to do better than this:
#!/usr/bin/perl -w
use strict;
use bigint;
die "usage: f.perl N (outputs N!)" unless ($ARGV[0] > 1);
print STDOUT &main::rangeProduct(1,$ARGV[0])."\n";
sub main::rangeProduct {
my($l, $h) = @_;
return $l if ($l==$h);
return $l*$h if ($l==($h-1));
# arghhh - multiplying more than 2 numbers at a time is too much work
# find the midpoint and split the work up :-)
my $m = int(($h+$l)/2);
my $pid = open(my $KID, "-|");
if ($pid){ # parent
my $X = &main::rangeProduct($l,$m);
my $Y = <$KID>;
chomp($Y);
close($KID);
die "kid failed" unless defined $Y;
return $X*$Y;
} else {
# kid
print STDOUT &main::rangeProduct($m+1,$h)."\n";
exit(0);
}
}
My interest in this is simply (1) alleviating boredom; and (2) learning something new. This isn't a homework or research problem for me.
Good luck!