Po to, aby uprzedzić niektóre komentarze „Nie chcemy konkretnych wyzwań językowych”, proszenie o pomoc w odszukaniu kodu jest tematem i inną historią niż wyzwania.
Martin Ender,
4
Czy musimy zachować algorytm, czy tylko wynik końcowy?
John Dvorak,
Chciałbym zacząć od 2, żeby być ściśle dokładne, ponieważ drukuje 0 i 1.
histokrata
próbujesz przyspieszyć wykonanie kodu, czy próbujesz użyć mniejszej liczby znaków w kodzie źródłowym?
user3629249,
1
Ponieważ prosisz o pomoc w golfie, pomocne byłoby umieszczenie liczby postów w twoim aktualnym rozwiązaniu (postaram się, aby było to 89).
Mark Reed,
Odpowiedzi:
7
59 57 bajtów
Oparty na rozwiązaniu @feersum, ale kontrola pierwszeństwa może być dalej rozgrywana w golfa
(Napisałem to, nie zdając sobie sprawy z ograniczeń wielkości liczb całkowitych w C, więc prawdopodobnie nie jest to przydatne do skracania kodu).
Najpierw słowo o algorytmie. Przed golfem kodu powinieneś pomyśleć o najlepszej ogólnej strategii, aby uzyskać wynik.
Jesteś sprawdzanie pierwszości wykonując podział testową - testowanie każdego potencjalnego dzielnik pz i. Jest to kosztowne dla postaci, ponieważ wymaga dwóch pętli. Zatem testowanie pierwotności bez pętli może uratować znaki.
Często krótszym podejściem jest użycie twierdzenia Wilsona : liczba njest liczbą pierwszą wtedy i tylko wtedy
fact(n-1)%n == n-1
gdzie factjest funkcja silnia. Ponieważ testujesz wszystkie możliwe nod 1do 1000, łatwo jest uniknąć implementacji silni, śledząc działający produkt Pi aktualizując go P*=npo każdej pętli. Oto implementacja tej strategii Pythona do drukowania liczb pierwszych do miliona.
Alternatywnie, fakt, że twój program musi mieć dokładnie 1000, otwiera inną strategię: test pierwszeństwa Fermata . Dla niektórych akażda liczba pierwsza nspełnia
pow(a,n-1)%n == 1
Niestety niektóre kompozyty nrównież zdają ten test a. Są to tak zwane pseudopierwsze Fermata . Ale a=2i a=3nie zawiedźcie razem, dopóki n=1105więc nie wystarczą do sprawdzenia liczb pierwszych do 1000. (Gdyby 1000 było 100, można by użyć tylko a=2.) Tak więc sprawdzamy pierwotność za pomocą (kodu nie golfowego)
pow(2,n-1)%n == 1 and pow(3,n-1)%n == 1
To również nie rozpoznaje liczb pierwszych 2 i 3, więc te będą musiały być w specjalnej obudowie.
Czy te podejścia są krótsze? Nie wiem, bo nie koduję w C. Ale są to pomysły, które powinieneś wypróbować, zanim zdecydujesz się na kawałek kodu, aby zacząć odszukiwać znaki.
Twierdzenie Wilsona nie jest przydatne w C, ponieważ ints są 32-bitowe. To samo dotyczy Fermata.
feersum
@feersum Och, strzelaj. To także problem dla silni. Czy istnieje typ big-int?
xnor
@xnor Nie wbudowane.
Martin Ender,
1
jeśli zdefiniujemy, fact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }wynik nie przepełni 32-bitowej liczby całkowitej dla nawet dość dużych wartości n. ( mjest modułem)
apnorton
@anorton Myślę, że masz na myśli (n*fact(n-1,m)) % m. Co podkreśla problem: nie można uniknąć rekurencji w implementacji, factponieważ mbędzie różna dla każdej iteracji zewnętrznej pętli.
hvd
4
78 77 znaków
(Właśnie zastosowałem kilka sztuczek nauczonych w innych językach).
int i=0,p,c;for(;i<1e3;i++){c=0;for(p=2;p<i;)c+=i%p++<1;c||printf("%u\n",i);}
Odpowiedzi:
5957 bajtówOparty na rozwiązaniu @feersum, ale kontrola pierwszeństwa może być dalej rozgrywana w golfa
Edytowane na podstawie komentarzy Runer112
źródło
d=p++%999
. W przeciwnym razie wygląda to dość szczelnie w golfa!67 bajtów
W C nie ma realnej alternatywy dla próbnego podziału, ale z pewnością można trochę pograć w golfa.
Wymaga wstępnych deklaracji C99, co pozwala zaoszczędzić 1 bajt.
źródło
(Napisałem to, nie zdając sobie sprawy z ograniczeń wielkości liczb całkowitych w C, więc prawdopodobnie nie jest to przydatne do skracania kodu).
Najpierw słowo o algorytmie. Przed golfem kodu powinieneś pomyśleć o najlepszej ogólnej strategii, aby uzyskać wynik.
Jesteś sprawdzanie pierwszości wykonując podział testową - testowanie każdego potencjalnego dzielnik
p
zi
. Jest to kosztowne dla postaci, ponieważ wymaga dwóch pętli. Zatem testowanie pierwotności bez pętli może uratować znaki.Często krótszym podejściem jest użycie twierdzenia Wilsona : liczba
n
jest liczbą pierwszą wtedy i tylko wtedygdzie
fact
jest funkcja silnia. Ponieważ testujesz wszystkie możliwen
od1
do1000
, łatwo jest uniknąć implementacji silni, śledząc działający produktP
i aktualizując goP*=n
po każdej pętli. Oto implementacja tej strategii Pythona do drukowania liczb pierwszych do miliona.Alternatywnie, fakt, że twój program musi mieć dokładnie 1000, otwiera inną strategię: test pierwszeństwa Fermata . Dla niektórych
a
każda liczba pierwszan
spełniaNiestety niektóre kompozyty
n
również zdają ten testa
. Są to tak zwane pseudopierwsze Fermata . Alea=2
ia=3
nie zawiedźcie razem, dopókin=1105
więc nie wystarczą do sprawdzenia liczb pierwszych do 1000. (Gdyby 1000 było 100, można by użyć tylkoa=2
.) Tak więc sprawdzamy pierwotność za pomocą (kodu nie golfowego)To również nie rozpoznaje liczb pierwszych 2 i 3, więc te będą musiały być w specjalnej obudowie.
Czy te podejścia są krótsze? Nie wiem, bo nie koduję w C. Ale są to pomysły, które powinieneś wypróbować, zanim zdecydujesz się na kawałek kodu, aby zacząć odszukiwać znaki.
źródło
int
s są 32-bitowe. To samo dotyczy Fermata.fact(int n, int m) { return (n==0) ? 1 : (n*f(n-1)) % m; }
wynik nie przepełni 32-bitowej liczby całkowitej dla nawet dość dużych wartościn
. (m
jest modułem)(n*fact(n-1,m)) % m
. Co podkreśla problem: nie można uniknąć rekurencji w implementacji,fact
ponieważm
będzie różna dla każdej iteracji zewnętrznej pętli.7877 znaków(Właśnie zastosowałem kilka sztuczek nauczonych w innych językach).
76 znaków w trybie C99
źródło
58 znaków (lub 61 dla kompletnego programu)
Kolejne ponowne użycie mojej odpowiedzi na podobne pytanie .
EDYCJA : samodzielna część kodu, brak funkcji do wywołania.
Kompletny program:
źródło
6764 bajtówZainspirowany rozwiązaniem Alchymist:
źródło