Die alten Griechen hatten diese Dinge einfach und doppelt gerade Zahlen genannt. Ein Beispiel für eine einfach gerade Zahl ist 14. Sie kann einmal durch 2 geteilt werden und ist dann zu einer ungeraden Zahl (7) geworden, nach der sie nicht mehr durch 2 teilbar ist. Eine doppelt gerade Zahl ist 20. Sie kann zweimal durch 2 geteilt werden und wird dann zu 5.
Ihre Aufgabe ist es, eine Funktion oder ein Programm zu schreiben, die / das eine Ganzzahl als Eingabe und die Anzahl der durch 2 teilbaren Ganzzahlen in möglichst wenigen Bytes ausgibt. Die Eingabe ist eine Ganzzahl ungleich Null (jeder positive oder negative Wert innerhalb der Grenzen Ihrer Sprache).
Testfälle:
14 -> 1
20 -> 2
94208 -> 12
7 -> 0
-4 -> 2
Die Antwort mit den wenigsten Bytes gewinnt.
Tipp: Versuchen Sie, die Zahl in Basis 2 umzuwandeln. Sehen Sie, was Ihnen das sagt.
The input will be a nonzero integer
Muss dies nach Ihrem Kommentar über Null als potenzielle Eingabe bearbeitet werden?Antworten:
Gelee , 4 Bytes
In der neuesten Version von Jelly
ÆEḢ
funktionieren (3 Byte).Probieren Sie es hier aus .
quelle
x86_64-Maschinencode, 4 Byte
Der BSF-Befehl (Bit Scan Forward) macht genau das !
In der gcc-artigen Montage ist dies:
Die Eingabe wird im EDI-Register angegeben und gemäß den üblichen 64-Bit- C- Aufrufkonventionen im EAX-Register zurückgegeben .
Aufgrund der Zweierkomplement-Binärcodierung funktioniert dies sowohl für -ve- als auch für + ve-Zahlen.
Auch trotz der Dokumentation "Wenn der Inhalt des Quelloperanden 0 ist, ist der Inhalt des Zieloperanden undefiniert." Finde ich auf meiner Ubuntu VM, dass die Ausgabe von
f(0)
0 ist.Anleitung:
evenness.s
und montieren Sie mitgcc -c evenness.s -o evenness.o
evenness-main.c
und kompilieren Sie mitgcc -c evenness-main.c -o evenness-main.o
:Dann:
gcc evenness-main.o evenness.o -o evenness
./evenness
@FarazMasroor bat um weitere Informationen darüber, wie diese Antwort abgeleitet wurde.
Da ich mit C besser vertraut bin als mit den Feinheiten von x86-Assemblys, benutze ich normalerweise einen Compiler, um Assembly-Code für mich zu generieren. Ich weiß aus Erfahrung , dass gcc Erweiterungen wie
__builtin_ffs()
,__builtin_ctz()
und__builtin_popcount()
typischerweise zusammenzustellen und um 1 oder 2 Anweisungen auf x86 montieren. Also begann ich mit einer c- Funktion wie:Anstatt die reguläre GCC-Kompilierung bis hin zum Objektcode zu verwenden, können Sie die
-S
Option verwenden, um nur Assembly zu kompilierengcc -S -c evenness.c
. Dies ergibt eine Assembly-Dateievenness.s
wie folgt:Vieles davon kann ausgenutzt werden. Insbesondere wissen wir, dass die c- Aufrufkonvention für Funktionen mit
int f(int n);
Signatur nett und einfach ist - der Eingabeparameter wird imEDI
Register übergeben und der Rückgabewert wird imEAX
Register zurückgegeben. So können wir die meisten Anweisungen herausnehmen - viele befassen sich mit dem Speichern von Registern und dem Einrichten eines neuen Stapelrahmens. Wir benutzen den Stack hier nicht und benutzen nur dasEAX
Register, also brauchen wir uns nicht um andere Register zu kümmern. Dies hinterlässt den Assembler-Code "Golf":Beachten Sie, wie @zwol hervorhebt, dass Sie auch eine optimierte Kompilierung verwenden können, um ein ähnliches Ergebnis zu erzielen.
-Os
Produziert insbesondere genau die obigen Anweisungen (mit ein paar zusätzlichen Assembler-Direktiven, die keinen zusätzlichen Objektcode produzieren.)Diese wird nun mit zusammengesetzt
gcc -c evenness.s -o evenness.o
, die dann wie oben beschrieben in ein Testtreiberprogramm eingebunden werden können.Es gibt verschiedene Möglichkeiten, den dieser Baugruppe entsprechenden Maschinencode zu ermitteln. Mein Favorit ist die Verwendung des
disass
Befehls gdb disassembly:So können wir sehen, dass der Maschinencode für die
bsf
Anweisung0f bc c7
und fürret
istc3
.quelle
evenness-main.c
mit verschiedenen Optimierungseinstellungen kompilieren . für mich bricht es mit-O
,-O2
oder-O3
.Python, 25 Bytes
n & -n
setzt alles außer dem niedrigstwertigen Bit auf Null, zB dies:Wir sind an der Anzahl der nachgestellten Nullen interessiert, also konvertieren wir sie mit in eine Binärzeichenfolge
bin
, die für die obige Zahl gilt"0b10000"
. Da uns weder das0b
noch das1
wichtig ist, subtrahieren wir 3 von dieser Saitenlänge.quelle
Pyth, 6 Bytes
Probieren Sie es hier aus .
quelle
JavaScript (ES6), 18 Byte
4 Bytes kürzer als
31-Math.clz32
. Hahquelle
Math.clz32
...JavaScript ES6,
2219 BytesRekursion scheint der kürzeste Weg zu sein.
quelle
Pyth, 8 Bytes
Zum Beispiel ist die binäre Darstellung von
94208
:Nach dem Teilen von
1
s und dem Aufnehmen des letzten Elements des resultierenden Arrays wird dies zu:Das sind 12 Nullen, also ist es "gerade 12".
Dies funktioniert, weil
x / 2
es sich im Wesentlichenx >> 1
um ein Bitverschiebungsrecht von handelt1
. Daher ist eine Zahl nur dann durch 2 teilbar, wenn das LSB ist0
(genau wie eine Dezimalzahl durch 10 teilbar ist, wenn ihre letzte Ziffer ist0
).quelle
05AB1E ,
45 BytesUnterstützt jetzt negative Zahlen. Code:
Probieren Sie es online!
Erläuterung:
Verwendet die CP-1252-Codierung.
quelle
Pyth, 6 Bytes
Grundsätzlich nur
quelle
MATL , 5 Bytes
Dies funktioniert für alle ganzen Zahlen.
Probieren Sie es online!
quelle
C, 36 (28) Bytes
(Es wurde angegeben, dass kein Argument ungleich Null auf Null geprüft werden soll.)
Update (als Antwort auf einen Kommentar) : Wenn wir Funktionsdeklarationen im K & R-Stil zulassen, können wir eine 28-Byte-Version haben:
In diesem Fall verlassen wir uns auf die Tatsache, dass der Compiler standardmäßig sowohl
n
als auch den Rückgabetyp vonf
to verwendetint
. Dieses Formular generiert jedoch eine Warnung mit C99 und wird nicht als gültiger C ++ - Code kompiliert.quelle
int n
->n
es ist immer noch gültiger C-Code und schneidet 4 Zeichen ab.Java 7, 39 oder vielleicht 44 Bytes
Ja Rekursion! Ich musste einen
!=
anstelle eines kürzeren Vergleichs verwenden, damit es bei negativen Eingaben nicht überläuft, aber ansonsten ist es ziemlich einfach. Wenn es ungerade ist, senden Sie eine Null. Wenn ja, fügen Sie einen hinzu und wiederholen Sie den Vorgang.Es gibt zwei Versionen, da die Ausgabe für Null derzeit unbekannt ist. Der erste Befehl wird solange wiederholt, bis der Stapel überläuft, und gibt nichts aus, da 0 unendlich gerade ist. Die zweite spuckt eine schöne, sichere, aber wahrscheinlich nicht mathematisch strenge 0 für die Ausgabe aus.
quelle
JavaScript (ES6),
20 Bytes,19 Bytes.Dies ist ein Port der Haskell-Lösung von @nimi zu JavaScript. Es verwendet die "Kurzschluss" -Eigenschaften
&&
, deren linke Seite zurückgegeben wird, wenn es falsch ist (was in diesem Fall der Fall ist-0
) oder die rechte Seite zurückgibt. Zur Umsetzung machenodd x = 0
wir daher die linke Seite,1 - (x % 2)
die0
durch die sprudelt&&
, ansonsten greifen wir zu1 + f(x / 2)
.Das Rasieren von
1 - (x % 2)
as(~x) % 2
ist auf @Neil zurückzuführen und hat die seltsame Eigenschaft, dass die obige Funktion-0
kleine ungerade Zahlen ausgibt . Dieser Wert ist eine Besonderheit der Entscheidung von JS, dass ganze Zahlen IEEE754-Doppelte sind. Dieses System hat ein separates+0
und-0
in JavaScript spezielles Gehäuse, um===
untereinander zu sein. Der~
Operator berechnet die bitweise 32-Bit-Ganzzahl-Inversion für die Zahl, die für kleine ungerade Zahlen eine negative gerade Zahl ist. (Die positive ZahlMath.pow(2, 31) + 1
zum Beispiel erzeugt0
eher als-0
.) Die seltsame Beschränkung auf die 32-Bit-Ganzzahlen hat keine anderen Auswirkungen; es beeinträchtigt insbesondere nicht die Richtigkeit.quelle
~x&1
ist ein Byte kürzer als1-x%2
.Perl 6,
2318 BytesVerwendungszweck
quelle
Ruby 24 Bytes
Meine erste Code Golf Einreichung (yey!)
Wie ich hierher gekommen bin :
Zuerst wollte ich Code bekommen, der die Spezifikation tatsächlich erfüllte, um das Problem in den Griff zu bekommen, also baute ich die Methode ohne Rücksicht auf die Anzahl der Bytes auf:
Mit diesem Wissen habe ich die Funktion in eine while-Schleife
$*
dekursiert und (ARGV) als Eingabe und i als Anzahl der Halbierungen der Zahl hinzugefügt, bevor sie ungerade wird.Ich war ziemlich stolz darauf und hätte es beinahe eingereicht, bevor mir auffiel, dass all das Teilen durch zwei für mich ein bisschen binär klang, weil ich ein Software-Ingenieur, aber nicht so sehr ein Informatiker war.
Daher habe ich einige Ergebnisse darüber gesammelt, wie die Eingabewerte im Binärformat aussahen:
Mir ist aufgefallen, dass das Ergebnis die Anzahl der Positionen links ist, die wir überqueren müssen, bevor die Anzahl ungerade wird.
Durch einige einfache Zeichenkettenmanipulationen habe ich die Zeichenkette beim letzten Auftreten von 1 geteilt und die Länge der verbleibenden Nullen gezählt:
Verwenden Sie die
("%b" % x)
Formatierung, um eine Zahl in eine Binärzahl umzuwandeln, und die Zeichenfolge # , um die Zeichenfolge aufzuteilen.Ich habe auf dieser Suche ein paar Dinge über Rubin gelernt und freue mich bald auf weitere Golfplätze!
quelle
@wizzwizz4
am Anfang einen Kommentar ein, um mir zu antworten. (Dies funktioniert mit allen Benutzernamen!)J, 6 Bytes
Erläuterung:
quelle
C 37 Bytes
f(int x){return x?x&1?0:1+f(x/2):0;}
Überprüfen Sie das letzte Bit rekursiv, bis es keine 0 mehr ist.quelle
f(int n){return __builtin_ctz(n);}
wenn Sie bereit sind, gcc-Erweiterungen zu verwenden. Oder sogar#define f __builtin_ctz
int
. Es ist implizit, genau wie der Rückgabetyp.f(n){...}
? GCC wird es nicht kompilieren. Ich bin kein C-Experte, aber eine schnelle Suche zeigt, dass dieses Feature in neueren Versionen von C entfernt wurde. Also wird es möglicherweise mit den entsprechenden Flags kompiliert?-ansi
oder-gnu99
? Ich weiß, ich habe es zum Arbeiten gebracht. Ich habe eine Tippantwort dazu geschrieben!Haskell, 28 Bytes
Anwendungsbeispiel:
f 94208
->12
.Wenn die Zahl ungerade ist, ist das Ergebnis
0
, sonst1
plus ein rekursiver Anruf mit der Hälfte der Zahl.quelle
div x 2
? Warum nichtx/2
?div
ist eine Ganzzahldivision, eine/
Gleitkommadivision.Befunge, 20
Die Codeausführung bewegt sich weiter nach rechts und umschließt das zweite Zeichen der ersten Zeile (dank des Trailings
#
) bis zur2%
Ausgabe1
, wodurch_
die Richtung nach links und dann|
nach oben gewechselt wird, die<
in die zweite Zeile übergeht. welche Ausgänge und Ausgänge. Wir inkrementieren das zweitoberste Element des Stapels jedes Mal durch die Schleife und teilen dann das oberste Element durch 2.quelle
Netzhaut ,
2917Probieren Sie es online!
2 Bytes gespart dank Martin!
Nimmt unäre Eingaben auf. Dies stimmt wiederholt mit der größten Menge von
1
s überein, die es geben kann, so dass diese Anzahl von1
s genau mit dem Rest von1
s in der Anzahl übereinstimmt . Jedes Mal, wenn dies geschieht;
, wird der Zeichenfolge ein vorangestellt . Am Ende zählen wir die Anzahl der;
s in der Zeichenfolge.Wenn Sie eine Dezimaleingabe wünschen, fügen Sie Folgendes hinzu:
an den Anfang des Programms.
quelle
Jolf, 6 Bytes
Probieren Sie es hier aus!
Ganz einfach ... Ein dickes Lob an ETHProductions, dass sie Jolf mit der Version verdrängt haben, die wirklich funktionieren sollte!
quelle
PARI / GP, 17 Bytes
quelle
6502 Maschinensprache, 7 Bytes
Um den Stellenwert des niedrigstwertigen 1-Bit des Nicht-Null-Werts im Akkumulator zu finden, belassen Sie das Ergebnis in Register X:
Um dies auf dem 6502-Simulator auf e-tradition.net auszuführen , muss ihm
A9
eine 8-Bit-Ganzzahl vorangestellt werden .Dies lässt sich wie folgt zerlegen:
Dies entspricht dem folgenden C, mit der Ausnahme, dass C
int
mindestens 16 Bit lang sein muss:Dasselbe funktioniert auf einem 65816 unter der Annahme von MX = 01 (16-Bit-Akkumulator, 8-Bit-Index) und entspricht dem obigen C-Snippet.
quelle
Brachylog ,
2715 BytesErläuterung
quelle
CJam, 8 Bytes
Ganzzahl, Absolutwert, Primfaktor lesen, zwei zählen.
quelle
JavaScript ES6, 36
38BytesZwei Bytes dank @ETHproductions
Ziemlich langweilige Antwort, aber es macht den Job. Kann einer anderen Antwort tatsächlich zu ähnlich sein, wenn er die vorgeschlagenen Änderungen hinzufügt, werde ich meine entfernen.
Um es auszuführen, weisen Sie es einer Variablen (
a=>{for...
) zu, da es eine anonyme Funktion ist, und rufen Sie es dann mit aufa(100)
.quelle
b%2==0
kann in geändertb%2-1
undc++
innerhalb des letzten Teils derfor
Anweisung verschoben werden . Ich denke, das würde auch funktionieren:b=>eval("for(c=0;b%2-1;b/=2)++c")
b%2-1
=>~b&1
Auch ich denke , das nicht auf Eingabe0
, die mit festgelegt werden kannb&&~b&1
b%2-1
Überprüfung auf negative ungerade Zahlen schlägt fehl.ES6, 22 Bytes
Gibt -1 zurück, wenn Sie 0 übergeben.
quelle
DUP , 20 Bytes
Try it here!
In Rekursion konvertiert, ist die Ausgabe jetzt die höchste Zahl im Stapel. Verwendungszweck:
Erläuterung
quelle
Japt,
95 BytesOnline testen!
Die vorherige Version sollte aus fünf Bytes bestehen, aber diese Version funktioniert tatsächlich.
Wie es funktioniert
quelle
C
444038 36 Bytes2 Bytes weg danke @JohnWHSmith . 2 Bytes weg danke @luserdroog .
Teste live auf ideone .
quelle
!(n%2)
durch ein nettes kleines ersetzen~n&1
.=0
. Globals werden implizit auf 0 initialisiert.a
, funktioniert sie nicht garantiert nur beim ersten Aufruf? Ich wusste nicht, dass das erlaubt war.