Das Diagramm der Modulo-Operation ( ) sieht folgendermaßen aus:
Dies ist eine sehr nützliche Funktion, da wir so ein "Wrapping" -Verhalten erzeugen können. Es ist jedoch sehr umständlich, wenn ich es verwenden möchte, um eine Erscheinung des "Springens" zwischen zwei Wänden zu erzeugen. Der Graph der "Bounce" -Funktion ( ) sieht folgendermaßen aus:
Die Periode des Graphen von ist . Die Periode des Graphen von ist , weil es sich für Einheiten nach oben und dann für andere Einheiten nach unten bewegt , bevor es zu seinem Ausgangspunkt zurückkehrt. Für beide Funktionen ist der Minimalwert für 0 und der Maximalwert ist (tatsächlich ist er für die Modulfunktion mit integralen Eingängen ). Außerdem ist für beide Funktionen der Wert, bei dem ist, 0.
Die Herausforderung
Geben Sie bei einer Ganzzahl und einer positiven Ganzzahl eine Ganzzahl- oder Gleitkommanäherung von .
Dies ist Code-Golf , also gewinnt die kürzeste gültige Übermittlung (in Bytes gezählt).
Testfälle
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
Bonuspunkte für einen Fourier- basierten Ansatz in Fourier .
quelle
k % k = 0
k
.Antworten:
x86-64-Maschinencode, 18 Byte
Dieser Code definiert eine Funktion in der x86-64-Maschinensprache (die berechnet
bounce(x, k
). Gemäß der auf Gnu / Unix-Systemen verwendeten AMD64-Aufrufkonvention von System V wird derx
Parameter im übergebenEDI
Register übergeben, während derk
Parameter imESI
Register übergeben wird. Wie bei allen x86-Aufrufkonventionen wird das Ergebnis imEAX
Register zurückgegeben.Um dies von C aus aufzurufen, würden Sie einen Prototyp wie folgt erstellen:
Probieren Sie es online!
Ungolfed Assembler-Mnemonik:
Beachten Sie, dass der erste Abschnitt (der den absoluten Wert annimmt) äquivalent geschrieben worden sein könnte:
Das ist genau die gleiche Anzahl von Bytes (6). Die Leistung sollte ähnlich sein, vielleicht etwas schneller (außer am bestimmten Intel-Chips, bei denen bedingte Bewegungen langsam sind ).
XCHG
ist natürlich relativ langsam und wäre nicht vorzuziehen,MOV
außer beim Code-Golfen (das erstere ist 1 Byte, wenn einer der Operanden der Akkumulator ist, wohingegen ein Register-RegisterMOV
immer 2 Byte ist).quelle
Gelee , 3 Bytes
Probieren Sie es online!
Eingebaute ftw.
Erläuterung
æ%
ist ein nützliches eingebautes hier. Ich weiß nicht, wie ich es beschreiben soll, daher werde ich nur die Ausgabe für einige Eingaben bereitstellen:Wie
x
geht von0
unendlich,xæ%4
geht,0,1,2,3,4,(-3,-2,-1,0,1,2,3,4,)
wo der Teil in Klammern bis unendlich in beide Richtungen wiederholt wird.quelle
Python 2 ,
2927 BytesProbieren Sie es online!
quelle
Python 3 , 27 Bytes
Probieren Sie es online!
quelle
Ruby,
40 Bytes32 BytesProbieren Sie es online!
Erläuterung
Hallo, das ist meine erste Antwort auf dieser Seite! Dieser Code basiert auf der Beobachtung, dass sich die Bounce-Funktion genau wie Modulo verhält, wenn ( n -1) k <= x < nk und n ungerade sind, und sich wie eine umgekehrte Modulo-Operation verhält, wenn n gerade ist.
(x/k+1)
ist die kleinste ganze Zahl größer als x / k (was x / k + 1 ist, abgerundet auf eine ganze Zahl). Daher(x/k+1)
findet sich das oben erwähnte n .%2>0
prüft, ob n ungerade oder gerade ist. Wenn n mod 2> 0 ist, dann ist n ungerade. Wenn nmod 2 = 0, dann ist n gerade. Wenn n ungerade ist, sollte die Sprungfunktion gleich x mod k sein . Wenn n gerade ist, sollte die Sprungfunktion umgekehrt sein, gleich k - x mod k . Der gesamte Ausdruck(x/k+1)%2>0?x%k:k-x%k
findet n und führt dann das x mod k aus, wenn es ungerade ist, und führt sonst k - x mod k aus .Die Antwort wurde auf Vorschlag von Cyoce verbessert .
quelle
def b(x,k) ... end
Verwendung->x,k{...}
.to_i
ist dies nicht erforderlich.Mathematica, 19 Bytes
quelle
Pyth , 5 Bytes
Überprüfen Sie alle Testfälle.
Gabel meiner Python Antwort .
quelle
J, 25 Bytes
Hinweis:
Hier ist eine (noch nicht gut eingespielte) Lösung in J. Wir werden versuchen, uns morgen zu verbessern:
komprimiert:
[((|~#){])(i.@>:,}:@i.@-)@]
komprimiert2:
[((|~#){])(<:|.|@}.@i:)@]
Probieren Sie es online!
quelle
i:
, hier verwendet werden zu können, aber ich habe noch keine Lösung ausprobierti:
. Habe gerade keine Zeit gehabt, die Hauptversion zu aktualisieren und eine Erklärung abzugeben. Ich gehe davon aus, dass ein Experte mindestens 4 oder 5 weitere Bytes abschneiden könnte ...((|~#){])]-|@}:@i:
für 18 BytesQBIC ,
253027 BytesHab ein bisschen umstrukturiert ...
Erläuterung
quelle
x
ist -13 undk
ist 14.abs
beide Male?C89, 40 Bytes
AC-Port meiner x86-Maschinencode-Antwort , dies definiert eine Funktion
f
, die das Bounce-Modulo für die Parameterx
und berechnetk
.Es wird die implicit-int-Regel von C89 verwendet, sodass beide Parameter, die globale Variable
t
und der Rückgabewert der Funktion implizit vom Typ sindint
. Die globale Variablet
wird nur verwendet, um einen temporären Wert zu speichern, der letztendlich Bytes spart, verglichen mit dem Wiederholen der Berechnung auf beiden Seiten des bedingten Operators.Die
abs
Funktion (absoluter Wert) wird in der<stdlib.h>
Kopfzeile bereitgestellt , muss jedoch hier nicht angegeben werden. Dies ist wiederum der impliziten Ganzzahl von C89 zu verdanken (in der die Funktion implizit deklariert und als zurückgegeben angenommen wird)int
) nicht hier aufgenommen werden.Probieren Sie es online!
Ungolfed-Version:
In Anbetracht meines handoptimierten Maschinencodes generieren Compiler tatsächlich eine ziemlich gute Ausgabe dafür. Ich meine, sie sollten; Es ist eine ziemlich einfache Funktion zum Optimieren! Ich habe jedoch einen kleinen Fehler im x86-64-Optimierer von GCC entdeckt , bei dem merkwürdigerweise größerer Code erzeugt wird , wenn Sie ihn zur Optimierung der Größe auffordern, und kleinerer Code, wenn Sie ihn zur Optimierung der Geschwindigkeit auffordern .
quelle
m;f(x,k){m=abs(x%k);x=x/k%2?k-m:m;}
ist kürzerHaskell, 37 Bytes
Probieren Sie es online!
Verwendung:
Rufen Sie als
15#14
für nicht negative linke Argumente und als(-13)#14
für negative linke Argumente auf, da Haskell interpretieren würde,-13#14
als-(13#14)
ob Sie etwas wie verwendenghci
. Der TIO-Link akzeptiert einfach zwei Befehlszeilenargumente.Erläuterung:
Definiert den binären Infixoperator zunächst so
!
, dass er mit dem Operator identisch istmod
. Haskells gibtmod
immer einen nicht-negativen Wert aus, daher brauchen wir nicht dieabs
Lösungen, die andere hier haben. Dann wird geprüft, obx/k
(Ganzzahldivision) ungerade ist, und wenn ja, wird zurückgegebenk-x mod k
(dh das Zurückspringen), oder es wird zurückgegebenx mod k
.quelle
!
da es keine Bytes mehr speichertx#k|odd$x`div`k=k-x`mod`k|1<2=x`mod`k
PHP,
40-50Bytesverdammte Dollar. Verdammter Importaufwand. :)
Ganzzahlige Version:
oder
float version, 56 bytes:
Ersetzen
abs($x)%$k
durchfmod(abs($x),$k)
.edit: fixe ergebnisse für negative
x
quelle
€argv
oder£argv
? Die würden nett aussehen: xJavaScript (ES6),
3632 BytesSpringt rekursiv
x
gegen0
undk
, so sehr im Geiste der Herausforderung.quelle
Common Lisp, 41 Bytes
Probieren Sie es online!
quelle
C (GCC),
4353 BytesBearbeiten: Negatives Problem behoben
Probieren Sie es online!
quelle
R, 28 Bytes
Was zur Funktion auswertet:
Welches scheint die Methode zu sein, die die meisten Lösungen verwenden. Ich habe sie nicht angesehen, bevor ich das gemacht habe.
quelle