Bu golf faktöriyel bir hesaplamanın birden çok iş parçacığı veya süreç arasında bölünmesini gerektirir.
Bazı diller bunu koordine etmeyi diğerlerinden daha kolaylaştırır, bu yüzden lang agnostiktir. Ungolfed örnek kodu sağlanır, ancak kendi algoritmanızı geliştirmelisiniz.
Yarışmanın amacı N'yi hesaplamak için en kısa (saniyede değil bayt cinsinden) çok çekirdekli faktöriyel algoritmayı kimin bulabileceğini görmektir. yarışma sona erdiğinde oylarla ölçülür. Çok çekirdekli bir avantaj olmalı, bu yüzden N ~ 10.000 için çalışmasını gerektireceğiz. Yazarlar, işçiyi işlemciler / çekirdekler arasında nasıl yaydığına dair geçerli bir açıklama sağlayamazsa ve golf kısaltmasına dayanarak oy kullanırlar.
Merak için lütfen bazı performans numaraları gönderin. Bir noktada golf skoru dengesine karşı bir performans olabilir, gereksinimleri karşıladığı sürece golf ile devam edin. Bunun ne zaman gerçekleştiğini bilmek isterdim.
Normalde kullanılabilir tek çekirdekli büyük tamsayı kitaplıkları kullanabilirsiniz. Örneğin, perl genellikle bigint ile kurulur. Bununla birlikte, sadece bir sistem tarafından sağlanan faktöriyel fonksiyonu çağırmanın, işi normalde birden fazla çekirdek arasında bölmeyeceğini unutmayın.
STDIN veya ARGV'den N girişini kabul etmeli ve STDOUT'a N! İsteğe bağlı olarak programa işlemci / çekirdek sayısını sağlamak için 2. giriş parametresini kullanabilirsiniz, böylece aşağıda göreceğiniz şeyi yapmaz :-) Veya mevcut olan her ne olursa olsun 2, 4 için açıkça tasarlayabilirsiniz.
Daha önce Farklı Dillerdeki Faktöriyel Algoritmalar altında Stack Overflow'da gönderilen kendi oddball perl örneğimi yayınlayacağım . Golf değil. Birçoğu golf ama birçoğu olmayan çok sayıda başka örnek sunuldu. Benzer şekilde lisanslama nedeniyle, yukarıdaki bağlantıdaki örneklerde yer alan kodu başlangıç noktası olarak kullanmaktan çekinmeyin.
Örneğimdeki performans birkaç nedenden dolayı yetersiz: çok fazla işlem, çok fazla dize / bigint dönüşümü kullanıyor. Dediğim gibi bu kasten tuhaf bir örnek. 5000 hesaplayacak! 4 çekirdekli bir makinede 10 saniyenin altında. Ancak, daha açık bir iki astar / sonraki döngü 5000 yapabilir! 3.6'larda dört işlemciden birinde.
Kesinlikle bundan daha iyisini yapmanız gerekecek:
#!/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);
}
}
Buna olan ilgim basitçe (1) can sıkıntısını hafifletmek; ve (2) yeni bir şey öğrenmek. Bu benim için bir ödev ya da araştırma sorunu değil.
İyi şanslar!
