Este golf requiere un cálculo factorial que se divida entre múltiples hilos o procesos.
Algunos idiomas hacen que esto sea más fácil de coordinar que otros, por lo que es un lenguaje agnóstico. Se proporciona un código de ejemplo no protegido, pero debe desarrollar su propio algoritmo.
El objetivo del concurso es ver quién puede encontrar el algoritmo factorial multinúcleo más corto (en bytes, no segundos) para calcular N! medido por los votos cuando se cierra el concurso. Debería haber una ventaja multinúcleo, por lo que necesitaremos que funcione para N ~ 10,000. Los votantes deben votar si el autor no proporciona una explicación válida de cómo distribuye el trabajo entre los procesadores / núcleos y votar en base a la concisión del golf.
Por curiosidad, publique algunos números de rendimiento. Puede haber una compensación entre el rendimiento y el puntaje de golf en algún momento, vaya con el golf siempre que cumpla con los requisitos. Me gustaría saber cuándo ocurre esto.
Puede utilizar bibliotecas de gran número de núcleos individuales normalmente disponibles. Por ejemplo, perl generalmente se instala con bigint. Sin embargo, tenga en cuenta que simplemente llamar a una función factorial proporcionada por el sistema normalmente no dividirá el trabajo en múltiples núcleos.
Debe aceptar de STDIN o ARGV la entrada N y la salida a STDOUT el valor de N !. Opcionalmente, puede usar un segundo parámetro de entrada para proporcionar también el número de procesadores / núcleos al programa para que no haga lo que verá a continuación :-) O puede diseñar explícitamente para 2, 4, lo que tenga disponible.
Publicaré mi propio ejemplo de perl Oddball a continuación, presentado previamente en Stack Overflow en Algoritmos factoriales en diferentes idiomas . No es golf. Se presentaron muchos otros ejemplos, muchos de ellos de golf pero muchos no. Debido a las licencias compartidas, siéntase libre de usar el código en cualquier ejemplo en el enlace anterior como punto de partida.
El rendimiento en mi ejemplo es mediocre por varias razones: utiliza demasiados procesos, demasiada conversión de cadenas / bigint. Como dije, es un ejemplo intencionalmente extraño. ¡Calculará 5000! en menos de 10 segundos en una máquina de 4 núcleos aquí. Sin embargo, ¡un dos forro más obvio para / próximo ciclo puede hacer 5000! en uno de los cuatro procesadores en 3.6s.
Definitivamente tendrás que hacerlo mejor que esto:
#!/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);
}
}
Mi interés en esto es simplemente (1) aliviar el aburrimiento; y (2) aprender algo nuevo. Este no es un problema de tarea o investigación para mí.
¡Buena suerte!
