Цей гольф вимагає розбиття факторів на кілька потоків або процесів.
Деякі мови полегшують координацію, ніж інші, тому вона є агностичною. Наведено приклад коду, який не використовується, але слід розробити власний алгоритм.
Мета конкурсу - побачити, хто може придумати найкоротший (у байтах, а не секундах) багатоядерний факторний алгоритм для обчислення N! вимірюється голосами, коли конкурс завершується. Має бути багатоядерна перевага, тому ми вимагатимемо, щоб вона працювала на N ~ 10 000. Виборці повинні голосувати проти, якщо автор не надає вагомих пояснень того, як він поширює роботу між процесорами / сердечниками та голосує на основі лаконічності гольфу.
Для цікавості, будь ласка, опублікуйте кілька номерів виступу. Можливо, в якийсь момент може відбутися компроміс з результатами порівняння з гольфом, займайтеся гольфом, якщо він відповідає вимогам. Мені буде цікаво дізнатися, коли це відбувається.
Ви можете використовувати звичайно доступні одноядерні великі цілі цілі бібліотеки. Наприклад, Perl зазвичай встановлюється з bigint. Однак зауважте, що просто виклик системи за умови функціональної функції зазвичай не розділяє роботу на декілька ядер.
Ви повинні прийняти від STDIN або ARGV вхід N та вихід на STDOUT значення N !. Ви можете додатково використовувати другий вхідний параметр, щоб також вказати кількість процесорів / ядер для програми, щоб вона не виконувала те, що ви побачите нижче :-) Або ви можете чітко спроектувати 2, 4, що б у вас було в наявності.
Я розміщую свій власний приклад дивного perl нижче, раніше поданий на стек переповнення у розділі Факторні алгоритми різними мовами . Це не гольф. Було подано чимало інших прикладів, багато з них - гольф, а багато - ні. Через ліцензування подібного доступу, сміливо використовуйте код у будь-яких прикладах у наведеному вище посиланні як вихідну точку.
Продуктивність у моєму прикладі є недостатньою з кількох причин: він використовує занадто багато процесів, занадто багато конвертації string / bigint. Як я вже сказав, це навмисне дивний приклад. Він підрахує 5000! менше ніж за 10 секунд на 4-х основній машині тут. Однак більш очевидний два вкладиші для / наступного циклу можуть робити 5000! на одному з чотирьох процесорів у 3.6s.
Вам обов'язково доведеться робити краще, ніж це:
#!/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);
}
}
Мій інтерес до цього просто (1) полегшення нудьги; та (2) дізнатися щось нове. Для мене це не домашня робота чи дослідження.
Удачі!
