To jest moje pierwsze pytanie w golfa i bardzo proste, dlatego z góry przepraszam, jeśli mogłem złamać jakieś wytyczne społeczności.
Zadanie polega na wydrukowaniu w porządku rosnącym wszystkich liczb pierwszych mniejszych niż milion. Format wyjściowy powinien wynosić jedną liczbę na linię wyjściową.
Celem, podobnie jak większości zgłoszeń do gry w golfa, jest zminimalizowanie rozmiaru kodu. Optymalizacja pod kątem czasu działania jest również bonusem, ale jest celem drugorzędnym.
code-golf
kolmogorov-complexity
primes
Delan Azabani
źródło
źródło
10^6
jest jeszcze krótszy;)1e6
:-DOdpowiedzi:
Mathematica ,
1724Dla porównania:
Jak zauważono w komentarzu, nie podałem jednej liczby pierwszej na linię; korekta:
źródło
Prime~Array~78498
również 17 :)Print/@
i kończenie za pomocą,;
aby zapobiec wyświetlaniu długiej listyNull
poprawek s, które kosztem 8 dodatkowych znaków.Python 3, 46 bajtów
Zanim pętla osiągnie testowanie
k
, iteracyjnie obliczyła czynnik kwadratowyP=(k-1)!^2
. Jeślik
jest liczbą pierwszą, to nie pojawia się w produkcie1 * 2 * ... * (k-1)
, więc nie jest to czynnikiemP
. Ale jeśli jest złożony, wszystkie jego czynniki pierwsze są mniejsze, a więc w produkcie. Kwadratowanie jest właściwie potrzebne tylko po to, by powstrzymać sięk=4
od fałszywego nazywania liczbą pierwszą.Mocniej wynika z twierdzenia Wilsona, że gdy liczba
k
pierwsza jestP%k
równa1
. Chociaż potrzebujemy tylko, aby nie była tutaj zerowa, ogólnieP%k
jest użyteczna, ponieważ jest zmienną wskaźnikową określającą, czyk
jest liczbą pierwszą.źródło
C, 61 znaków
Prawie dokładnie taki sam jak ten (pytanie jest prawie dokładnie takie samo).
źródło
SEG-FAULT
po wydrukowaniu881
-O3
abygcc
rozwiązać problem !!n=2;main(m){n<1e6&&main(m<2?printf("%d\n",n),n:m-++n%m);}
MATLAB
(16)(12)Niestety dane wyjściowe w jednym wierszu:
ale rozwiązuje to prosta transpozycja macierzy:
i mogę wyciąć niektóre znaki za pomocą notacji wykładniczej (zgodnie z sugestiami w komentarzach):
źródło
1e6
zamiast1000000
pomaga tutaj.'
końcaBash (37 znaków)
(60 znaków)
na moim komputerze (procesor 2,0 GHz, 2 GB RAM) trwa 14 sekund.
źródło
seq 2 1000000|factor|sed 's/[0-9]*: //g;/^.* .*$/ d'
seq 1e6|factor|awk '$0=$2*!$3'
jest nieco krótszy.c p
tam, gdzie c jest dowiązaniem symbolicznym do cat, a p to plik tekstowy z liczbami pierwszymi do miliona ... czy możesz to zrobić z wbudowanymi powłokami?seq
i jużfactor
sącoreutils
, więc jest to uzasadnione.sed
jest również dość wszechobecny.coreutils
można traktować jak wbudowany. Bash bez coreutils jest jak C ++ bez STL.J, 21 znaków
które można skrócić
jeśli wiesz, ile liczb pierwszych jest poniżej 1000000.
źródło
,.
, zamiast 1 [\\, aby zapisać znak. Usuń niepotrzebne nawias i używać notacji wykładniczej:1e6
.,.i.&.(p:^:_1)1e6
głowy : nie krócej (po zastosowaniu sugestii @Omara), ale użycie tego było zbyt interesujące.PowerShell,
4744 bajtówBardzo powoli, ale najkrótszy, jaki mogłem wymyślić.
PowerShell, 123 bajty
To jest znacznie szybsze; daleki od optymalnego, ale dobry kompromis między wydajnością a zwięzłością.
źródło
Rubin 34
źródło
Bash, 30 bajtów
Ponieważ saeedn nie zareaguje na moją sugestię - która jest zarówno krótsza, jak i szybsza niż jego podejście - pomyślałem, że opublikuję własną odpowiedź:
Jak to działa
wyświetla wszystkie liczby całkowite dodatnie do 1 000 000.
uwzględnia je jeden po drugim. Dla pierwszych dziesięciu wynik jest następujący:
Wreszcie,
zmienia całą linię (
$0
) na iloczyn drugiego pola (pierwszego czynnika pierwszego) i logicznej negacji trzeciego pola (1
jeśli jest to jeden czynnik pierwszy lub mniej, w0
przeciwnym razie).Zastępuje to wiersze odpowiadające liczbom podstawowym samą liczbą, a wszystkie inne wiersze zerami. Ponieważ awk drukuje tylko prawdziwe wartości, drukowana będzie tylko liczba pierwsza.
źródło
awk '$0=$2*!$3'
jest niesamowicie fajny!Rubin
5041źródło
.to_a
, jak już zawiera Enumerableselect
. Możesz także użyć skrótu do symbolu # to_proc, aby go jeszcze bardziej skrócić:p (2..1e6).select &:prime?
(1 nie jest liczbą pierwszą)require'prime';p Prime.take 78498
.Bash, 37 lat
Zagram więcej, jeśli mogę ...
Większość z nich próbuje przeanalizować
factor
niewygodny format wyjściowy.Wykonanie na moim komputerze zajmuje około 5,7 sekundy.
(Zdarzyło się, że mój post jako pierwszy wszedł na drugą stronę odpowiedzi, więc nikt go nie zobaczy ...)
Stare rozwiązanie
Jest to dłuższe i wolniejsze (zajmuje 10 sekund).
źródło
factor
wcześniej nie spotkałem , ale jest tam w coreutils!seq 1e6|factor|grep -oP "(?<=: )\d+$"
wyglądając perlowo-grepowo-P
włącza wyrażenia regularne w stylu perla.(?<=: )
jest dodatnim wyglądem dla ciągu „:”. Zasadniczo mówi to, że „:” musi pojawić się przed tym\d+$
, co pasuje , ale tak naprawdę nie jest częścią dopasowania, więc-o
opcja daje nam tylko jeden pasujący numer po dwukropku, tj. Podaje tylko liczby, w których występuje tylko jeden czynnik, tj. Liczba pierwsza.Python 3.x: 66 znaków
Bardziej wydajne rozwiązanie: 87 znaków
Na podstawie sita Eratostenesa.
źródło
0
i1
. Możesz to naprawić, używając zamiast tegorange(2,10**6)
. Ponadto uważam, żeif
instrukcja musi znajdować się w osobnym wierszu niż out,for
inaczej wystąpi błąd.Haskell, 51
źródło
mapM_
namapM
, zwracana wartość nie zostanie wydrukowana, a to jest Code Golf. ;)APL, 15
Mój tłumacz napotkał problemy z pamięcią, ale działa teoretycznie.
źródło
⍪
znaku z przodu, aby utworzyć jeden numer na linię, i nie potrzebujesz,
.⍳
to pierwsze liczby całkowite.1↓
upuszcza pierwszy.p←
przypisuje do p.p∘.×p
tworzy tabliczkę mnożenia.p~
usuwa z p wszystko, co jest po prawej stronie. (,
nie jest potrzebny, wrzuca tabelę w listę.)Perl, 49 bajtów
Wyrażenie regularne kung fu :)
Wersja bez golfa:
Nie poczyniłem nawet 10% postępu, gdy piszę ten post!
Źródło wyrażenia regularnego: http://montreal.pm.org/tech/neil_kandalgaonkar.shtml
źródło
1000000
można napisać10**6
Julia, 11 lat
Wygląda na to, że wbudowane opinie są coraz bardziej popularne, a do dłuższej odpowiedzi potrzebowałem więcej słów.
źródło
J (15 lub 9)
Nie mogę uwierzyć, że ten beat Mathematica (nawet jeśli jest
to singielo 2 znaki)Lub:
źródło
... The output format should be one number per line of output.
Dlatego moja odpowiedź zaczyna się od1[\
.gs2, 5 bajtów
Zakodowane w CP437:
1C 29
popycha milion,11 6C
jest liczbą pierwszą poniżej,54
pokazuje linie.źródło
GolfScript, 22/20 (20/19) bajtów
Kosztem prędkości kod może zostać skrócony o dwa bajty:
Jeśli format wyjściowy określony w edytowanym pytaniu zostanie pominięty (co robi wiele istniejących odpowiedzi), dwa bajty można zapisać w szybkiej wersji, a jeden w wolniejszym:
Spowoduje to wydrukowanie dodatkowego LF po liczbach pierwszych dla wersji szybkiej i wydrukuje liczby pierwsze jako tablicę dla wersji wolnej.
Jak to działa
Obie wersje są implementacjami sita Eratostenesa .
Szybka wersja wykonuje następujące czynności:
Ustaw
A = [ 2 3 4 … 999,999 ]
i| = [ 0 1 2 … 999,999 ]
.Ustaw
N = A[0]
i wydrukujN
.Zebrać wszystkie n-ty element z
|
wC
. Są to wielokrotnościN
.Set
A = A - C
.Jeśli
A
nie jest pusty, wróć do 2.Wersja powolna działa w podobny sposób, ale zamiast sukcesywnego usuwania wielokrotności minimum „A” (co zawsze jest liczbą pierwszą), usuwa wielokrotności wszystkich liczb całkowitych dodatnich poniżej 1 000 000.
Konkurencyjność
W przypadku braku wbudowanych funkcji matematycznych do faktoryzacji lub sprawdzenia pierwszeństwa, wszystkie rozwiązania GolfScript będą albo bardzo duże, albo bardzo nieefektywne.
Choć wciąż daleko mi do wydajności, wydaje mi się, że osiągnąłem przyzwoity stosunek prędkości do wielkości. W chwili jego przedstawienia takie podejście wydaje się być najkrótsze z tych, które nie wykorzystują żadnego z wyżej wymienionych wbudowanych elementów. Mówię, wydaje się, ponieważ nie mam pojęcia, jak działają niektóre odpowiedzi ...
Dokonałem analizy porównawczej wszystkich czterech przesłanych rozwiązań GolfScript: w0lf (podział próbny), mojej drugiej odpowiedzi (twierdzenie Wilsona) i dwóch z tej odpowiedzi. Oto wyniki:
źródło
NARS2000 APL, 7 znaków
źródło
Golfscript
26 2524Edytuj (zapisałem jeszcze jeden znak dzięki Peterowi Taylorowi):
Stary kod:
Ten kod ma tylko wartość teoretyczną, ponieważ jest niewiarygodnie wolny i nieefektywny. Myślę, że uruchomienie może potrwać kilka godzin.
Jeśli chcesz to przetestować, spróbuj na przykład tylko liczb pierwszych do 100:
źródło
\;
ją*
. (Możesz również uzyskać znacznie szybsze obliczanie liczby obecnych postaci, znajdując pierwszy dzielnik zamiast wszystkich:10 6?,2>{.),2>{1$\%!}?=},`
.,
z:x,
i\.@
zx\
(spacje z powodu ucieczki problemy z MD w komentarzach) i zdjąć*
.CJam - 11
1e6,
- tablica 0 ... 999999{mp},
- wybierz liczby pierwszeN*
- połącz z nowymi liniamiźródło
GolfScript, 25 (24) bajtów
Jeśli format wyjściowy określony w edytowanym pytaniu zostanie pominięty, można zapisać jeden bajt:
Spowoduje to wydrukowanie liczb pierwszych jako tablicy (jak robi to wiele innych rozwiązań) zamiast jednej w linii.
Jak to działa
Ogólna idea polega na użyciu twierdzenia Wilsona , które stwierdza, że n > 1 jest liczbą pierwszą wtedy i tylko wtedy
Benchmarki
Szybszy niż podział próbny, ale wolniejszy niż sito Eratostenesa. Zobacz moją drugą odpowiedź .
źródło
Java, 110 bajtów
Wykorzystanie podziału jednoargumentowego przez wyrażenie regularne jako testu pierwotności.
źródło
C,
9188858281807672 znakówAlgorytm jest strasznie nieefektywny, ale ponieważ uprawiamy golfa kodu, nie powinno to mieć znaczenia.
źródło
main(i,j,b){for(;i++<1e6;b++&&printf("%d\n",i))for(j=2;j<i;)b=i%j++&&b;}
lub jakiś taki pomysł (skoro go nie skompilowałem)i
pewno będzie 0? Myślę, że jeśli podasz jakiś argument, zawiedzie. Myślę też, żej
wystąpi jakiś błąd typu. Nie jestem pewienb
.Mathematica 25
Zakładając, że nie znasz liczby liczb pierwszych mniejszych niż 10 ^ 6:
źródło
J, 16 znaków
Bez wymogu formatu wyjściowego można to zmniejszyć do 13 znaków:
1]\
po prostu bierze tablicę liczb pierwszych 1, zamienia ją w tablicę liczb 2 i umieszcza każdą liczbę pierwszą w osobnym rzędzie - tak więc domyślny format wyjściowy interpretera zamienia listę jednej linii w jedną liczbę pierwszą w linii.(#~ f) y
jest w zasadziefilter
, gdzief
zwraca wartość logiczną dla każdego elementu wy
.i.1e6
jest zakresem liczb całkowitych [0,1000000) i1&p:
jest funkcją logiczną, która zwraca 1 dla liczb pierwszych.źródło
R,
4543 znakówDla każdej liczby x od 2 do 1e6 po prostu ją wypisz, jeśli liczba x mod 2 do x, które są równe 0, jest mniejsza niż 2.
źródło
Bash (433643)
Moja (niezbyt sprytna) próba użycia współczynnika do uwzględnienia produktu.
Niestety przy dużych liczbach produkt jest oczywiście ogromny. Uruchomienie zajęło również ponad 12 godzin. Postanowiłem go jednak opublikować, ponieważ uważałem, że jest wyjątkowy.
Oto pełny kod.
Gdyby było liczbą pierwszą poniżej szóstej, byłoby rozsądne.
No cóż, próbowałem.
źródło
factor
działanie jest znacznie gorsze niż podstawowy algorytm podziału próby.C #, 70
Długo się tu nie zobaczycie ...
źródło
double
1e6
naint
, aleint
jest to wymagane przezRange
. (2) WewnętrzneRange
musi przyjmować co najwyżejn-2
warunki, w przeciwnym razie przetestujesz,n % n
co jest wyraźnie0
. (3) Piszesz,x%n
kiedy chceszn%x
. Rozwiązując te problemy, coś takiego będzie działać:Enumerable.Range(2,999999).Where(n=>Enumerable.Range(2,n-2).All(x=>n%x!=0))
Jednak nadal nie wyświetla to liczb; wymagano jednego na linię.