Zadanie
Korzystając z dowolnego rodzaju paralelizacji, odczekaj kilka okresów, aby całkowity czas snu wynosił co najmniej minutę (ale mniej niż półtorej minuty).
Program / funkcja musi zakończyć się w ciągu 10 sekund i zwrócić (w jakikolwiek sposób iw dowolnym formacie) dwie wartości: całkowity czas, który upłynął, i całkowity czas wykonania snu. Obie wartości czasu muszą mieć dokładność co najmniej 0,1 sekundy.
Jest to podobne do pojęcia roboczogodzin : zadanie, które zajmuje 60 godzin, można wykonać w zaledwie 6 godzin, jeśli 10 pracowników dzieli zadanie. Tutaj możemy mieć 60 sekund czasu snu, np. W 10 równoległych wątkach, co wymaga jedynie 6 sekund na wykonanie całego zadania.
Przykład
Program MyProgram tworzy 14 wątków, każdy wątek śpi przez 5 sekund:
MyProgram
→ [5.016,70.105]
Czas wykonania jest dłuższy niż 5 sekund, a całkowity czas snu jest dłuższy niż 70 sekund z powodu obciążenia.
Odpowiedzi:
Dyalog APL,
65272321 bajtówTo znaczy:
Wyjaśnienie:
⎕DL&¨9/7
: odkręć 9 wątków, z których każdy czeka 7 sekund.⎕DL
zwraca rzeczywisty czas oczekiwania w sekundach, który będzie taki sam, jak argument podany lub potrwa kilka milisekund.⎕TSYNC
: poczekaj na zakończenie wszystkich wątków i uzyskaj wynik dla każdego wątku.(⌈/,+/)
: zwraca najdłuższy czas wykonania pojedynczego wątku (podczas wykonywania którego wszystkie pozostałe wątki zostały zakończone, więc jest to rzeczywisty czas działania), a następnie sumę czasu wykonania wszystkich wątków.Wypróbuj online!
źródło
Python 2, 172 bajty
Wymaga to, aby system operacyjny z dokładnością czasową większą niż 1 sekunda działał poprawnie (innymi słowy, każdy nowoczesny system operacyjny). Utworzono 8 wątków, które śpią przez 9 sekund, co daje czas działania w czasie rzeczywistym ~ 9 sekund i równoległy czas działania ~ 72 sekund.
Chociaż oficjalna dokumentacja mówi, że
Thread
konstruktor powinien być wywoływany z argumentami słów kluczowych, rzucam ostrożność na wiatr i i tak używam argumentów pozycyjnych. Pierwszym argumentem (group
) musi byćNone
, a drugim argumentem jest funkcja docelowa.nneonneo wskazał w komentarzach, że dostęp do atrybutu (np.
f.t
) jest krótszy niż dostęp do indeksu listy (npt[0]
.). Niestety w większości przypadków kilka bajtów uzyskanych w ten sposób zostałoby utraconych przez konieczność utworzenia obiektu, który umożliwi tworzenie atrybutów zdefiniowanych przez użytkownika w czasie wykonywania. Na szczęście funkcje obsługują atrybuty zdefiniowane przez użytkownika w czasie wykonywania, więc wykorzystuję to, oszczędzając całkowity czas wt
atrybucief
.Wypróbuj online
Dzięki DenkerAffe za -5 bajtów z
exec
trikiem.Dzięki kundor dla -7 bajtów, wskazując, że argument wątku jest niepotrzebny.
Dzięki nneonneo za -7 bajtów z różnych ulepszeń.
źródło
f()
, i dwa ostatnie argumenty naThread
(usuwając w ten sposób 7 znaków) i używając,t.append(m()-n)
aby uniknąć przypisania zmiennej lokalnejt
(używając 5 więcej znaków niż+=
.)t
pomocąt=[0]
, zamień append przezt[0]+=m()-n
i zamieńsum(t)
nat[0]
.import threading as H,time as t
; zapisz kolejne dwa bajty za pomocąz=H.Thread
imap(z.join,r)
; zaoszczędź kolejne dwa bajty, przechowując całkowity czas jako atrybut (np.T.z+=m()-n
)Narzędzia Bash + GNU, 85
Wymusza użycie
time
pliku wykonywalnego zamiast wbudowanej powłoki przez przedrostek z\
.Dołącza do pliku
j
, który musi być pusty lub nieistniejący na początku.źródło
if [ $1 -lt 9 ];then { ./a $(( $1 + 1 )) &};sleep 7;fi
czy coś takiego? Czy byłoby to sprzeczne z zasadami lub czymś, czego nie rozumiem na temat specyfikacji? [edytować; Brakowało mi wymogu wyjścia. Och, to sprawia, że jest to interesujące!](($1<9))&&$0 $[$1+1]&sleep 7
Idź - 189 bajtów
Dzięki @cat!
Wyjścia (ms): 160,9939 ms , 60001 (160 ms, aby czekać 60,001 sekund)
źródło
@Rob In some languages the obvious solution is already (close to) the shortest. Besides, one way to view code-golf challenges is finding the shortest solution in EACH language. Otherwise Jelly will win most of the time... So: go ahead.
nie oznacza, że nie powinieneś próbować grać w golfa w odpowiedzi, ale że jest OK, jeśli nie wygra. Czy możesz dodać rozwiązanie w golfa?tot
na coś podobnegoq
.Bash
19611711493 bajtówZaktualizowano, aby obsługiwał lepszą precyzję czasu, integrując sugestie @manatwork i @Digital Trauma, a także kilka innych optymalizacji przestrzeni:
Zauważ, że zakłada to, że
j
plik jest nieobecny na początku.źródło
function s
→s()
,b=`date +%s`
→b=$SECONDS
,expr $t + $i
→$[t+i]
,`cat j`
→$(<j)
i ogólnie zobacz Wskazówki dotyczące gry w golfa w Bash na temat tego, jak to ograniczyć: pastebin.com/DDqUaDug5↵5↵5↵…
pisać+5+5+5…
- a następnie załadować wszystko bezpośrednio do obliczeń arytmetycznych i oszczędzić drugiej pętli: pastebin.com/LB0BjDMZb=`date +%s`
→b=$SECONDS
sugestię.bash
jak tylko arytmetyka liczb całkowitych, całe rozwiązanie musi zostać przepisane, aby użyć zewnętrznego narzędzia do obliczeń. Zazwyczajbc
: pastebin.com/eYFEVUuzJavaScript (ES6), 148 bajtów
Obiecuje czekać 9 razy przez 7 sekund w sumie 63 sekundy (faktycznie 63,43, kiedy próbuję), ale tak naprawdę zajmuje tylko 7,05 sekundy czasu rzeczywistego, gdy próbuję.
źródło
C, 127 bajtów (obraca procesor)
To rozwiązanie obraca procesor zamiast spać i odlicza czas za pomocą
times
funkcji POSIX (która mierzy czas procesora zużywany przez proces nadrzędny i wszystkie oczekiwane dzieci).Odrzuca 7 procesów, które wirują przez 9 sekund na sekundę, i drukuje czasy końcowe w zegarach C (w większości systemów 100 tyknięć zegara = 1 sekunda).
Przykładowe dane wyjściowe:
co oznacza 9,06 sekund czasu rzeczywistego i 63,47 sekundy całkowitego czasu procesora.
Aby uzyskać najlepsze wyniki, skompiluj za pomocą
-std=c90 -m32
(wymuś kod 32-bitowy na komputerze 64-bitowym).źródło
PowerShell v4, 144 bajty
Zestawy są
$d
równeGet-Date
i usuwa wszystkie istniejące historie zadańGet-Job | Remove-Job
. Następnie zapętlamy1..20|%{...}
i każda iteracja wykonujeStart-Job
przekazanie bloku skryptu{$x=date;sleep 3;((date)-$x).ticks/1e7}
dla zadania (co oznacza, że każde zadanie wykona ten blok skryptu). Przesyłamy dane wyjściowe do>$null
, aby ukryć informacje zwrotne (tj. Nazwę zadania, status itp.), Które zostaną zwrócone.Blok skryptu ustawia się
$x
naGet-Date
, potemStart-Sleep
na3
sekundy, a następnie bierze nowyGet-Date
odczyt, odejmuje$x
, pobiera.Ticks
i dzieli przez,1e7
aby uzyskać sekundy (z precyzją).Z powrotem w głównym wątku, tak długo, jak każda praca jest nadal
-S
tatus"Running"
, obracamy się w pustejwhile
pętli. Kiedy to zrobimy, będziemyGet-Job
pobierać obiekty dla wszystkich istniejących zadań, potokować te, doReceive-Job
których pobiorą ekwiwalent STDOUT (tj. To, co wyprowadzają),-join
wyniki wraz z+
, i potokować doiex
(Invoke-Expression
i podobnie doeval
). Spowoduje to wygenerowanie wynikowego czasu uśpienia plus narzutu.Ostatnia linia jest podobna, ponieważ pobiera nową datę, odejmuje oryginalny znacznik daty
$d
, pobiera.Ticks
i dzieli przez,1e7
aby wyświetlić całkowity czas wykonania.NB
OK, więc to trochę zgubne zasady. Najwyraźniej przy pierwszym uruchomieniu PowerShell musi załadować kilka zestawów .NET z dysku dla różnych operacji wątków, ponieważ nie są one ładowane z domyślnym profilem powłoki. Kolejne wykonania, ponieważ zestawy są już w pamięci, działają dobrze. Jeśli pozostawisz okno powłoki wystarczająco długo bezczynne, dostaniesz wbudowane zbieranie śmieci w PowerShell i usuniesz wszystkie te zespoły, co spowoduje, że następne wykonanie zajmie dużo czasu, gdy zostaną ponownie załadowane. Nie jestem pewien, jak to obejść.
Możesz to zobaczyć w czasach wykonania w poniższych uruchomieniach. Uruchomiłem nową powłokę, przeszedłem do katalogu golfa i wykonałem skrypt. Pierwszy bieg był przerażający, ale drugi (wykonany natychmiast) działał dobrze. Następnie pozostawiłem muszlę bezczynną na kilka minut, aby umożliwić przechodzenie do śmiecia, a potem ta kolejność jest znowu długa, ale kolejne serie znów działają dobrze.
Przykład działa
źródło
JavaScript (ES6),
212203145 bajtówTen kod po załadowaniu tworzy 10 obrazów w odstępie dokładnie 6 sekund.
Czas wykonania nieznacznie przekracza go (z powodu obciążenia).
Ten kod zastępuje wszystko w dokumencie!
Zakłada się, że używasz kodowania jednobajtowego dla backticks, co jest wymagane, aby silnik Javascript nie zadziałał.
Alternatywnie, jeśli nie chcesz spędzać 6 sekund na czekaniu, oto 1-bajtowe rozwiązanie, które kończy się w mniej niż sekundę:
Różnica polega na tym, że ten kod czeka 600 ms na 100 obrazów. To da ogromną kwotę narzutu.
Stara wersja (203 bajtów):
Ten kod tworzy 10 ramek iframe z odstępem dokładnie 6 sekund każdy, zamiast tworzyć 10 obrazów.
Wersja oryginalna (212 bajtów):
źródło
Ruby, 92
źródło
JavaScript (ES6),
10892 bajtyRobię nową odpowiedź, ponieważ używa nieco innego podejścia.
Generuje ogromną liczbę
setTimeout
s, które prawie wszystkie są wykonywane z odstępem 4 ms.Każdy interwał trwa 610 milisekund, w sumie 99 interwałów.
Zwykle działa w ciągu 610 ms, a całkowity czas wykonania wynosi około 60,5 sekundy.
Zostało to przetestowane na Google Chrome w wersji 51.0.2704.84 m, na Windows 8.1 x64.
Stara wersja (108 bajtów):
źródło
Scratch - 164 bajty (16 bloków)
Zobacz to w akcji tutaj .
Używa zmiennej o nazwie „t” i duszka o nazwie „s”. Duszek tworzy własne klony, z których każdy czeka 8 sekund, i zwiększa zmienną taktowaną przez cały czas oczekiwania. Na końcu podaje całkowity czas wykonania i całkowity czas oczekiwania (na przykład
65.488 8.302
).źródło
Clojure,
135120111109 bajtówWersja sformatowana z nazwanymi zmiennymi:
wyjście (w nanosekundach):
Zmieniony format. Dzięki Adám, mogłem przeoczyć specyfikację formatu w pytaniu, gdy ją czytam.
Zmieniono na nanoTime dla umiejętności gry w golfa.
Dzięki Cliffroot, zupełnie zapomniałem o notacji naukowej i nie mogę uwierzyć, że nie widziałem
apply
. Myślę, że użyłem tego w czymś, co grałem wczoraj w golfa, ale nigdy nie opublikowałem. Zapisałeś mi 2 bajty.źródło
7e3
zamiast7000
i użyjapply
zamiastreduce
Rdza,
257, 247 bajtówUżywam tych samych czasów, co odpowiedź Mego na Python.
Naprawdę jedynym nieco sprytnym bitem jest użycie ii, aby uzyskać czas trwania 0 sekund.
Wydruki:
Nie golfowany:
Edycja: dobra stara dla pętli jest nieco krótsza
źródło
JavaScript (ES6, przy użyciu WebWorkers),
233215 bajtówUPD: zastąpiono sposób, w jaki pracownik jest wykonywany z ciągu, na bardziej zwarty i przeglądarkowy, w aspekcie zasad dotyczących różnych źródeł. Nie będzie działać w przeglądarce Safari, jeśli nadal ma
webkitURL
obiekt zamiastURL
w przeglądarce IE.źródło
{ "message": "Uncaught SecurityError: Failed to construct 'Worker': Script at 'data:application/javascript,a%3Dnew%20Date()%3BsetTimeout(()%3D%3EpostMessage(new%20Date()-a)%2C5e3)' cannot be accessed from origin 'null'.", "filename": "http://stacksnippets.net/js", "lineno": 13, "colno": 45 }
Python 2, 130 bajtów
To jest pochodna odpowiedzi Mego, ale wystarczająco różni się od tego, że myślałem, że powinna to być osobna odpowiedź. Jest testowany do pracy w systemie Windows.
Zasadniczo usuwa 9 wątków, które śpią przez 7 sekund, podczas gdy rodzic śpi przez 8 lat. Następnie drukuje czasy. Przykładowe dane wyjściowe:
W systemie Windows
time.clock
mierzy czas na ścianie od pierwszego połączenia.źródło
time.clock()
zachowuje się inaczej między platformami Windows i UNIX / Linux .Perl 6,
7271 bajtówMoże to być krótszy sposób
to wychodzi
źródło
Mathematica, 109 bajtów
Funkcja anonimowa. Do uruchomienia wymagana jest licencja z sub-jądrem 7+. Zajmuje 9 sekund w czasie rzeczywistym i 63 sekundy czasu jądra, nie uwzględniając kosztów ogólnych. Pamiętaj, aby uruchomić poprzednie instrukcje tylko raz (aby nie próbowało ponownie uruchamiać jądra). Testowanie:
źródło
JavaScript (ES6), 105 bajtów
Zaktualizowana wersja: 106 bajtów Pożyczono od @ Ismaela Miguela, ponieważ miał świetny pomysł, aby skrócić czas snu i wydłużyć interwały.
JavaScript Ungolfed, 167 bajtów
źródło
d+=t()-s;if(!c)alert([t()-i,d])
możesz pisaćd+=t()-s;c||alert([t()-i,d])
, co pozwoli zaoszczędzić kilka bajtów. Ponadto, jeśli usunąć funkcję i przepisać to wszystko, można konkurować z moim 92-bajtowy długi rozwiązanie:for(c=8,i=(t=Date.now)(d=0);c--;)setTimeout((c,s)=>{d+=t()-s;c||alert([t()-i,d])},8e3,c,t())
. I tak, ten również ma 92 bajty długości.Java,
358 343 337 316313 bajtówi nie golfił
nie próbuj tego w domu, ponieważ to rozwiązanie nie jest bezpieczne dla wątków.
Edytować:
Wziąłem sugestie @A Boschmana i @ Adáma, a teraz mój program wymaga mniej niż 10 sekund na uruchomienie, a jego rozmiar jest krótszy o 15 bajtów.
źródło
Thread.
wywołań metody static sleep ()? Czy ten program nie zakończy się w ciągu nieco ponad 10 sekund, dyskwalifikując go?static long t
. Wspominam o tym tylko dlatego, że specyfikacja mówi „Obie wartości czasu muszą mieć dokładność co najmniej 0,1 sekundy”.long
przeds
i dodać,s
do,static long t,i,s;
aby zaoszczędzić kilka bajtów.C (z pthreads),
339336335 bajtówźródło
C90 (OpenMP), 131 bajtów (+ 17 dla zmiennej env) = 148 bajtów
Przykładowe dane wyjściowe:
Uwagi:
7091 jest w cyklach (100 / s), więc program działał przez 70 sekund
Mógłbym być znacznie krótszy, gdybym wymyślił sposób na uruchomienie timera inny niż omp_get_wtime (), ponieważ wtedy mógłbym również usunąć instrukcję include.
Uruchom z OMP_NUM_THREADS = 9
źródło
Wspólne Lisp (SBCL) 166 bajtów:
Powoduje to po prostu odrodzenie wątków, które śpią, a następnie atomowy przyrost czasu. Pętla zewnętrzna obraca się, czekając, aż całkowity czas wyniesie ponad 60000 tyknięć (tj. 60 s na sbcl). Licznik jest przechowywany na liście z powodu ograniczeń typów miejsc, w których atomic-incf może modyfikować. Może to zabraknąć miejsca przed zakończeniem pracy na szybszych komputerach.
Nie golfowany:
źródło
Perl, 101 bajtów
Rozwidla 7 procesów potomnych, z których każdy czeka 9 sekund.
Przykładowe dane wyjściowe:
źródło
Groovy,
158143 znakówPrzykładowy przebieg:
źródło
Eliksir, 168 bajtów
Przykładowy przebieg:
Dane wyjściowe to całkowity czas oczekiwania, a następnie czas działania programu, w mikrosekundach.
Program odradza się przez 14 sekund
Task
i czeka na każdego z nich, odwzorowując je, a następnie znajduje sumę upływającego czasu. Wykorzystuje Erlangatimer
do pomiaru czasu.źródło
Haskell,
278271262246 bajtów!
mierzy czas działaniaa
(drugi argument) i stosujeb
(pierwszy argument) do wyniku.w
jest funkcją spania.main
jest mierzony sam, a wynik drukowany (print!...
).#
toreplicateM
powtórzenie podanej akcji N razy (i powrót zt
powodu gry w golfa).Wewnątrz mierzonej części 9 wątków (
replicate 9 $ forkIO ...
) śpi przez5^10
milisekundy (9,765625 sekund) i umieszcza wynik (writeChan
) na rurze utworzonej przez główny wątek (newChan
), który sumuje 9 wyników i drukuje sumę (getChanContents >>= print . sum . take 9
).Wynik:
źródło
Python 2, 132 bajty
Korzysta z puli procesów, aby spawnować 9 procesów i pozwolić każdemu z nich spać przez 7 sekund.
Najpierw drukuje całkowity czas snu, a następnie rzeczywisty czas działania:
źródło
Rubin (z
parallel
klejnotem),123116 bajtówEdycja: Dodano odniesienie „Time.now” z odpowiedzi Ruby autorstwa histocrata.
źródło
Matlab, 75 bajtów
Szybkie wyjaśnienie:
parfor
tworzy równoległą pętlę for, rozmieszczoną w puli pracowników.tic
itoc
mierz upływ czasu (i moim zdaniem są jedną z najlepiej nazwanych funkcji w MATLAB). Ostatni wiersz (tablica z całkowitym czasem spania i upływem czasu rzeczywistego) jest wyprowadzany, ponieważ nie jest zakończony średnikiem.Zauważ jednak, że tworzy to aż 9 pełnoprawnych procesów MATLAB. Są szanse, że ten konkretny program nie zakończy się w ciągu 10 sekund na twoim komputerze. Myślę jednak, że w przypadku instalacji MATLAB, która nie ma żadnych zestawów narzędzi, z wyjątkiem zestawu narzędzi Parallel Computing - zainstalowanego w wysokiej klasy systemie z dyskiem SSD - może zakończyć się w ciągu 10 sekund. W razie potrzeby możesz dostosować parametry, aby mniej procesów śpiło więcej.
źródło
b
jest prawdopodobnie dlatego, że już coś miałeś w swoim obszarze roboczym. Nie mam problemów z używaniemparfor q=b