Aufgabe
Bei einer positiven Ganzzahl n
wird ausgegeben, n+1
wenn n
ungerade ist, und ausgegeben, n-1
wenn gerade n
ist.
Eingang
Eine positive ganze Zahl. Sie können davon ausgehen, dass sich die Ganzzahl innerhalb der Verarbeitungskapazität der Sprache befindet.
Ausgabe
Eine positive ganze Zahl, wie oben angegeben.
Testfälle
input output
1 2
2 1
3 4
4 3
5 6
6 5
7 8
8 7
313 314
314 313
Wertung
Das ist Code-Golf , also gewinnt die kürzeste Antwort in Bytes.
Es gelten Standardlücken .
Antworten:
C 20 Bytes
Probieren Sie es online aus .
quelle
Stapel Katzen , 3 + 3 (
-n
) = 6 BytesProbieren Sie es online!
Braucht die
-n
Flag, um mit numerischer Eingabe und Ausgabe zu arbeiten.Erläuterung
Stack Cats ist in der Regel weit davon entfernt, wettbewerbsfähig zu sein, da es sich bei den Befehlen um Injektionen und bei den meisten um Involutionen handelt und jedes Programm eine Spiegelsymmetrie aufweisen muss. Eine der Involutionen besteht jedoch darin, das niedrigstwertige Bit einer Zahl umzuschalten, und wir können den Wert durch eine ebenfalls vorhandene unäre Negation ausgleichen. Zum Glück gibt uns das ein symmetrisches Programm, sodass wir uns um nichts anderes kümmern müssen:
Eingabe und Ausgabe sind am Anfang und Ende des Programms implizit, da die Eingabe und Ausgabe nicht umkehrbar ist und daher keine Befehle sein können.
quelle
perl -nle 'stuff'
ist 2 Zeichen mehr alsperl -e 'stuff'
, also zählt es für 2 weitere Zeichen ". Also(space)-n
sind 3 Bytes mehr als ohne Flag.-e "code"
und dann zusätzliche Flags vor dem einfügene
, z-pe "code"
. Dann ist das-p
Flag nur ein Byte. Stack Cats hat jedoch kein solches-e
Argument, daher müssen Sie<sp>-n
dem Befehl immer den vollen Wert hinzufügen , und daher sind es drei Bytes.x86-Assembly, 9 Byte (für konkurrierende Einträge)
Jedem, der diese Herausforderung in Hochsprachen versucht, entgeht der wahre Spaß, rohe Teile zu manipulieren. Es gibt so viele subtile Variationen, es ist verrückt - und es macht viel Spaß, darüber nachzudenken. Hier sind einige Lösungen, die ich in der 32-Bit-x86-Assemblersprache entwickelt habe.
Ich entschuldige mich im Voraus, dass dies nicht die typische Code-Golf-Antwort ist. Ich werde viel über den Gedankenprozess der iterativen Optimierung (für die Größe) streifen. Hoffentlich ist das interessant und lehrreich für ein größeres Publikum, aber wenn Sie der TL; DR-Typ sind, werde ich nicht beleidigt sein, wenn Sie bis zum Ende springen.
Die naheliegende und effiziente Lösung besteht darin, zu testen, ob der Wert ungerade oder gerade ist (was effizient durch Betrachten des niedrigstwertigen Bits erfolgen kann), und dann entsprechend zwischen n + 1 oder n - 1 zu wählen . Unter der Annahme, dass die Eingabe als Parameter im
ECX
Register übergeben wird und das Ergebnis imEAX
Register zurückgegeben wird, erhalten wir die folgende Funktion:(13 Bytes)
Für Code-Golf-Zwecke sind diese
LEA
Anweisungen jedoch nicht besonders gut, da sie 3 Byte zum Codieren benötigen. Eine einfacheDEC
Rementation vonECX
wäre viel kürzer (nur ein Byte), dies wirkt sich jedoch auf Flags aus. Wir müssen also etwas geschickter sein, wie wir den Code anordnen. Wir können die Abnahme tun zuerst , und die gerade / ungerade Test zweite , aber dann haben wir das Ergebnis der gerade / ungerade Test invertieren.Außerdem können wir die Anweisung zum bedingten Verschieben in eine Verzweigung ändern, wodurch der Code möglicherweise langsamer ausgeführt wird (je nachdem, wie vorhersehbar die Verzweigung ist) Muster, es wird schneller sein), was uns ein weiteres Byte sparen wird.
Tatsächlich kann mit dieser Überarbeitung die gesamte Operation an Ort und Stelle ausgeführt werden, wobei nur ein einziges Register verwendet wird. Das ist großartig, wenn Sie diesen Code irgendwo einfügen (und es ist wahrscheinlich, dass er so kurz ist).
(Inline: 7 Bytes; als Funktion: 10 Bytes)
Aber was, wenn Sie es zu einer Funktion machen wollten? Keine Standardaufrufkonvention verwendet für die Übergabe von Parametern dasselbe Register wie für den Rückgabewert. Daher müssen Sie
MOV
am Anfang oder Ende der Funktion eine Register-Register- Anweisung hinzufügen . Dies hat praktisch keine Kosten für die Geschwindigkeit, fügt jedoch 2 Bytes hinzu. (DieRET
Anweisung fügt auch ein Byte hinzu, und es entsteht ein gewisser Overhead durch die Notwendigkeit, einen Funktionsaufruf auszuführen und von diesem zurückzukehren. Dies ist also ein Beispiel, bei dem Inlining sowohl einen Geschwindigkeits- als auch einen Größenvorteil erzeugt, anstatt nur eine klassische Geschwindigkeit zu sein -für-den-Raum-Kompromiss.) Insgesamt wird dieser Code als Funktion auf 10 Bytes aufgebläht.Was können wir in 10 Bytes noch tun? Wenn es uns überhaupt um Leistung geht (zumindest vorhersehbare Leistung), wäre es schön, diesen Zweig loszuwerden. Hier ist eine verzweigungslose Bit-Twiddling-Lösung mit der gleichen Größe in Bytes. Die Grundvoraussetzung ist einfach: Wir verwenden ein bitweises XOR, um das letzte Bit umzukehren und einen ungeraden Wert in einen geraden Wert umzuwandeln und umgekehrt. Aber es gibt ein Problem - für ungerade Eingaben erhalten wir n-1 , für gerade Eingaben erhalten wir n + 1 - genau das Gegenteil von dem, was wir wollen. Um dies zu beheben, führen wir die Operation mit einem negativen Wert durch, wobei das Vorzeichen effektiv umgedreht wird.
(Inline: 7 Bytes; als Funktion: 10 Bytes)
Ziemlich glatt; Es ist schwer zu erkennen, wie das verbessert werden kann. Eines fällt mir jedoch auf: diese zwei 2-Byte-
NEG
Anweisungen. Ehrlich gesagt scheinen zwei Bytes ein Byte zu viel zu sein, um eine einfache Negation zu codieren, aber das ist der Befehlssatz, mit dem wir arbeiten müssen. Gibt es Workarounds? Sicher! Wenn wirXOR
durch -2 ersetzen, können wir die zweiteNEG
Ation durch eineINC
Zement ersetzen:(Inline: 6 Bytes; als Funktion: 9 Bytes)
Ein weiterer die Merkwürdigkeiten des x86 - Befehlssatzes ist die Mehrzweck
LEA
Anweisung , die ein Register-Register bewegen tun, ein Register-Register zusätzlich durch eine konstanten Ausgleich, und das alles in einem einzigen Befehl Skalierung!(10 Bytes)
Der
AND
Befehl entspricht demTEST
zuvor verwendeten Befehl, da beide ein bitweises UND ausführen und die Flags entsprechend setzen, aberAND
den Zieloperanden tatsächlich aktualisieren. DerLEA
Befehl skaliert dies dann um 2, addiert den ursprünglichen Eingabewert und dekrementiert ihn um 1. Wenn der Eingabewert ungerade war, subtrahiert dies 1 (2 × 0 - 1 = –1) davon; Wenn der Eingabewert gerade war, wird 1 (2 × 1 - 1 = 1) hinzugefügt.Dies ist eine sehr schnelle und effiziente Methode, um den Code zu schreiben, da ein Großteil der Ausführung im Front-End ausgeführt werden kann, aber es bringt uns nicht viel mit Bytes, da so viele zum Codieren eines Komplexes erforderlich sind
LEA
Anweisung. Diese Version funktioniert auch nicht so gut für Inlining-Zwecke, da der ursprüngliche Eingabewert als Eingabe derLEA
Anweisung beibehalten werden muss . Mit diesem letzten Optimierungsversuch sind wir also tatsächlich zurückgegangen, was darauf hindeutet, dass es an der Zeit ist, damit aufzuhören.Für den letzten konkurrierenden Eintrag haben wir also eine 9-Byte-Funktion, die den Eingabewert in das
ECX
Register (eine registerbasierte Semistandard-Aufrufkonvention für 32-Bit x86) aufnimmt und das Ergebnis imEAX
Register zurückgibt (wie bei alle x86-Aufrufkonventionen):Montagefertig mit MASM; Aufruf von C als:
quelle
dec eax; xor eax, 1; inc eax
funktionieren und ein Byte mehr sparen?Gelee , 3 Bytes
Probieren Sie es online!
Pseudocode:
abs((-1)**n - n)
quelle
-1
.Python3,
20 bis18 BytesZiemlich einfach. Zuerst berechnen wir n-1 und entscheiden, ob wir 2 hinzufügen wollen oder nicht.
Wenn n gerade ist -> n mod 2 wird 0 sein, so werden wir 2 * 0 zu n-1 addieren , was zu n-1 führt .
Wenn n ungerade ist -> n mod 2 ist 1, so addieren wir 2 * 1 zu n-1 , was zu n + 1 führt .
Ich bevorzuge eine Erklärung, die ich mit MS Paint und einem Laptop-Touchpad gemacht habe ...
quelle
Python, 16 Bytes
Probieren Sie es online!
quelle
"x+-012~|&^()*/%"
.-(1^-x)
.MATL , 7 Bytes
Dadurch werden Rechenoperationen vermieden. Probieren Sie es online!
Erläuterung
Betrachten Sie die Eingabe
4
als Beispiel.quelle
Braingolf v0.1 ,
1110 BytesProbieren Sie es online! (Zweites Argument ist der Braingolf-Code, drittes Argument ist die Eingabe)
Ein Byte dank Neil gespeichert
Die erste konkurrierende Braingolf-Antwort: D
Erläuterung:
Braingolf v0.2 , 9 bytes [nicht konkurrierend]
Probieren Sie es online! (Zweites Argument ist der Braingolf-Code, drittes Argument ist die Eingabe)
Erklärung siehe oben. Der einzige Unterschied ist, dass in Braingolf v0.2 das Standardverhalten von diadischen Operatoren und die Funktion des
,
Modifikators umgekehrt sind, was bedeutet, dass die 2 Kommas in der v0.1-Antwort nicht mehr benötigt werden.Jedoch wurde v0.2 nach der Herausforderung veröffentlicht, so dass dieser nicht konkurrierend ist
quelle
.1<2,%?+:-
was ich denke was es tut?-
, damit die Operation korrekt ausgeführt wird. In diesem Fall hat sie immer noch die gleiche Länge wie meine Antwort<
, dass der1
unterhalb des Eingangs rotiert , so dass er bereits an der richtigen Stelle wäre.-
sieht sie bis zum Erreichen des Stacks folgendermaßen aus:[n,1]
Braingolf-Operatoren werden umgekehrt, sodass sie ausgeführt werden1 - n
, was zur Folge hat-(n-1)
, dass das gewünschte Ergebnis einfachn-1
Cubix ,
109 BytesProbieren Sie es online aus
Erläuterung
Netzversion
Die ausgeführten Zeichen sind
quelle
Python, 68 Bytes
Im Geiste eines einzigartigen Ansatzes. Das folgende Diagramm zeigt die Funktion (mit violetten Punkten, die die ersten 10 Fälle darstellen). Es sollte theoretisch möglich sein, eine Lösung für diese Frage auf der Grundlage der meisten (alle?) Periodischen Funktionen (z. B. sin, tan, sec) zu konstruieren. Tatsächlich sollte das Ersetzen von cos für sec im Code funktionieren.
quelle
PHP, 15 Bytes
quelle
;
erforderlich ist, und habe versucht, eine.php
Datei zu verwenden und auch direkt in php (php7 cli.) Zurückzukehren. Jedes Mal, wenn mir gesagt wird, dass dies$argn
eine undefinierte Variable ist.F
Flagge und einer Pipeline:echo 42 | php -F script.php
.Javascript,
1712 BytesEin weiterer Ansatz, 10 Bytes
aus der C-Antwort gestohlen (sssshhh)quelle
x=>x-(-1)**x
|0
? Beide Lösungen scheinen automatisch Zeichenfolgen in Zahlen umzuwandeln. (Für die erste Lösung, wenn Sie Dezimalstellen vermeiden möchten, verwenden Sie<input type=number>
.)JavaScript (ES6),
14131210 ByteVersuch es
Original, 12 Bytes
quelle
Python, 20 Bytes
n%2or-1
wird 1 zurückgeben, wenn es ungerade ist, aber wenn es gerade ist,n%2
ist es "falsch" (0), also gibt es stattdessen -1 zurück. Dann fügen wir das einfach hinzun
.Vorherige Lösung, 23 Bytes
n%2
berechnet den Rest, wenn ern
durch 2 geteilt wird. Wenn er gerade ist, wird 0 zurückgegeben, und Element 0 in dieser Liste istn-1
. Wenn es ungerade ist, gibt dies 1 zurück und Element 1 in dieser Liste istn+1
.quelle
lambda n:[n-1,n+1][n%2]
Netzhaut , 21 Bytes
Probieren Sie es online! Meine erste Retina-Antwort mit zwei nachgestellten Zeilenumbrüchen! Erläuterung: Die ersten beiden Zeilen werden von dezimal in unär umgewandelt. Die dritte und vierte Zeile subtrahieren zwei von geraden Zahlen. Die letzte Zeile wird zurück in Dezimal umgewandelt, fügt aber auch eine hinzu.
quelle
05AB1E , 4 Bytes
Probieren Sie es online!
quelle
Èi>ë<
aber so hübsch;_;
.Cubix , 11 Bytes
Probieren Sie es online!
Erläuterung
Netzversion:
Zeichen werden in der folgenden Reihenfolge ausgeführt:
quelle
Brain-Flak , 36 Bytes
Probieren Sie es online!
Ich persönlich bin mit dieser Antwort sehr zufrieden, da sie viel kürzer ist als die herkömmliche Methode zur Lösung dieses Problems.
Erläuterung
Das erste Stück Code
konvertiert den Stack von nur
n
nachDann, während der obere Teil des Stapels nicht Null ist, dekrementieren wir ihn und drehen das Vorzeichen der Zahl darunter
Dann entfernen wir die Null und addieren die beiden verbleibenden Zahlen
quelle
Mathematica,
2219 Bytes3 Bytes gespart dank Greg Martin!
Vorherige Antwort 22 Bytes
Erklärung (für vorherige Antwort)
Mathematica hat die nette Funktion, dass Operationen wie das Rechnen automatisch über Listen laufen.
In diesem Fall nehmen wir,
Mod[#,2]
was 0 oder 1 zurückgibt, aber wir müssen 1 hinzufügen, weil Mathematica-Listen 1-indiziert sind. Wenn es gerade ist , ergibt dies 1 und#-1
wird zurückgegeben. Wenn es ungerade ist , ergibt dies 2 und#+1
wird zurückgegeben.quelle
[[0]]
Fähigkeit:#-1[-1][[#~Mod~2]]&
.Wise , 8 Bytes
Probieren Sie es online!
Erläuterung
Wenn dies umgekehrt wäre (Verringern wenn ungerade, Erhöhen wenn gerade), wäre es ziemlich einfach, dies zu tun.
Wir würden nur das letzte Stück drehen.
Das Problem ist, dass wir das letzte bisschen drehen, während wir negativ sind. Die negativen Zahlen weichen von der Negation der Zahlen um 1 ab,
~
sodass ein Versatz entsteht, der das Problem löst.Also nehmen wir einfach das Programm heraus und packen es ein
-
.quelle
Java 8,
1610 BytesJava 7,
3428 BytesLangweilige Häfen von @feersums erstaunlicher C-Antwort .
Probieren Sie es hier aus.
Alte Antworten:
Java 8, 16 Bytes
Java 7, 34 Bytes
Erklärung (der alten Java 7 Antwort):
Probieren Sie es hier aus.
Die Antwort oben ist eine kürzere Variante,
int c(int n){return n%2<1?n-1:n+1;}
indem Sie den Raum loswerden.quelle
Japt , 6 Bytes
Probieren Sie es online!
quelle
Python, 20 Bytes
quelle
Befunge 93 , 18 Bytes
Ich bin noch nicht fertig mit Golfen (hoffe ich).
quelle
kv
(oderjv
wenn es streng 1 oder 0 ist) anstelle von verwenden#v_
. Wenn Sie Try it online verwenden (und ich empfehle es), können Sie das Programm auch mit einem anderen beenden&
(obwohl dies 60 Sekunden dauert), sodass Sie das@
in der ersten Zeile entfernen können, wenn Sie das verwenden. Hier ist die vollständige Liste der Befehle für Befunge-98 , auch wenn sie in TIO möglicherweise nicht alle korrekt implementiert sind, z. B. das&
Beenden des Programms anstelle der Umkehrung auf EOF.Ruby, 12 Bytes
quelle
R, 17 Bytes
wo
n=scan()
ist der Wert für diese Stelle.quelle
-(-1)^n
anstatt dass+(-1)^n
wir zurückkehren müssen,n-1
wennn
es gerade istCasio-Basic, 27 Bytes
26 Byte für die Funktion, +1 für die Eingabe
n
in das Parameterfeld.quelle
C 29 Bytes
quelle
Gelee , 4 Bytes
Probieren Sie es online!
quelle
Batch, 20 Bytes
Unabhängig wiederentdeckt @ feersums Algorithmus, ehrlich!
quelle