Esse golfe exige que um cálculo fatorial seja dividido entre vários segmentos ou processos.
Alguns idiomas facilitam a coordenação do que outros, por isso é agnóstico. Um código de exemplo não-fornecido é fornecido, mas você deve desenvolver seu próprio algoritmo.
O objetivo do concurso é ver quem consegue criar o algoritmo fatorial multicore mais curto (em bytes, não em segundos) para calcular o N! medido pelos votos quando o concurso é encerrado. Deveria haver uma vantagem multicore, portanto, exigiremos que funcione para N ~ 10.000. Os eleitores devem votar se o autor não fornecer uma explicação válida de como ele distribui o trabalho entre processadores / núcleos e votar com base na concisão do golfe.
Por curiosidade, publique alguns números de desempenho. Em algum momento, pode haver uma troca entre desempenho e pontuação do golfe, vá com o golfe desde que atenda aos requisitos. Eu ficaria curioso para saber quando isso ocorre.
Você pode usar bibliotecas inteiras grandes de núcleo único normalmente disponíveis. Por exemplo, o perl geralmente é instalado com o bigint. No entanto, observe que simplesmente chamar uma função fatorial fornecida pelo sistema normalmente não dividirá o trabalho em vários núcleos.
Você deve aceitar de STDIN ou ARGV a entrada N e a saída para STDOUT o valor de N !. Opcionalmente, você pode usar um segundo parâmetro de entrada para também fornecer o número de processadores / núcleos para o programa, para que ele não faça o que você verá abaixo :-) Ou você pode criar explicitamente para 2, 4, o que você tiver disponível.
Vou postar meu próprio exemplo de oddball perl abaixo, enviado anteriormente no Stack Overflow em Algoritmos fatoriais em diferentes idiomas . Não é golfe. Vários outros exemplos foram apresentados, muitos deles golfe, mas muitos não. Por causa do licenciamento compartilhado, fique à vontade para usar o código em qualquer exemplo no link acima como ponto de partida.
O desempenho no meu exemplo é pouco claro por várias razões: ele usa muitos processos, muita conversão de string / bigint. Como eu disse, é um exemplo intencionalmente estranho. Ele calculará 5000! em menos de 10 segundos em uma máquina de 4 núcleos aqui. No entanto, um forro mais óbvio de dois for / next loop pode fazer 5000! em um dos quatro processadores no 3.6s.
Você definitivamente terá que fazer melhor do que isso:
#!/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);
}
}
Meu interesse nisso é simplesmente (1) aliviar o tédio; e (2) aprender algo novo. Este não é um problema de lição de casa ou de pesquisa para mim.
Boa sorte!
