Mówi się, że funkcja ma cykl długości n, jeśli istnieje w jej domenie x taki, że f n (x) = x i f m (x) ≠ x dla 0 <m <n , gdzie indeks górny n oznacza n - złóż aplikację f . Zauważ, że cykl o długości 1 jest stałym punktem f (x) = x .
Twoim zadaniem jest zaimplementowanie funkcji bijectywnej od liczb całkowitych do siebie, która ma dokładnie jeden cykl o każdej długości dodatniej n . Funkcja bijectywna to korespondencja jeden do jednego, tzn. Każda liczba całkowita odwzorowana na dokładnie jeden raz. Posiadanie dokładnie jednego cyklu długości n oznacza, że istnieją dokładnie n różnych liczb x, dla których f n (x) = x i f m (x) ≠ x dla 0 <m <n .
Oto przykład, jak mogłaby wyglądać taka funkcja około x = 0 :
x ... -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 ...
f(x) ... 2 4 6 -3 -1 1 -4 0 -2 5 7 -7 -6 3 -5 ...
Ten fragment zawiera cykle o długości od 1 do 5 :
n cycle
1 0
2 -2 1
3 -4 -3 -1
4 -5 6 3 7
5 -7 2 5 -6 4
...
Zauważ, że powyżej używam „funkcji” tylko w sensie matematycznym. Możesz napisać funkcję lub pełny program w wybranym przez siebie języku, pod warunkiem, że pobiera on jedną (całkowitą) liczbę całkowitą jako wejście i zwraca jedną (całkowitą) liczbę całkowitą. Jak zwykle możesz przyjmować dane wejściowe za pośrednictwem STDIN, argument wiersza poleceń, argument funkcji itp. I dane wyjściowe za pomocą STDOUT, wartości zwracanej funkcji lub argumentu funkcji (wyjściowej) itp.
Oczywiście wiele języków nie obsługuje (łatwo) liczb całkowitych o dowolnej precyzji. W porządku, jeśli twoja implementacja działa tylko w zakresie rodzimego typu liczb całkowitych twojego języka, o ile obejmuje on co najmniej zakres [-127, 127] i działałby dla dowolnych liczb całkowitych, gdyby typ liczb całkowitych języka został zastąpiony przez dowolne- precyzyjne liczby całkowite.
Obowiązują standardowe zasady gry w golfa .
źródło
Odpowiedzi:
Pyth,
2718 bajtówObjaśnienie (Pyth inicjuje
Q
się na wejściową liczbę całkowitą):To ma cykle
(−1)
(0, −2)
(1, −3, −4)
(2, −5, −7, −6)
(3, −9, −13, −11, −8)
(4, - 17, -25, -21, -15, -10)
(5, -33, -49, -41, -29, -19, -12)
(6, -65, -97, -81, -57, -37, -23, -14)
(7, -129, -193, -161, -113, -73, -45, -27, -16)
(8, -257, -385, -321, -225 , −145, −89, −53, −31, −18)
(9, −513, −769, −641, −449, −289, −177, −105, −61, −35, −20)
⋮
Cykl długości n jest określony przez
( n - 2,
−2 ^ ( n - 2) ⋅1 - 1,
−2 ^ ( n - 3) ⋅3 - 1, 22
^ ( n - 4) ⋅5 - 1,
…,
−2 ^ 2 ⋅ (2 · n - 7) - 1,
-2 ^ 1⋅ (2 · n - 5) - 1,
-2 ^ 0⋅ (2 · n - 3) - 1).
Każda liczba całkowita k ≥ -1 pojawia się jako pierwszy element cyklu ( k + 2). Dla każdej liczby całkowitej k <−1 możemy jednoznacznie zapisać 1 - k = 2 ^ i ⋅ (2⋅ j + 1) dla niektórych i , j ≥ 0; wtedy k pojawia się jako ( j + 2) element elementu ( i + j + 2) -cykl.
źródło
MATL , 47 bajtów
Wypróbuj online!
Ogólne wyjaśnienie
Funkcja 2 poniżej jest taka sama, jak użyta w odpowiedzi @ Sp3000 na powiązane wyzwanie. Dzięki @ Agawa001 za zauważenie.
Funkcja składa się z trzech:
Funkcje 1 i 3 są używane, ponieważ jest to łatwiejsze (chyba) w celu uzyskania pożądanego zachowania w N , niż w Z. .
Funkcja 2 wygląda następująco: górna linia to domena, dolna linia to domena kodowa. Przecinki są używane dla przejrzystości:
Pierwszy blok (od górnej
1
do dolnej1
) to cykl o długości 1. Drugi (od2 3
do3 2
) to cykl o długości 2 itd. W każdym bloku dolna część (obraz funkcji) jest górnie przesunięta kołowo jeden krok w prawo.Funkcja 1 wygląda następująco:
Funkcja 3 jest taka sama jak 1 z zamienionymi dwoma liniami.
Przykłady
Obraz
3
jest-5
. Pierwszy3
jest mapowany7
przez funkcję 1; następnie7
jest mapowany10
przez funkcję 2; następnie10
jest mapowany na -5` przez funkcję 3.Cykl długości 1 wynosi
0
. Cykl długości 2 wynosi-1 1
. Cykl długości 3 wynosi-3 2 -2
itp.Kod wyjaśniony
Funkcje 1 i 3 są proste.
Funkcja 2 polega na znalezieniu dolnego punktu końcowego odpowiedniego bloku wejściowego. Na przykład, jeśli dane wejściowe do tej funkcji
9
znajdują się7
(patrz bloki powyżej). Następnie wybiera górny punkt końcowy, który znajduje się10
w przykładzie. Okrągłe przesunięcie bloku uzyskuje się dzięki modułowej indeksacji MATL 1.źródło
Python 2, 55 bajtów
59 bajtów:
Tworzy cykle
Zmodyfikowano z mojego rozwiązania z wcześniejszego wyzwania , które jest zmodyfikowane z konstrukcji Sp3000 .
Funkcja
tworzy cykle nieparzystych liczb nieujemnych
Aby znaleźć prawidłowy rozmiar cyklu
k
,n
przesuń wejście w dół o,k=1,3,5,7,...
aż wynik znajdzie się w przedziale[0,k)
. Cykl ten należyn->(n+1)%k
wykonać z operacją , a następnie cofnąć wszystkie odejmowania wykonane na danych wejściowych. Jest to realizowane rekurencyjnie przezk+g(n-k,k+2)
.Teraz potrzebujemy ujemnego, aby wykonać parzyste cykle. Zauważ, że jeśli będziemy modyfikować
g
zacząćk=2
INg
, chcielibyśmy dostać nawet cykle-sizeTe biject do negatywów poprzez bit-dopełniacz
~
. Kiedy więcn
jest negatywna, po prostu oceniamyg(n)
jako~g(~n,2)
.źródło
k
wydaje się , że jest to inny sposób obliczaniaMath.floor(Math.sqrt(n))*2+1
.Python 3, 110 bajtów
Nadal nie wymyśliłem, jak uzyskać tam lambdę
jeśli n jest liczbą trójkątów [1,3,6,10,15,21,28 itd.], to f (n) jest porządkiem na liście pomnożonym przez jeden ujemny. jeśli liczba jest ujemna, daj jej 1 + kolejny najmniejszy numer trójkąta. w przeciwnym razie przyrost.
Przykład: 5 nie jest liczbą trójkątów, więc dodaj 1.
Następna iteracja, mamy 6. 6 jest liczbą trójkątów, i jest 3 na liście, więc wychodzi -3.
Program podaje te listy
długość 1: [0]
długość 2: [1, -1]
długość 3: [2,3, -2]
długość 4: [4,5,6, -3]
długość 5: [7,8,9,10, -4]
Edycja: Jeszcze raz dziękuję @TuukkaX za usunięcie nadmiaru znaków.
źródło
0.5
na.5
iinput('')
nainput()
.Python 3, 146 bajtów
Dla każdej liczby większej niż 0 istnieją parzyste pętle (len 2,4,6,8 ...), a mniej niż 0, nieparzyste pętle (1,3,5,7). 0 odwzorowuje na 0.
(-3, -2, -1), (0), (1,2), (3,4,5,6)
mapy do
(-2, -1, -3), (0), (2,1), (6,3,4,5)
Edycja: @TuukkaX zdjął 8 bajtów z poprzedniego rozwiązania. I kolejne 3.
źródło
mi
można go zmienić na coś mniejszego, na przykładb
.f=lambda x:1+2*int(abs(x)**0.5)if x<1 else 2*int(x**0.5+0.5) x=int(input()) n=f(x) if x>0:b=n*(n-2)/4 else:b=-((n+1)/2)**2 print(b+1+(x-b-2)%n)
input('')
nainput()
. Cytaty są bezużyteczne, ponieważ nie musimy drukować niczego na konsoli, gdy chcemy tylko uzyskać dane wejściowe.f=lambda x:1+2*int(abs(x)**.5)if x<1 else 2*int(x**.5+.5) x=int(input());n=f(x) if x>0:b=n*(n-2)/4 else:b=-((n+1)/2)**2 print(b+1+(x-b-2)%n)
Matlab (423)
Niekonkurencyjny, ponieważ bije dobry rekord bycia kondominium do ostatniego rankingu, podczas gdy staram się skrócić go tak bardzo, jak to możliwe.
Kilka bezsensownych błędów dotyczących dokładności w matlabie, których nie mogłem znaleźć, poza tym, że mój kod jest saratystycznie duży, z drugiej strony mapowanie, które wybrałem, dotyczyło głównych elementów i logarytmu n-ary.
Wykonanie
Wyjaśnienie
Knonwing, po pierwsze, że dowolna liczba może być zapisana jako iloczyn wykładników liczb pierwszych
N=e1^x1*e2^x2...
z tej bazy, postanowiłem zmapować obrazy cykli,C
które są wydobywane z największego wykładnika najmniejszego czynnika (niekoniecznie liczby pierwszej), że N jest doskonałą potęgą .prościej, niech
N=P^x
gdzie P jest najmniejszym idealnym pierwiastkiem,x
oznacza dokładnie dwa podstawowe terminy dla cyklu:x=Ʃ(r*P^i)
terminP
jest podstawą cyklu, a także doskonałym pierwiastkiem dla liczby głównej N, ik
jest stopniem cykluC=p^k
, gdziei
zmienia się między 1 i k, współczynnikr
jest zwiększany o 1 i ograniczony przez P-1 dla dowolnego następnego obrazu wstępnego, dopóki wszystkie współczynniki nie zostaną ustawione na r = 1, więc przechodzimy do początku tego cyklu.Aby uniknąć kolizji między cyklami, wybór potęgowania liczb pierwszych zamiast ich iloczynu jest dokładny, ponieważ jako przykład dwóch cykli zasad
3
i2
miejsca spotkania między nimi można3*2
uniknąć, dlatego unika się tego, ponieważ cykl jest definiowany na podstawie stopnia większego niż jego podstawa, a dla punktu spotkania jest kolejny cykl podstawy6
i stopień 1.Liczby ujemne stanowią wyjątek, ponieważ zarezerwowałem nieparzyste stopnie dla liczb ujemnych, a nawet stopnie dla pozostałych. Jak to ?
dla dowolnej liczby N osadzonej w cyklu
P^k
zapisuje się jakoP^(a0*P^i0+a1*P^i1+...)
, że ilość(a0*P^i0+a1*P^i1+...)
jest przekształcana w zasadę P-ary jakoa0,a1,....
, aby wyjaśnić ten punkt, jeśli (p = 2) sekwencja musi być w bazie binarnej. Jak wiadomo przede wszystkim bez ustawiania warunku stopni dodatnich / ujemnych i wyjątku (+/- 1), liczba N znajduje się na krawędziach stopniak
, tylko wtedy, gdy sekwencjaA
jest zapisana jako1111..{k+1}..10
lub111..{k}..1
dla wszystkich zasad, w przeciwnym razie obrót nie jest potrzebny, więc przypisanie warunku ujemnego / dodatniego dla odpowiednich stopni nieparzystych / parzystychk/k'
dla obu tworzy nieparzystą sekwencję zapisaną w formularzu101..{k}..100
, parzysta sekwencja jest zapisana w formularzu101..{k'}..10
dla początkowej krawędzi odpowiednio ujemnego / dodatniego cyklu liczbowego .Przykład:
Biorąc liczbę
N=2^10
,x=10=2^1+2^3
sekwencja A jest zapisywanaA=1010
, ten typ sekwencji objawia skończoną krawędź dodatniego cyklu liczbowego, co oznaczaC=2^3
, że następny obraz to krawędź początkowa,A=011
która jest8
, Ale poprzez standaryzację tego wyniku na (+ / -) 1 wyjątek2^10/2
odwzorowuje na8/2
i poprzedni obraz nie może być obracany.Biorąc liczbę
N=-3^9
,x=9=3^2
sekwencja A jest zapisywanaA=100
, ten typ sekwencji symbolizuje skończoną krawędź ujemnego cyklu liczbowego, co jestC=3^1
, więc następnym obrazem jest krawędź początkowa,A=01
która jest3
, Ale poprzez dostosowanie tego wyniku do ujemnej / dodatniej-3^9
mapy warunków do-3
.dla pary
(-/+)1
przewidywałem , że będę wtrącał się do niej w ramach liczby zasad cyklu2
, pod przykrywką, że zwykła sekwencja grup cyklicznych{2,4}{8,16,32,64}..
składa się w innej formie{1,2}{4,8,16,32}..
, co zapobiega utracie poprzednich elementów, a wykonana operacja zmienia się z trzaskiem nowy element w.Wyniki:
uruchomienie tego małego arkusza kodu w celu zweryfikowania pierwszych rozsądnych zakresów liczb cyklicznych:
To prowadzi do tych wyników
Ostatni to błąd segmentacji, ale pasuje do [-127,127] standardowego zakresu liczb całkowitych ze znakiem.
źródło
JavaScript (ES6), 73 bajty
Działa poprzez wyliczenie sekwencji (0, -1, 1, -2, 2, -3, 3, ...), aż znajdzie
n
, zliczając cykle w miarę upływu czasu.i
zawiera bieżący wpis;j
zawiera początek bieżącego cyklu,k
indeks w cyklu,l
długość bieżącego cyklu im
następny wpis w sekwencji. Gdy się dowiemyn
, bierzemy,j
czy jesteśmy pod koniec cyklu,m
czy nie.źródło