Wykres operacji modulo ( ) wygląda następująco:
Jest to bardzo przydatna funkcja, ponieważ pozwala nam tworzyć zachowanie „zawijające”. Jest to jednak bardzo kłopotliwe, gdy chcę go użyć do stworzenia efektu „odbijania się” między dwiema ścianami. Wykres funkcji „odbicia” ( ) wygląda następująco:
Okres od wykresu znaczy . Okres wykresu wynosi , ponieważ przesuwa się w górę o jednostek, a następnie przesuwa się w dół o kolejne jednostek, zanim powróci do miejsca, w którym się zaczął. W przypadku obu funkcji minimalna wartość dla wynosi 0, a maksymalna to (w rzeczywistości dla funkcji modułu ze zintegrowanymi wejściami jest to ). Ponadto dla obu funkcji wartość, gdzie wynosi 0.k y = odbicie ( x , k ) 2 k k k y k k - 1 x = 0
Wyzwanie
Biorąc pod uwagę liczbę całkowitą i dodatnią liczbę całkowitą , zwróć przybliżoną liczbę całkowitą lub zmiennoprzecinkową .k y = odbicie ( x , k )
To jest golf golfowy , więc wygrywa najkrótsze prawidłowe zgłoszenie (liczone w bajtach).
Przypadki testowe
x, k -> bounce(x, k)
0, 14 -> 0
3, 7 -> 3
14, 14 -> 14
15, 14 -> 13
-13, 14 -> 13 (12.999997 etc would be an acceptable answer)
-14, 14 -> 14
191, 8 -> 1
192, 8 -> 0
źródło
k % k = 0
k
.Odpowiedzi:
Kod maszynowy x86-64, 18 bajtów
Ten kod definiuje funkcję obliczającą się w języku maszynowym x86-64
bounce(x, k
). Zgodnie z konwencją wywoływania AMD64 w Systemie V stosowaną w systemach Gnu / Unix,x
parametr jest przekazywany doEDI
rejestru, podczas gdyk
parametr jest przekazywany doESI
rejestru. Podobnie jak w przypadku wszystkich konwencji wywoływania x86, wynik jest zwracany doEAX
rejestru.Aby wywołać to z C, prototypujesz go w następujący sposób:
Wypróbuj online!
Mnemoniki do montażu bez golfa:
Zauważ, że pierwsza sekcja (która przyjmuje wartość bezwzględną) mogła zostać napisana w równoważny sposób:
która jest dokładnie taką samą liczbą bajtów (6). Wydajność powinna być podobna, być może nieco szybsza (z wyjątkiem niektórych układów Intel, w których ruchy warunkowe są powolne ).
XCHG
jest oczywiście stosunkowo wolny i nie byłby preferowany, zMOV
wyjątkiem kodowania w golfa (ten pierwszy ma 1 bajt, gdy jednym z operandów jest akumulator, podczas gdy rejestr rejestruMOV
ma zawsze 2 bajty).źródło
Galaretka , 3 bajty
Wypróbuj online!
Wbudowane ftw.
Wyjaśnienie
æ%
jest przydatnym wbudowanym tutaj. Nie wiem, jak to opisać, więc przedstawię dane wyjściowe dla niektórych danych wejściowych:Gdy
x
idzie od0
nieskończoności,xæ%4
idzie0,1,2,3,4,(-3,-2,-1,0,1,2,3,4,)
tam , gdzie część w nawiasach jest powtarzana do nieskończoności w obie strony.źródło
Python 2 ,
2927 bajtówWypróbuj online!
źródło
Python 3 , 27 bajtów
Wypróbuj online!
źródło
Rubinowy,
40 bajtów32 bajtyWypróbuj online!
Wyjaśnienie
Cześć, to moja pierwsza odpowiedź na tej stronie! Ten kod opiera się na spostrzeżeniu, że funkcja odbicia zachowuje się dokładnie tak jak modulo, gdy ( n -1) k <= x < nk i n jest nieparzysta, i zachowuje się jak odwrócona operacja modulo, gdy n jest parzyste.
(x/k+1)
jest najmniejszą liczbą całkowitą większą niż x / k (która jest x / k +1 zaokrąglona w dół do liczby całkowitej). Dlatego(x/k+1)
znajduje n wspomniane powyżej.%2>0
sprawdza, czy n jest nieparzyste, czy parzyste. Jeśli n mod 2> 0, to n jest nieparzyste. Jeśli nmod 2 = 0, a następnie n jest parzyste. Jeśli n jest nieparzyste, funkcja odbicia powinna wynosić x mod k . Jeśli n jest parzyste, funkcja odbicia powinna być odwrotna, równa k - x mod k . Całe wyrażenie(x/k+1)%2>0?x%k:k-x%k
znajduje n , a następnie wykonuje x mod k, jeśli jest nieparzyste, i wykonuje k - x mod k w przeciwnym razie.Odpowiedź została poprawiona na podstawie sugestii Cyoce .
źródło
def b(x,k) ... end
użycia->x,k{...}
.to_i
nie jest to konieczne.Mathematica, 19 bajtów
źródło
Pyth , 5 bajtów
Sprawdź wszystkie przypadki testowe.
Widelec mojej odpowiedzi w języku Python .
źródło
J, 25 bajtów
Wskazówka:
Oto (jeszcze niezbyt dobrze zagrane) rozwiązanie w J. Postaram się poprawić jutro:
sprężony:
[((|~#){])(i.@>:,}:@i.@-)@]
skompresowany2:
[((|~#){])(<:|.|@}.@i:)@]
Wypróbuj online!
źródło
i:
można go tutaj wykorzystać, ale nie próbowałem jeszcze rozwiązaniai:
. Po prostu nie miałem czasu na aktualizację głównego i wyjaśnienie. Oczekuję, że ekspert mógłby ogolić kolejne 4 lub 5 bajtów przynajmniej ...((|~#){])]-|@}:@i:
przez 18 bajtówQBIC ,
253027 bajtówCzy trochę restrukturyzacji ...
Wyjaśnienie
źródło
x
jest -13 ik
jest 14.abs
obu razy?C89, 40 bajtów
Port AC mojej odpowiedzi na kod maszynowy x86 , to definiuje funkcję
f
, która oblicza moduł bounce dla parametrówx
ik
.Korzysta z reguły C89 niejawnej, dzięki czemu oba parametry, zmienna globalna
t
i wartość zwracana przez funkcję są niejawnie typuint
. Zmienna globalnat
jest po prostu używana do przechowywania wartości tymczasowej, która kończy oszczędzanie bajtów, w porównaniu do powtarzania obliczeń po obu stronach operatora warunkowego.abs
Function (wartość bezwzględna) jest zaopatrzona w<stdlib.h>
nagłówku, ale nie muszą zawierać tutaj, znowu dzięki niejawny-int reguły C89 jest (gdy funkcja jest niejawnie zadeklarowanej i zakładanym do zwrotuint
).Wypróbuj online!
Wersja bez golfa:
Patrząc na to w świetle mojego ręcznie dostosowanego kodu maszynowego , kompilatory faktycznie generują całkiem niezłą wydajność . Mam na myśli, że powinni; jest to dość prosta funkcja do optymalizacji! Odkryłem jednak drobny błąd w optymalizatorze x86-64 GCC , gdzie ciekawie generuje większy kod, gdy każesz mu zoptymalizować rozmiar i mniejszy kod, gdy mówisz, żeby zoptymalizować szybkość .
źródło
m;f(x,k){m=abs(x%k);x=x/k%2?k-m:m;}
jest krótszyHaskell, 37 bajtów
Wypróbuj online!
Sposób użycia:
połączenia jak
15#14
za nieujemnych pozostawionych argumentów i jak(-13)#14
dla negatywu lewo argumenty, ponieważ Haskell byłoby interpretować-13#14
jako-(13#14)
jeśli używasz coś podobnegoghci
. Łącze TIO po prostu przyjmuje dwa argumenty wiersza poleceń.Objaśnienie:
Najpierw redefiniuje binarny operator poprawki,
!
aby był taki sam jakmod
. Haskellmod
zawsze generuje wartość nieujemną, więc nie potrzebujemy tegoabs
, co robią inne rozwiązania. Następnie sprawdza, czyx/k
(dzielenie liczb całkowitych) jest nieparzyste, a jeśli tak, zwracak-x mod k
(tj. Odskok wsteczny) lub zwracax mod k
.źródło
!
ponieważ nie oszczędza to więcej bajtówx#k|odd$x`div`k=k-x`mod`k|1<2=x`mod`k
PHP,
4050 bajtówcholerne dolary. cholerny narzut z importu. :)
wersja całkowita:
lub
wersja zmiennoprzecinkowa, 56 bajtów:
Wymień
abs($x)%$k
sięfmod(abs($x),$k)
.edycja: poprawiono wyniki dla negatywnych
x
źródło
€argv
lub£argv
? Wyglądałyby ładnie: xJavaScript (ES6),
3632 bajtówRekurencyjnie odbija się
x
od0
ik
tak bardzo w duchu wyzwania.źródło
Common Lisp, 41 bajtów
Wypróbuj online!
źródło
C (gcc),
4353 bajtówEdycja: Naprawiono negatywny problem
Wypróbuj online!
źródło
R, 28 bajtów
Który ocenia się na funkcję:
Która wydaje się być metodą używaną przez większość rozwiązań. Nie patrzyłem na nie przed zrobieniem tego.
źródło