Oto hipoteza Collatza (OEIS A006577 ):
- Zacznij od liczby całkowitej n > 1.
- Powtórz następujące kroki:
- Jeśli n jest parzyste, podziel je przez 2.
- Jeśli n jest nieparzyste, pomnóż go przez 3 i dodaj 1.
Udowodniono, że dla wszystkich liczb całkowitych dodatnich do 5 * 2 60 lub około 5764000000000000000 , n ostatecznie stanie się 1 .
Twoim zadaniem jest dowiedzieć się, ile iteracji potrzeba (o połowę lub trzykrotnie plus jeden), aby osiągnąć 1 .
Zasady:
- Najkrótszy kod wygrywa.
- Jeśli wprowadzona zostanie liczba <2, liczba całkowita nie będąca liczbą całkowitą lub liczba nieparzysta, wynik nie ma znaczenia.
Przypadki testowe
2 -> 1
16 -> 4
5 -> 5
7 -> 16
1+
jest specjalnie zaprojektowany jako)
.C -
5047 znakówZłe małe C wymaga niestety okropnej ilości kodu dla podstawowych operacji wejścia / wyjścia, więc zwarcie tego wszystkiego sprawiło, że interfejs użytkownika jest nieco nieintuicyjny.
Skompiluj to na przykład
gcc -o 1 collatz.c
. Dane wejściowe są jednoznaczne z cyframi oddzielonymi spacją, a odpowiedź znajdziesz w kodzie wyjścia. Przykład z liczbą 17:źródło
return~-a?
zapisuje 1. Również przejścieb++
do?
skrzynki powinno oszczędzaćb--
.Perl 34 (+1) znaków
Nadużywanie
$\
końcowego wyniku, jak zwykle. Uruchom z-p
opcją wiersza poleceń, dane wejściowe są pobierane zstdin
.Zapisano jeden bajt dzięki Eliasowi Van Ootegem . W szczególności obserwacja, że następujące dwa są równoważne:
Chociaż jeden bajt dłużej, oszczędza dwa bajty, skracając
$_/2
do just.5
.Przykładowe użycie:
PHP 54 bajty
Wygląda na to, że JavaScript w konkursie na drewnianą łyżkę był nieco za krótki w tym wyzwaniu. Jednak z tym problemem nie ma wiele miejsca na kreatywność. Dane wejściowe są traktowane jako argument wiersza poleceń.
Przykładowe użycie:
źródło
$_
w trójskładnikowego wydaje się marnotrawstwem, można zgolić inną postać za pomocą*=
tak:$\++,$_*=$_&1?3+1/$_:.5while$_>1}{
. Mnożenie przez1/$_
ma taki sam efekt jak+1
, więc$_*=3+1/$_
działa dobrze$_*=3+1/$_
jest genialny, dzięki!Matematyka (35)
Stosowanie:
źródło
Jak zwykle, zacznę od własnych odpowiedzi.
JavaScript,
4644 znaków (uruchamiane na konsoli)źródło
Java,
165, 156, 154, 134, 131,129,128, 126 (pełne języki też potrzebują trochę miłości)Wszystko odbywa się wewnątrz for
To cholernie piękny mężczyzna. Dzięki Pater Taylor !!!, a pomysł użycia pętli for został skradziony z ugoren
W skrócie zastąpiłem Integer.
źródło
i(,++y)
. Możesz zaoszczędzić jeszcze dwa, używając<
zamiast==
.class a{public static void main(String[]a){for(int x=new Short(a[0]),y=0;x>1;System.out.println(++y))x=x%2<1?x/2:x*3+1;}}
Zmiany dokonane: 1) ZastępujeShort.valueOf(...)
sięnew Short(...)
do -4 bajtów i 2) Mam umieścićx=x%2<1?x/2:x*3+1;
w korpusiefor
-loop aby pozbyć się przecinek za -1 bajt .Rebmu : 28
W przypadku tego krótkiego i mathiego problemu GolfScript prawdopodobnie wygra o pewien procent w stosunku do Rebmu (jeśli nie jest wymagane, aby czytać pliki z Internetu lub generować pliki JPG). Jednak wydaje mi się, że większość zgodziłaby się z logiką Golfscript, która nie jest tak łatwa do naśladowania, a całkowity stos wykonywalny, który ją uruchamia, jest większy.
Chociaż twórca Rebola, Carl Sassenrath, powiedział mi, że uznał Rebmu za „nieczytelnego”, jest zajęty i nie ma czasu, aby naprawdę ćwiczyć transformację typu świnia- latynos poprzez rozproszenie . To naprawdę przekształca się w:
Zauważ, że miejsce było wymagane, aby uzyskać a: zamiast a . To jest „słowo-zestaw!” a oceniający zauważa ten typ symbolu, aby uruchomić przypisanie.
Gdyby zostało napisane w skrócie (ale niezręcznie napisany Rebol), dostałbyś:
Rebol, podobnie jak Ruby, ocenia bloki do ich ostatniej wartości. Pętla UNTIL jest ciekawą formą pętli, która nie przyjmuje warunku pętli, po prostu przestaje zapętlać, gdy jej blok ocenia się na wartość NIE FAŁSZ lub BRAK. Tak więc w miejscu,
1 ==
w którym wynik przypisania A (argumentu rebmu) do wyniku warunku Collatz (albo jest IF-ELSE, który ocenia wybraną gałąź) ... pętla pęka.J i K są inicjalizowane na wartość całkowitą zero w Rebmu. I jak już wspomniano, całość ocenia się na ostatnią wartość. Tak więc odniesienie J na końcu programu oznacza liczbę iteracji.
Stosowanie:
źródło
Repl. Python, 48
Nie jestem przekonany, że nie ma krótszego wyrażenia niż
n=3*n+1;n/=1+n%2*5;
. Prawdopodobnie znalazłem kilkanaście różnych wyrażeń o tej samej długości ...edytuj: Znalazłem inne rozwiązanie, które nigdy nie będzie rywalizować, ale zbyt zabawne jest, aby się nim nie dzielić.
źródło
(n//2,n*3+1)[n%2]
jest krótszy.n/2
działałoby tak dobrze, jak wiemy, że jest w ogóle?APL (31)
źródło
{1=⍵:0⋄2|⍵:1+∇1+3×⍵⋄1+∇⍵÷2}
{1=⍵:0⋄1+∇⊃⍵⌽0 1+.5 3×⍵}
J, 30 znaków
Okazało się nieco dłużej niż pożądane
stosowanie:
-:`(1+3&*)`]
to gerunda złożona z trzech czasowników, używanych trzykrotnie.-:
oznacza „zmniejsz o połowę”(1+3&*)
lub(1+3*])
koduje krok pomnożenia i]
(tożsamość) pomaga w zakończeniu.2&|+1&=
tworzy indeks do gerunda. dosłownie „reszta po podzieleniu przez dwa plus czy równa się jeden”.#verb^:a:
iteruje funkcję, aż wynik będzie stabilny (tutaj, wymuszony jawnie), podczas zbierania kroków, a następnie je zlicza. Skradzione z @JB .<:
zmniejsza liczbę kroków o jeden, aby dostosować się do wymagań dotyczących pytania.źródło
<:
,#-:
,:`(
,&*)
,=)
,)^:
.<:
oznacza „zmniejszenie” lub „mniejszy lub równy”,#
oznacza „liczbę” lub „n razy”,-:
oznacza „połowę” lub „epsilon-równość”,:`(
oznacza z kolei koniec wspomnianej „połowy”, związek między dwa czasowniki w gerund i lewy nawias (używane do grupowania).&*)
oznacza „coś związane z mnożeniem” (3 połączone z mnożeniem tworzy operator „razy trzy”) i koniec grupowania.=
przeprowadza kontrolę równości lub, w jednoznacznym sensie, samoklasyfikację.^:
to koniunkcja mocy (iteracja czasownika). Ponieważ wiele czasowników J kończy się dwukropkiem, ... :-)<:#a:2&(<*|+|6&*%~)
19 bajtów (-11)Schemat Gambit,
10698 znaków, 40 nawiasów(let((f(lambda(x)(cond((= x 1) 0)((odd? x)(+ 1(f(+ 1(* 3 x)))))(else(+ 1(f(/ x 2))))))))(f(read)))
9189 znaków z definiować bezpośrednio(define(f x)(cond((= x 1)0)((odd? x)(+ 1(f(+ 1(* 3 x)))))(else(+ 1(f(/ x 2))))))(f(read))
źródło
PowerShell:
7774717061Kod do gry w golfa:
Uwagi:
Początkowo próbowałem pobrać dane wejściowe od użytkownika, nie zmuszając go do uzyskania liczby całkowitej, ale zepsuło to w ciekawy sposób. Wszelkie nieparzyste dane wejściowe byłyby przetwarzane niedokładnie, ale nawet dane wejściowe działałyby poprawnie. Zrozumienie, co się dzieje, zajęło mi minutę.
Podczas mnożenia lub dodawania program PowerShell najpierw traktuje wpisane dane jako ciąg. Tak więc
'5'*3+1
staje się „5551” zamiast 16. Parzyste dane wejściowe zachowywały się dobrze, ponieważ PowerShell nie ma domyślnej akcji dzielącej ciągi znaków. Nawet parzyste dane wejściowe, które przechodziłyby przez liczby nieparzyste, działały dobrze, ponieważ zanim PowerShell osiągnął liczbę nieparzystą w pętli, zmienna była już i tak zmuszona do operacji na liczbach całkowitych.PowerShell Golfer's Tip: W niektórych scenariuszach, takich jak ten,
switch
bijeif/else
. Tutaj różnica wynosiła 2 znaki.Nie ma sprawdzania błędów dla wartości niecałkowitych lub liczb całkowitych mniejszych niż dwa.
Jeśli chcesz skontrolować skrypt, umieść go
;$i
tuż przed ostatnim nawiasem klamrowym w skrypcie.Nie jestem pewien, jak dobrze PowerShell obsługuje liczby, które przechodzą w bardzo duże wartości, ale spodziewam się, że w pewnym momencie utraci się dokładność. Niestety, spodziewam się również, że niewiele można z tym zrobić bez poważnego rozdęcia scenariusza.
Nieskluczony kod z komentarzami:
Przypadki testowe:
Poniżej kilka przykładów z włączoną kontrolą. Zredagowałem również dane wyjściowe dla większej przejrzystości, dodając etykiety do danych wejściowych i końcowych oraz wstawiając odstępy, aby rozdzielić wartości Collatz.
Interesujące bity na temat liczb wejściowych, które nie pochodzą z przypadków testowych pytania:
14
i197
są liczbami Keitha31
jest Mersenne Prime6174
jest stała Kaprekara8008135
. I oczywiście Numberphile .źródło
switch
z$i=(($i/2),($i*3+1))[$i%2]
read-host
na liczbę - wystarczy zmienić$i*3
na3*$i
.$i*3
- dlaczego już o tym nie pomyślałem?param($i)for(;$i-ne1;$x++){$i=(($i/2),(3*$i+1))[$i%2]}$x
- zamień read-host na parametr, aby uzyskać 56 bajtów . Wypróbuj Online link80386, 16 bajtów
W tym przykładzie użyto składni AT&T i konwencji wywoływania fastcall, argument dotyczy
ecx
:Oto wynikowe 16 bajtów kodu maszynowego:
źródło
Brachylog , 16 bajtów
Wypróbuj online!
Wyjaśnienie
Alternatywne rozwiązanie przy tej samej liczbie bajtów:
Wypróbuj online!
źródło
GolfScript (23 znaki)
Test online
źródło
F # - 65 znaków
źródło
Python
68585452 znakówf=lambda n:1+(n-2and f((n/2,3*n+1)[n%2]));f(input())
Dzięki Bakuriu i stoisku za wskazówki :)
źródło
n%2and 3*n+1or n/2
aby zapisać 5 znaków. Również w python2 możesz usunąć wywołanieint
, zmniejszając rozmiar do 58 bajtów.[n/2,3*n+1][n%2]
.unsupported operand type(s) for -: 'str' and 'int'
Siatkówka , 43 bajty
Pobiera dane wejściowe i drukuje dane wyjściowe jako jednoargumentowy.
Każda linia powinna przejść do własnego pliku. 1 bajt na dodatkowy plik dodany do liczby bajtów.
Możesz uruchomić kod jako jeden plik z
-s
flagą. Na przykład:Algorytm to pętla wykonywania kroku Collatza z jednoznaczną liczbą i dodawania nowego znacznika kroku
x
na końcu łańcucha, jeśli liczba nie jest równa 1.Kiedy pętla kończy się na
1
, konwertujemy znaczniki na liczbę pojedynczą (usuwając wiodące1
), co jest pożądanym wyjściem.źródło
Galaretka , niekonkurująca
12 bajtów Ta odpowiedź nie konkuruje, ponieważ wyzwanie poprzedza powstanie galaretki.
Wypróbuj online!
Jak to działa
źródło
dc, 27 znaków
Zastosowanie czarnej magii boothby :
Nie jestem pewien, czy rozumiem, w jaki sposób - albo że - to działa.
Stosowanie:dc, 36 znaków
Moje własne stworzenie; nieco bardziej tradycyjne podejście, chociaż musiałem dość pokłócić się z językiem, aby przezwyciężyć brak
else
częściif
wypowiedzi:Wewnętrznie generuje wszystkie liczby sekwencji i zapisuje je na stosie, a następnie wyskakuje na końcu
1
i wyświetla wysokość stosu.źródło
2<x
i się go pozbyćk
. Na wypadek, gdybyś chciał odzyskać bajt po czterech latach. : Dpieprzenie mózgu ,
5956 bajtówWypróbuj online! (Lekko zmodyfikowany dla łatwości użycia)
Wejście i wyjście jako kody znaków. Jest to bardziej przydatne w przypadku komórek o dowolnym rozmiarze, ale nadal może działać z małymi wartościami w ograniczonych rozmiarach komórek.
Jak to działa
źródło
Sześciokąt ,
4844 bajtówWypróbuj online!
Rozszerzony:
Pamiętaj, że to się nie udaje z1
... hmm ... powodów . Szczerze mówiąc, nie jestem już pewien, jak to działa. Wiem tylko, że kod dla liczb nieparzystych jest uruchamiany wstecz dla liczb parzystych? Jakoś?Nowa wersja jest znacznie czystsza od poprzedniej, ale ma kilka dodatkowych kierunków w porównaniu, a także kończy się błędem dzielenia przez zero. Jedyny przypadek, w którym nie popełni błędu, to fakt, że faktycznie obsługuje
1
poprawnie.źródło
If a number < 2 is input ... output does not matter.
: o)C,
7069 znakówCałkiem proste, żadnych sztuczek.
Odczytuje dane wejściowe ze standardowego wejścia.
źródło
Q, 46
źródło
(#)1_(1<){(1+3*x;x%2)0=x mod 2}\
Ruby 1.9, 49 znaków
Rubyfikowana odpowiedź Valentina CLEMENT na Python , przy użyciu stabilnej składni lambda. Sqeezed to w jedną instrukcję dla dodatkowej nieczytelności.
Niektóre koszty ogólne, ponieważ Ruby, w przeciwieństwie do Pythona, nie jest zadowolona z mieszania liczb z booleanami.
źródło
C ++ (
5148)Jest to funkcja rekurencyjna, która to robi; odczyt wejściowy jest dostarczany osobno.
Jestem pewien, że mogę zrobić coś w tym rodzaju „i / lub”
== 0
, ale nie mam pojęcia, jak to zrobić.źródło
==0
i zamienić boki warunkowegon==1
ponieważ w pytaniu podałem, że liczba jest zawsze większa niż 1n==1
jest to podstawowy przypadek rekurencji. Umieszczenien==2
tam nie poprawiłoby wyniku.return~-n?
i zamienić strony warunkowen==1
==n<2
.~ - ~! (Bez komentarza) -
7153Ten język oczywiście nie jest najlepszy do gry w golfa, ponieważ brakuje mu dużej liczby natywnych funkcji, ale to jest jego piękno.
Najpierw ustaw
'''
dane wejściowe. Funkcja''
może być następnie wywołana za pomocą%
jako, gdy jest wprowadzana i zwróci odpowiedź, tak jak:'''=~~~~~:''&%:
To wróci
~~~~~
. To faktycznie działa dlan==1
(zawsze zapętla sięn==0
).Jak zawsze w tym języku, niesprawdzony.
źródło
JavaScript (ES6) - 29 znaków
Tworzy funkcję,
f
która akceptuje pojedynczy argument i zwraca liczbę iteracji.JavaScript - 31 znaków
Zakłada, że dane wejściowe znajdują się w zmiennej
n
i tworzy zmienną,c
która zawiera liczbę iteracji (i będzie również wysyłanac
do konsoli jako jej ostatnie polecenie).źródło
Perl 6, 40 bajtów
Metoda funkcji rekurencyjnej, zgodnie z Valentin CLEMENT i daniero : 40 znaków
Metoda listy leniwej: 32 znaki
źródło
> <>,
27 2623 bajtówPodobnie jak inne odpowiedzi> <>, buduje to sekwencję na stosie. Gdy sekwencja osiągnie 2, rozmiar stosu jest liczbą wykonanych kroków.
Dzięki @Hohmannfan zaoszczędzono 3 bajty dzięki bardzo sprytnej metodzie bezpośredniego obliczenia następnej wartości. Wzór zastosowany do obliczenia następnej wartości w sekwencji to:
Ułamek odwzorowuje liczby parzyste na 0,5, a nieparzyste na 3. Mnożenie przez
n
i dodawanien%2
kończy obliczenia - nie trzeba wcale wybierać następnej wartości!Edycja 2: Oto wersja przed @ Hohmannfan:
Sztuką jest to, że oba
3n+1
in/2
są obliczane na każdym kroku w sekwencji, a ten należy spadł z sekwencja jest wybrana później. Oznacza to, że kod nie musi rozgałęziać się, dopóki nie zostanie osiągnięty 1, a obliczenie sekwencji może istnieć w jednym wierszu kodu.Edycja: Zignorowałem inną postać po uświadomieniu sobie, że jedyną dodatnią liczbą całkowitą, która może prowadzić do 1, jest 2. Ponieważ wyjście programu nie ma znaczenia dla danych wejściowych <2, generowanie sekwencji może zakończyć się po osiągnięciu 2, pozostawiając rozmiar stosu będąca dokładną liczbą wymaganych kroków.
Wersja poprzednia:
źródło
\::2%:@5*1+2,*+:2=?