Sleep Sort to algorytm sortowania liczb całkowitych, który znalazłem w Internecie. Otwiera strumień wyjściowy i dla każdej liczby wejściowej równolegle opóźnia liczbę sekund i wysyła tę liczbę. Ze względu na opóźnienia najwyższa liczba zostanie wyprowadzona na końcu. Szacuję, że ma O (n + m), gdzie n to liczba elementów, a m to najwyższa liczba.
Oto oryginalny kod w Bash
#!/bin/bash
function f() {
sleep "$1"
echo "$1"
}
while [ -n "$1" ]
do
f "$1" &
shift
done
wait
Oto pseudokod
sleepsort(xs)
output = []
fork
for parallel x in xs:
sleep for x seconds
append x to output
wait until length(output) == length(xs)
return output
Twoim zadaniem jest wdrożenie funkcji Sleep Sort jako funkcji w wybranym języku programowania. Możesz pominąć wszelkie czynniki współbieżności, takie jak warunki wyścigu i nigdy nie blokować żadnych wspólnych zasobów. Najkrótszy kod wygrywa. Definicja funkcji liczy się do długości kodu.
Lista wejściowa jest ograniczona tylko do nieujemnych liczb całkowitych, a długość listy wejściowej powinna być odpowiednio długa (przetestuj co najmniej 10 liczb), aby warunki wyścigu nigdy się nie zdarzyły. i zakładając, że warunki wyścigowe nigdy się nie zdarzają.
Odpowiedzi:
Rodzaj kiepskiej próby Perla ,
5955523832 znaków :map{fork||exit print sleep$_}@a
Gołe kości: 25 znaków:
... jeśli nie masz nic przeciwko sortowaniu wyników jako wyniku wyjściowego:
map{fork||die sleep$_}@a
Ze wszystkimi dodatkami:
(dla maksymalnej zgodności z wyzwaniem, 44 znaki)
sub t{map{fork||exit print sleep$_}@_;wait}
Jeśli pozwolisz Perlowi na ciebie czekać, 39 znaków:
sub t{map{fork||exit print sleep$_}@_}
I znowu, jeśli nie masz nic przeciwko
die()
, 32 znaki ...sub t{map{fork||die sleep$_}@_}
Zauważ, że w Perlu 6 lub gdy deklarowana jest funkcja „powiedz”, można zastąpić tę
print
funkcjęsay
, zapisując znak w każdym przypadku. Oczywiście, ponieważdie
oba kończą rozwidlony proces i zapisują dane wyjściowe, pozostaje to najkrótsze rozwiązanie.źródło
perl-E
aby włączyć funkcje 5.010, takie jaksay
(fork&&die sleep$_)for@a
też działaC , 127 znaków, dość oczywiste rozwiązanie:
(Kompilowany
gcc -std=c99 -fopenmp sort.c
i ignorujący wszystkie ostrzeżenia.)źródło
for(;c>=0;--c){int x=atoi(v[c]);
. Nie jestem pewien, czy to dozwolone.Ruby 1.9, 32 znaki
Jako funkcja:
Jeśli możemy po prostu użyć predefiniowanej zmiennej, zmniejsza się ona do 25 znaków:
źródło
Thread.new{p sleep i}
drukując dane wyjściowe.JavaScript , 65 znaków (w zależności od tego, czy używasz,
console.log
czy czegoś innego do wyświetlania wyniku)Zakłada się, że
a
jest to tablica liczb całkowitych nieujemnych imap()
istnieje w prototypie macierzy (JavaScript 1.6+).źródło
1e3
zamiast tego.alert
jest blokującym wyjściemprompt
JavaScript, blokuje wejścieconfirm
JavaScript i blokuje wejście binarne JavaScript. Gdyby JS miał być napisany w linii poleceń, byłyby to wywołania, których użyłbyś.APL (
1513)Co to robi:
źródło
⎕DL
funkcji, która jest trybem uśpienia.Cztery próby w Erlang:
Wyjdź na konsolę, skorzystaj z tej możliwości,
9ms * Number
ponieważ jest to wystarczająco dużo, aby działało (testowane na płycie wbudowanej Atom = wolno):Potrzebuje 60 znaków
Dane wyjściowe na konsolę są całkowicie nienawistne, więc
P
zamiast tego wysyłamy komunikat do przetworzenia :Potrzebuje 55 znaków
Wysyłanie po pewnym czasie można również wykonać inaczej (działa to nawet z
1ms * Number
):Potrzebuje 41 znaków
W rzeczywistości jest to trochę niesprawiedliwe, ponieważ wbudowana funkcja
send_after
jest opóźniona i wymagaerlang:
prefiksu przestrzeni nazw , jeśli weźmiemy pod uwagę tę przestrzeń nazw zaimportowaną (wykonaną na poziomie modułu):Potrzebuje 34 znaków
źródło
C # - 137 znaków
Oto odpowiedź w języku C # (zaktualizowana o stopnie równoległości zgodnie z komentarzem)
źródło
WithDegreeOfParallelism
aby to działało, analogicznie jaknum_threads
w moim kodzie OpenMP C.void m(int[] l){foreach(var i in l){var t=new Thread(()=>{Thread.Sleep(int.Parse(s));Console.Write(s);});t.Start();}}}
Python - 81
93148150153Poprawianie kodu @ BiggAl, ponieważ w tę grę gramy ....
... lub 97
175z opóźnionym uruchomieniem wątkuPobiera dane z wiersza poleceń, ala
Podobnie jak w przypadku wielu golfów pythonowych, pojawia się moment, w którym kod jest na tyle zwarty, że aliasing zmiennych w celu skrócenia nazw nawet nie zapisuje znaków.
Ten jest jednak funky, ponieważ alias sys i wątki ZARÓWNO jako t, więc sys.argv staje się t.argv. Krótszy niż z importu foo * i oszczędności postaci netto! Jednak przypuszczam, że Guido nie byłby zadowolony ...
Uwaga do samodzielnego uczenia się c i zaprzestania gry w python.ŚWIĘTA KRÓWKA JEST KRÓTSZE NIŻ ROZWIĄZANIE C!źródło
daemon
nie wymaga ustawiania, chyba że uruchamiasz go jako demon, a użycie argumentów pozycyjnych jest krótsze, szczególnie. Jeśli aliasNone
doN
j
wydaje się skończyć jakoFalse
- efekt uboczny próby zrobienia zbyt wiele w jednej linii?as t,s
, a następnie zmienić w użycius
dlasys
print
funkcji zamiastsys.stdout.write
?Dla zabawy, oto wersja ColdFusion (8+) ;-) Ma 109 znaków, nie licząc zawijania linii i wcięć, które dodałem tutaj dla czytelności.
Zakłada się, że
<cfoutput>
to działa. Kilka znaków można zapisać, pisząc wszystko w jednym wierszu.źródło
Java (aka nigdy nie wygrywa w codegolf):
234211187 znakówbez golfa:
źródło
throws Throwable
i pozbyć sięcatch
klauzuli.Long.parseLong
jeLong.valueOf
.public
ifinal
można je usunąć;class M{public static void main
może byćinterface M{static void main
(Java 8+);Long.parseLong(a)
może byćnew Long(a)
(co daje 165 bajtów )JavaScript - 52 znaki
źródło
Scala -
4240 znaków (przypadek specjalny)Jeśli masz pulę wątków, co najmniej rozmiar liczby elementów listy:
Scala - 72 znaki (ogólnie)
źródło
{}
podczas pobytu na jednej linii.{}
jedną instrukcję , ale nadal potrzebujesz jej do grupowania rzeczy oddzielonych;
, jedną linią lub nie. W{}
niektórych przypadkach możesz pisać instrukcje wieloliniowe (na przykład if / else).()
w liniach jednokreskowych. myślę, że to kwestia gustu. (Po prostu tak naprawdę nie rozumiem, dlaczego()
w ogóle są wspierani, gdy są{}
zastępowani. Może nie od razu wyobcują użytkowników Java). Scala jest fajna, ale definiowanie bloków kodu przez wcięcie jest wyraźnie lepsze. (i tak następuje wojna religijna;))()
do pojedynczych instrukcji. Spróbuj(1 to 9).map(i => {val j = i+1; i*j})
wpisać REPL, a następnie sprawdź, co się stanie, jeśli użyjesz(1 to 9).map(i => (val j = i+1; i*j))
.Haskell - 143 znaki
Prawdopodobnie można by to skrócić, przyjmując wejście na stdin, gdyby to była opcja, ale jest już późno i tak czy inaczej, nadal ma 104 znaki dla samej funkcji.
źródło
Befunge-98,
3831 bajtówWiem, że to stare wyzwanie, ale niedawno odkryłem zarówno sleepsort, jak i języki 2D, wpadłem na pomysł, jak je połączyć i szukałem miejsca, aby je opublikować, więc oto jesteśmy.
Główny adres IP odczytuje liczbę (
&
), a następnie uderza w to,t
który go klonuje: jeden przechodzi do tej samej linii i wykonuje cykle, odczytuje nowe liczby i generuje nowe potomki, aż osiągnie EOF, który kończy sekwencję. Wszystkie procesy potomne utkną w zamkniętej pętli (v
i^
trzeciej kolumny), dopóki główny adres IP nie zakończy odczytu danych wejściowych i nie wykona sekwencji poleceń'<21p
, która umieszcza znak<
w pozycji (1,2), zastępując^
i zwalniając wszystkie procesy potomne, które zaczynają się cyklicznie, zmniejszając o 1 ich liczbę przy każdej iteracji. Ponieważ szybkość wykonywania różnych adresów IP jest zsynchronizowana w befunge, będą one kończyć (i drukować swoją wartość) w kolejności, sortując listę danych wejściowych.źródło
Trochę późno na imprezę:
Klon -
9183 znakówW 91:
W 83:
(Wymaga wersji 15 Maple i oczekuje, że lista zostanie posortowana w L)
źródło
C,
7069 znakówNie czeka na powrót procesów potomnych, w przeciwnym razie działa.
źródło
PHP 57 bajtów
pcntl_fork () jest dostępny tylko w Linuksie.
źródło
Bash (38):
Edycja: zmiennoprzecinkowy od standardowego, oddzielony spacjami lub znakami nowej linii.
źródło
Haskell, 90
Mam nadzieję, że spełnia wszystkie wymagania.
źródło
𝔼𝕊𝕄𝕚𝕟, 11 znaków / 22 bajty
Try it here (Firefox only).
שĤ⇀ôa
, to wygląda świetnie.źródło
Tylko kilka poprawek z wersji @rmckenzie:
Python opóźniony start wątku w
155152114108107:Python bez opóźnienia
130128969593:Zarządzałem kilkoma dodatkowymi optymalizacjami, używając
Timer
zamiastThread
, który ma bardziej zwięzłe wywołanie i wyeliminował potrzebę importowaniatime
. Metoda opóźnionego startu wątku korzysta ze zrozumienia listy, ponieważ eliminuje potrzebę oddzielnego inicjowania listy na początku, chociaż jest ona o dwa znaki dłuższa ("["+"]"+" "-":"
) niż pętla for, więc jest bezużyteczna bez opóźnionego startu i należy uważać, aby użyć listy zamiast generatora, albo tak naprawdę nie tworzysz wątków timera, dopóki nie poruszysz generatora.Czy ktoś jeszcze ma jakieś optymalizacje?
Sztuczka z pomocą
as
pomaga, ale w wersji 2.7.1 możesz zaimportować tylko jeden moduł do aliasu, a po niektórych zabawach o tobie nie możesz, nawetimport mod1,mod2 as a,b
musiszimport mod1 as a, mod2 as b
. Wciąż oszczędza kilka postaci, ale to nie jest lekarstwo - wszystko, co myślałem, że to było ... I w rzeczywistości lepiej zostawić sys jako sys. Aliasing wątków wciąż pomaga ...źródło
Clojure, 54
(defn s[n](doseq[i n](future(Thread/sleep i)(prn i))))
źródło
defn
(nawiasy + lista argumentów: od 54 do 43 znaków), lub użyjfn
zamiastdefn
=> len- = 2, więc powiedziałbym, że w clj jest to 43: DRdza - 150 bajtów
I dlatego nie piszesz golfa w Rust, jest bardziej gadatliwy niż Java;). Zależy od zewnętrznej skrzynki
crossbeam
, bez niej byłoby jeszcze gorzej.Pełny program testowy:
źródło
Trochę nudne, port C #, żeby znów zacząć korzystać z języka:
F # - 90 znaków
źródło
JavaScript, 74
lub 71/65 znaków o niestandardowym charakterze:
źródło
function(a){a.map(function(v){setTimeout(console.log,v,v)})}
mógł działać w co najmniej jednej przeglądarce na 60 bajtów. Oczywiście teraz piszesza=>a.map(v=>setTimeout(console.log,v,v))
zamiast tego.Tcl 8.6, 41 znaków
Musisz to zabić
^C
źródło
VB.NET 100 bajtów
Ponieważ VB.Net wymaga, aby lambda w jednym wierszu zawierały tylko jedną instrukcję, ten kod musi zawierać wiele wierszy:
Nie golfowany:
Jednak nie jestem pewien, czy policzymy instrukcje importu w liczbie bajtów, ponieważ jeśli ich nie policzymy, mógłbym napisać:
VB.NET 71 bajtów
Nie golfowany:
źródło
Groovy, 47 bajtów
Zakłada, że liczby są podane w wierszu poleceń ...
źródło
Mathematica, 34 lub 36 bajtów
Wystarczy dołączyć listę do posortowania na końcu tego kodu i ocenić. Jeśli musi to być poprawna definicja funkcji, zajmuje dwa dodatkowe bajty:
źródło
C ++ 11, 229 bajtów
Niegolfowane i użytkowanie:
źródło