Znalezienie liczb pierwszych to programowy rytuał przejścia i bardzo często pierwszy poważny program, który ktoś buduje (zwykle z podziałem na próby).
Ale same liczby pierwsze są już zużyte. Kolejną o wiele bardziej interesującą rzeczą jest uzyskanie pierwszych luk: najdłuższych jak dotąd przerw między kolejnymi liczbami pierwszymi. Są to dość rzadkie i „cenne”. Kilka pierwszych par i ich różnice to:
2 3 1
3 5 2
7 11 4
23 29 6
89 97 8
113 127 14
...
Mój ojciec obliczał je ręcznie dla zabawy do 10 tys. Zobaczmy, jak krótki jest kod.
Zasady:
- brak wbudowanych funkcji do testowania liczb pierwszych, generowania liczb pierwszych i luk podstawowych
- brak pobierania http://oeis.org/A002386 lub podobnego (z daleka czuję was oszustów :))
- brak wstępnie obliczonych tablic
- kontynuuj drukowanie, dopóki wewnętrzny typ liczb całkowitych nie zawiedzie
Wygrywa najniższa liczba postaci. +10 znaków, jeśli drukujesz odstępy bez liczb pierwszych.
Możesz również pochwalić się wersjami z wbudowanymi funkcjami, jeśli są interesujące. Bądź kreatywny.
Wyjaśnienie: przechodzisz przez liczby pierwsze i raportujesz za każdym razem, gdy widzisz lukę, która jest większa niż jakakolwiek luka, którą widziałeś wcześniej. Na przykład między 3 a 5 jest przerwa o szerokości 2 jednostek. Różnica między 5 a 7 wynosi również 2, ale to stare wieści, że już nas to nie obchodzi. Tylko wtedy, gdy zobaczysz nową największą lukę, zgłoś ją. Odzwierciedla to, w jaki sposób liczby pierwsze stają się coraz rzadsze, gdy luki stają się coraz większe.
EDYCJA : Większość odpowiedzi jest genialna i zasługuje na większe uznanie. Jak dotąd wpis w GolfScript z 48 znakami jest najkrótszy.
Odpowiedzi:
GolfScript
6659574948Chociaż mam problem z uruchomieniem go tutaj http://golfscript.apphb.com/ (może ta strona nie lubi nieskończonej pętli?), Ale działa dobrze, gdy uruchomię ją na moim komputerze z golfscript.rb. Jestem całkiem nowy w GolfScript, więc można go jeszcze bardziej pograć w golfa. AKTUALIZACJA: Nie sądzę, że można to znacznie pogorszyć bez zmiany algorytmu.
Wydrukowano kilka pierwszych wierszy (jeśli nie podoba ci się drukowany „”, możesz dodać; na początku skryptu, ale powoduje to wzrost do 49 znaków):
Ogólne, czytelne dla człowieka pojęcie o tym, jak to działa (kilka rzeczy nieco się różni, ponieważ nie używam stosu w tej wersji):
źródło
Python,
121110109108104103 znakówPo raz pierwszy próbowałem odpowiedzieć tutaj, mam nadzieję, że zrobiłem to dobrze ... nie jestem pewien, czy poprawnie policzyłem postacie.
Hmmm, mógłbym zapisać inną postać na wydruku, obniżając wersję do Pythona 2.x ...
źródło
#
, poważnie nie liczysz znaków ręcznie, prawda? javascriptkit.com/script/script2/charcount.shtmlif all(n%x>0for x in p):
jest nieco krótszy. Możesz także zapisać niektóre znaki, przenosząc instrukcje do tej samej linii (npa=1;b=2;f()
.).JavaScript,
90857874 znakówKrótki kod (Kompilator Google Closure - zaawansowane optymalizacje; niektóre zmiany ręczne; więcej zmian przez @ MT0 )
Długi kod
Wynik
Dość nieefektywny test liczb pierwszych, ale w ten sposób zużywa mniej znaków.
Pierwszy post tutaj, więc proszę wybacz błędy.
źródło
for(a=b=2,c=0;b++;){for(d=b;b%--d;);1==d&&(c<b-a&&console.log(a,b,c=b-a),a=b)}
for(a=b=2,c=0;b++;)for(d=b;b%--d;)d<3&&(c<b-a&&console.log(a,b,c=b-a),a=b)
Mathematica,
114108Pozwala na nieskończoną moc wyjściową, chociaż po pewnym momencie sekwencji wentylator włącza się i zaczynasz podejrzewać, że Twój procesor gra Freecell, starając się wyglądać na zajętego.
Próbka wyjściowa (są to te, które zbiera w pierwszych ~ 30s):
Nieskluczony kod:
źródło
≠
?Haskell -
122116114112110(Nieefektywne) wyrażenie listy głównej skradzione Willowi Nessowi .
- edytuj - nigdy nie wiedziałem,
x|y=z|w=q
że będzie ważny.źródło
MATLAB
10489Właśnie wdrożyłem podstawową metodę, sprawdzając każdy możliwy podział.
Wynik:
źródło
octave
i tainf
funkcja nie działa (a drukowanie jest odraczane do momentu zakończenia pętli). Czy Matlab ma ocenę leniwego zasięgu?76 znaków, dogelang
Konwertowane z mojej wersji Python :
Wynik:
źródło
Golfscript,
595150 znakówCzłowiek każdej postaci jest niezwykle trudny do stracenia:
Wyjście :
Objaśnienie :
Stos jest skonfigurowany, więc każda iteracja zaczyna się od stosu w ten sposób, górna jest po prawej stronie.
[
Wskazuje aktualny znacznik tablicy, czyli gdy interpreter napotka]
, wszystko na stosie od znaku do góry należy umieścić w tablicy.g
to maksymalna jak dotąd luka. Z góry na dół:Wewnątrz pętli:
Jak umieszcza wszystkie dzielniki na liście? Zróbmy to krok po kroku
Co robi, jeśli dzielniki są puste?
Dwie ścieżki: tak i nie. Jeśli tak (pamiętaj, że
if
zużywa najwyższą wartość na stosie):Jeśli nie:
W obu przypadkach nasz stos jest teraz w formie
... | g [ c | c | c
.Teraz
do
wyskakuje najwyższa wartość ze stosu - zawszec
- i zapętla się, jeśli jest dodatnia. Ponieważc
zawsze rośnie, jest to zawsze prawda, więc zapętlamy na zawsze.Po wysunięciu górna część stosu oznacza
g [ c | c
, że ostatnia została zaktualizowanac
, znak tablicy znajduje się w tym samym miejscu ig
nadal jest tam, gdzie się tego spodziewamy.Są to zawiłe operacje GolfScript. Mam nadzieję, że podobało Ci się śledzenie!
źródło
Ruby, 110
Tylko dla Ruby 2.0 ze względu na
lazy
metodę:Wynik:
źródło
Perl, 105 bajtów
Nie golfowany:
Algorytm jest prosty,
$p
pamięta poprzednią liczbę pierwszą. Następnie$i
przechodzi z3
góry do, gdy typ $ i „zawodzi na mnie” lub staje się ujemny z powodu przepełnienia.$i
jest testowany w przybliżeniu, sprawdzając wszystkie dzielniki od 2 do$i-1
. Linia jest drukowana, jeśli aktualna różnica jest większa niż poprzednia wydrukowana różnica$d
.Przy większej liczbie bajtów czas działania można poprawić:
The Wynik zaczyna się od:
źródło
Pyton,
9391 znakówNaiwne sprawdzanie liczby pierwszej (sprawdź, czy można podzielić przez coś od 2 do
n
(mniej znaków niż don/2
)):Drugi poziom wcięcia to jeden znak tabulacji.
Wynik:
źródło
n
tylko do czeków don-1
Bash i trochę Perla dla pierwotnego wyrażenia regularnego (
167 157 143112 bajtów)niektóre dane wyjściowe:
źródło
test
dużo protestuje i to nie działa dla mnie. Można również korzystać z niektórychlet n++
ilet f=c-p
i zastąpićtest
z[
. Lub ewentualnie przetestuj,(())
gdzie nie potrzebujesz$
ani spacji.test -n $d
zwrócił true dla pustego ciągu.test -n "$d"
było w porządku, ale dłużej. Jednak strona man mówi, że -n jest opcjonalne i okazuje się, żetest $d
było w porządku. I dlatego[ $d ]
też. I trzeba było zainicjować g = 0.Perl
9590 bajtówstara wersja bez golfa:
Jest to podobne do mojego innego zdania, sans bash.
źródło
for($n=$c=2;$p=$c;$c-$p>$g&&printf"$p $c %d\n",$g=$c-$p){$c=$n if(1x++$n)!~/^(11+?)\1+$/}
C (100)
Mój własny wkład, brak specjalnego algorytmu, po prostu golf:
źródło
r
ip
będziesz mieć mniej znaków i zdobędziesz bonus :)Haskell, 134 ° C
Gra w golfa:
Nie golfowany:
źródło
C:
493302272246Użyłem rekurencji, a nie zwykłej pętli
for
lubwhile
.Wynik:
źródło
leaking
na górze, ponieważ nie testujesz isPrime (n2), dopuszczasz liczby pierwsze od n1 do n2. I tak naprawdę nie można tego naprawić, ponieważ nie można zwiększyć n2 bez spełnienia liczb pierwszych.return
w głównej. Pomiń ostatnielse
. Wymienić&&
->&
inum%i==0
znum%i<1
. A według starożytnych standardów c (pojawią się ostrzeżenia) nie trzeba określać zwracanych wartości funkcji void i int (ich argumenty również domyślnie int).int
) i znacznie zredukowaną funkcją testowania:e(j,i){while(j%++i);return i==j;}f(a,b,c){int A=e(a,1),B=e(b,1);if(A&B&&c<b-a)printf("%d %d %d\n",a,b,c=b-a);f(a+(B|!A),b+(A|!B),c);}main(){f(2,3,0);}
Oracle SQL,
216202196172 + 10 = 182Właśnie zauważyłem to w pytaniu:
Ponieważ jest to SQL, a słowa kluczowe są tak długie, właściwie lepiej wziąć karę, podając następujące. To ten sam pomysł, co oryginał.
co upiększa:
Stara odpowiedź (196)
oraz w czytelnym formacie:
To tworzy generator liczb w
c
, najbardziej wewnętrzny podselekcja tworzy liczby pierwsze za pomocą sita Eratostenesa, zewnętrzny sprawdza poprzednią liczbę pierwszą, a na koniec ostatni wybór odejmuje jeden od drugiego.To nic nie zwróci, ponieważ wykonuje 1 x 10 124 zapytań rekurencyjnych ... Więc jeśli chcesz, aby działał, obniż tę liczbę do rozsądnego poziomu.
źródło
D - 153 + 10 = 163
Chętnie biorę tutaj karę +10, ponieważ liczba znaków jest nadal niższa niż byłaby, gdybym również wydrukował liczby pierwsze.
Gra w golfa :
Wersja do odczytu :
źródło
JAVASCRIPT 174 char
krótka wersja:
źródło
JavaScript 138
Skopiuj ten kod do konsoli przeglądarki. Tak będzie na zawsze, ponieważ maksymalna liczba jest czymś w pobliżu
1.79*10^308
.Nie golfowany:
źródło
C #
162161 znaków151 znaków + 10 znaków kary = 161 znaków
Krótka wersja:
Długa wersja:
W rzeczywistości lepiej było wziąć 10 znaków kary, ponieważ jest krótszy
g
(11 znaków z karą) niżp+" "+i+" "+g
(13 znaków bez kary).źródło
Ruby
90868483 znakówNiektóre zwarcia logiczne, nadużycie oceny ekspresji itp.
źródło
C 248
Kod porównuje kolejne liczby pierwsze a, b, a następnie sprawdza, czy luki są większe niż g, a następnie znajduje następną parę liczb pierwszych.
źródło
Haskell,
154 144 137123p
Liczby pierwsze są generowane za pomocą sita erasthotenów#
, a następnie filtrowane i drukowane za pomocą%
.Wygląda jak
co mam nadzieję jest w porządku.
źródło
Game Maker Language, 85
Zakładając, że wszystkie niezainicjowane zmienne
0
to (jest to domyślne ustawienie w niektórych wersjach Game Maker).źródło
Game Maker Language, 74 + 55 = 129
Zakładając, że wszystkie niezainicjowane zmienne
0
to (jest to domyślne ustawienie w niektórych wersjach Game Maker).Skrypt
p
znajduje się poniżej:źródło
Perl, 87 bajtów ( przy użyciu modułu )
Napisałem moduł, ale musielibyśmy dodać dodatkowe 565,000 znaków do licznika. Przeważnie publikowanie dla zabawy, ale także w celu zapewnienia alternatywnej wydajności, ponieważ do tej pory nie widzę żadnych programów wbudowanych. 4,6s dla przerw do 1e9, 36s dla przerw do 1e10, 6,5 min dla 1e11.
Pari / GP 2.8 można wykonać w zasadzie w ten sam sposób, aczkolwiek ponad dwukrotnie wolniej:
źródło
Perl 153
Krótki kod:
łatwy do odczytania:
źródło