Überprüfen Sie, ob eine Ganzzahl eine Potenz von 2 ist, ohne +, - -Operationen zu verwenden [closed]


30

Schreiben Sie ein Programm, das überprüft, ob die Ganzzahl eine Potenz von 2 ist.


Beispieleingabe:

8

Beispielausgabe:

Yes

Beispieleingabe:

10

Beispielausgabe:

No

Regeln:

  • Verwenden Sie nicht +, -Operationen.

  • Verwenden Sie einen Eingabestream, um die Nummer zu ermitteln. Die Eingabe soll zunächst nicht in einer Variablen gespeichert werden.

  • Der kürzeste Code (in Bytes) gewinnt.

Sie können jede wahrheitsgemäße / falsche Antwort verwenden (z. B. true/ false). Sie können davon ausgehen, dass die eingegebene Nummer größer als ist 0.


1
Darf man auch "true" anstelle von "yes" und "false" anstelle von "no" ausgeben?
ProgramFOX

2
Ja, Sie können jede positive / negative Antwort verwenden. Die Frage wurde aktualisiert.
gthacoder

1
Die predFunktion, wenn in eine ganze Zahl n angewendet wird , kehrt n - 1 sind Funktionen wie diese, die dünne Verkleidung um den verbotenen Betreiber sind auch verboten?
Wayne Conrad

1
@Wayne genau wie Golfscript )oder die meisten C-basierten Sprachen --.
Türklinke

2
Ich weiß, dass wir jetzt 3 Jahre in der Zukunft sind, aber "+/- Operatoren" sind nicht beobachtbar oder zumindest schwach definiert.
ATaco

Antworten:


13

GolfScript, 6 Zeichen, keine Dekremente

~.3/&!

Hier ist eine Lösung, die die x & (x-1)Methode in keiner Form verwendet. Es verwendet x & (x/3)stattdessen. ;-) Gibt 0false aus, 1wenn true.

Erläuterung:

  • ~ Wertet die Eingabezeichenfolge aus, um sie in eine Zahl umzuwandeln.
  • .dupliziert es (für das nachfolgende &),
  • 3/ teilt es durch drei (abschneiden),
  • & berechnet das bitweise UND des geteilten Wertes mit dem Original, das genau dann Null ist, wenn die Eingabe Null oder eine Zweierpotenz ist (dh wenn höchstens ein Bit gesetzt ist), und
  • ! Negiert dies logisch und ordnet null und alle anderen Werte null zu.

Anmerkungen:

  • Nach den erläuterten Regeln ist Null keine gültige Eingabe , daher ist dieser Code in Ordnung, auch wenn er ausgegeben wird, 1wenn die Eingabe Null ist.

  • Wenn der GolfScript-Dekrement-Operator (zulässig ist, reicht die von aditsu bereitgestellte 5- ~.(&! stellige Lösung aus. Es scheint jedoch gegen den Geist der Regeln zu verstoßen , wenn nicht gegen den Buchstaben.

  • Ich habe mir den x & (x/3)Trick vor Jahren auf der Fun With Perl-Mailingliste ausgedacht. (Ich bin mir sicher, dass ich nicht der erste bin, der es entdeckt hat, aber ich habe es selbstständig (neu) erfunden.) Hier ist ein Link zum Originalbeitrag , einschließlich eines Beweises, dass es tatsächlich funktioniert.


Ich finde es wirklich ein bisschen albern, dass man mit golfscript genau die Lösung schreiben kann, die das OP ausschließen wollte, ohne die Regeln zu brechen.
Tim Seguine

1
@Tim: OK, hier ist eine ohne Dekremente. ;)
Ilmari Karonen

wie kann das gehen Zum Beispiel 7/3 = 2 (0010), also 7 & 2 = 0111 & 0010 = 0010was eindeutig das letzte Bit ist nicht 1
phuclv

@ LưuVĩnhPhúc: Nein, aber das zweite Bit ist. Wenn Sie versuchen, eine lange Division durch 3 im Binärformat durchzuführen, ist es ziemlich offensichtlich, warum dies immer dann der Fall ist, wenn für die Dividende mehr als ein Bit festgelegt ist.
Ilmari Karonen

ah ich verstehe dies mit "teilbar durch 2"
phuclv

15

APL (7)

Ja, das sind 7 Bytes . Nehmen wir für den Moment an, dass ich IBM Codepage 907 anstelle von Unicode verwende und dann jedes Zeichen ein Byte ist :)

0=1|2⍟⎕

dh 0 = mod(log(input(),2),1)


Ich frage mich nur, was passiert, wenn Sie 0 oder eine negative Zahl eingeben?
Aditsu

@Aditsu Ich weiß nicht, was Unendlich Mod 1 ist, aber es sollte auf keinen Fall Null sein.
Tim Seguine

1
@ TimSeguine Mathematica gibt mir, Indeterminatewenn ich das versuche.
LegionMammal978

7

GolfScript, 11 (für 1 (wahr) und 0 (falsch))

.,{2\?}%?0>

Lege die Zahl auf den Stapel und laufe dann.

GolfScript, 22 (für Ja / Nein)

.,{2\?}%?0>'Yes''No'if

Ich finde es toll, wie das Konvertieren von 1/ 0nach Yes/ Noso viel Code benötigt wie die Herausforderung selbst: D

Warnung: EXTREM ineffizient;) Bei Zahlen bis 10000 funktioniert es einwandfrei, aber sobald Sie diesen Wert erreicht haben, stellen Sie eine leichte Verzögerung fest.

Erläuterung:

  • .,: wird nzu n 0..n( .duplizieren, ,0..n Bereich)
  • {2\?}: hoch 2
  • %: map "Potenz von 2" über "0..n" so wird es n [1 2 4 8 16 ...]
  • ?0>: prüft, ob das Array die Zahl enthält (0 ist größer als Index)

1
1 Byte kürzer für Ja / Nein .,{2\?}%?0<'YesNo'3/=:; Ich denke auch, Sie betrügen, indem Sie nach "Die Zahl auf den Stapel legen" fragen. Sie sollten mit a beginnen ~.
Aditsu

1
Scheitert am 1., was 2 ^ 0 ist
Joachim Isaksson

6

Mathematica 28

Numerator[Input[]~Log~2]==1

Für ganzzahlige Potenzen von 2 ist der Zähler des Basis-2-Protokolls 1 (was bedeutet, dass das Protokoll ein Einheitenbruch ist).

Hier modifizieren wir die Funktion leicht, um die vermutete Eingabe anzuzeigen. Wir verwenden #anstelle von Input[]und addieren &, um eine reine Funktion zu definieren. Es wird dieselbe Antwort zurückgegeben, die zurückgegeben würde, wenn der Benutzer die Nummer in der obigen Funktion eingibt.

    Numerator[#~Log~2] == 1 &[1024]
    Numerator[#~Log~2] == 1 &[17]

Richtig
Falsch

Mehrere Nummern gleichzeitig testen.

    Numerator[#~Log~2] == 1 &&/@{64,8,7,0}

{Richtig, Richtig, Falsch, Falsch}


4

Perl 6 (17 Zeichen)

say get.log(2)%%1

Dieses Programm erhält eine Zeile von der STDIN- getFunktion, berechnet den Logarithmus mit der Basis 2 ( log(2)) und prüft, ob das Ergebnis durch 1 dividiert wird ( %%1wobei %%durch den Operator dividiert wird). Nicht so kurz wie die GolfScript-Lösung, aber ich finde das akzeptabel (GolfScript gewinnt sowieso alles), aber viel schneller (auch wenn man bedenkt, dass Perl 6 momentan langsam ist).

~ $ perl6 -e 'say get.log(2)%%1'
256
True
~ $ perl6 -e 'say get.log(2)%%1'
255
False

2
Der Grund, dass +und -für diese Herausforderung verboten sind, ist, weil wenn x & (x - 1)gleich ist 0, dann xist eine Potenz von 2.
ProgramFOX

@ProgramFOX: Ich verstehe. Interessanter Trick.
Konrad Borowski

1
@ProgramFOX Funktioniert aber x&~(~0*x)immer noch. Das sind nur 2 Zeichen länger.
Orlp

4

Oktave ( 15 23)

BEARBEITEN: Aktualisierung aufgrund von Benutzereingabeanforderungen;

~mod(log2(input('')),1)

Lässt den Benutzer einen Wert eingeben und gibt 1 für wahr, 0 für falsch aus.

Getestet in Octave, sollte auch in Matlab funktionieren.


Funktioniert auch in Matlab :)
jub0bs

4

R 13, 11

Basierend auf der Perl-Lösung. Rückgabe FALSEoder TRUE.

!log2(i)%%1

Der Parameter irepräsentiert die Eingangsvariable.

Eine alternative Version mit Benutzereingabe:

!log2(scan())%%1

4

GolfScript, 5

Ausgänge 1 für wahr, 0 für falsch. Basierend auf der Idee von user3142747:

~.(&!

Hinweis: Wird (dekrementiert, was hoffentlich nicht als -:) gilt.
Wenn dies der Fall ist (und die Kommentare des OP darauf hindeuten, dass dies der Fall sein könnte), beziehen Sie sich stattdessen auf die Lösung von Ilmari Karonen .
Fügen Sie für die J / N-Ausgabe 'NY'1/=am Ende (7 weitere Bytes) an.


4

Python, 31

print 3>bin(input()).rfind('1')

31 wenn Sie tunbin(input()).rfind('1')<3
Blender

@Blender Gut beschmutzt. Ich hatte verwendet, 2==weil ich dachte, dass es auch für nicht positive Zahlen funktionieren sollte. Das wird von den Regeln ausdrücklich nicht verlangt, also ...
Stand

1
+1. Ich wollte print bin(input()).count('1')<2insgesamt 31 Zeichen posten , aber es ist zu ähnlich wie bei Ihnen.
Steven Rumbalski

4

C 48

main(x){scanf("%i",&x);puts(x&~(x*~0)?"F":"T");}

Kann kürzer sein, wenn unary negate erlaubt ist, ist länger, wenn negative Konstanten nicht erlaubt sind. Nimmt das Zweierkomplement an.
Orlp

*hat eine höhere Priorität als binär &, du brauchst keine parens. Und wenn Rückgabewert akzeptiert wird (nur gefragt) exit(x&x*-1)wäre viel kürzer.
Kevin

Es gibt ein -: x*-1.
klingt.net

@ klingt.net ja, aber das ist Teil einer numerischen Konstante. Technisch ist, wie es jetzt formuliert ist, nur der Betreiber -verboten.
Kevin

1
@ klingt.net Ersetzt durch eine Version ohne Zeichen.
Orlp

4

Ich habe mich für einen anderen Ansatz entschieden, der auf der Anzahl der Einwohner oder der Seitwärtssumme der Zahl (der Anzahl der 1-Bits) basiert . Die Idee ist, dass alle Potenzen von zwei genau ein 1Bit haben und keine andere Zahl. Ich habe eine JavaScript-Version hinzugefügt, weil ich sie amüsant fand, obwohl sie mit Sicherheit keinen Golfwettbewerb gewinnen wird.

J, 14 15 Zeichen (Ausgänge 0 oder 1)

1=##~#:".1!:1]1

JavaScript, 76 Zeichen (gibt true oder false aus)

alert((~~prompt()).toString(2).split("").map(Number).filter(Boolean).length)

Hierfür wird eine Addition verwendet, die von der Herausforderung ausgeschlossen ist.
FUZxxl

Huh. Ich habe keine Ahnung, was ich gedacht habe, als ich das geschrieben habe ... Ich habe es jetzt behoben, damit es tatsächlich den Regeln folgt.
FireFly

4

Clip , 9 8 7

!%lnxWO

Liest eine Zahl von stdin.

Erläuterung:

Beginnen Sie mit, Z= 0, W= 2und O= 1. Dies ermöglicht die Platzierung von Wund Onebeneinander, während die Verwendung von 2und 1als Zahl 21 ohne Trennzeichen (ein unerwünschtes zusätzliches Zeichen) interpretiert wird. In Clip funktioniert die Modulo-Funktion ( %) mit Nicht-Ganzzahlen. Wenn Sie also herausfinden möchten, ob ein Wert veine Ganzzahl ist, überprüfen Sie, ob vMod 1 = 0 ist. Mit der Clip-Syntax wird dies wie folgt geschrieben =0%v1. Da Boolesche Werte jedoch als 1(oder als alles andere) gespeichert werden und 0überprüft wird, ob etwas gleich ist, 0wird es nur "nicht". Dafür hat Clip den !Operator. In meinem Code vist lnx2. xist eine Eingabe von stdin,nwandelt einen String in eine Zahl um und labist die Protokollbasis bvon a. Das Programm übersetzt daher (besser lesbar) nach 0 = ((log base 2 of parseInt(readLine)) mod 1).

Beispiele:

8

Ausgänge

1

und

10

Ausgänge

0

Edit 1: ersetzt 0, 1und 2mit Z, Ound W.

Edit 2: ersetzt =Zdurch !.

Ebenfalls:

Pyth , 5

Komprimiert die Clip-Version noch weiter, da Pyth Q für bereits ausgewertete Eingaben und eine log2 (a) -Funktion anstelle von nur allgemeinem log (a, b) hat.

!%lQ1

3

Javascript (37)

a=prompt();while(a>1)a/=2;alert(a==1)

Einfaches Skript, das nur wiederholt durch 2 dividiert und den Rest überprüft.


1
gleiche Idee mit einer forSchleife (auch 37 Zeichen)for(i=prompt();i>1;i/=2){}alert(i==1)
Math Chiller

3

Mathematica (21)

IntegerQ@Log2@Input[]

Ohne Eingabe ist es etwas kürzer

IntegerQ@Log2[8]

Wahr

IntegerQ@Log2[7]

Falsch


⌊#⌋==#&@Log2@Input[]
Alephalpha

1
@alephalpha Damit werden 24 Byte für die UTF-8-Zeichen verwendet. Ein weiteres 21-Byte-Programm ist Log2@Input[]~Mod~1==0.
LegionMammal978

2

JavaScript, 41 bis 40 Zeichen

l=Math.log;alert(l(prompt())/l(2)%1==0);

So funktioniert das: Sie nehmen den Logarithmus an der Basis 2 mit l(prompt()) / l(2), und wenn dieses Ergebnis Modulo 1 gleich Null ist, dann ist es eine Potenz von 2.

Zum Beispiel: Nachdem Sie den Logarithmus von 8 auf Basis genommen haben 2, erhalten Sie 3. 3 modulo 1ist gleich 0, dies gibt also true zurück.

Nachdem Sie den Logarithmus von 7 auf Basis 2 genommen haben, erhalten Sie 2.807354922057604. 2.807354922057604 modulo 1ist gleich 0.807354922057604, daher wird false zurückgegeben.


Sie müssen die Eingabe nicht in eine Zahl umwandeln. Math.logwird das schon tun : "Jede der folgenden Math-Objektfunktionen wendet den abstrakten Operator ToNumber auf jedes seiner Argumente an ..."
apsillers

Leidet es nicht an numerischen Ungenauigkeiten?
Mark Jeronimus

@ MarkJeronimus: Ich weiß es eigentlich nicht. Es könnte sein, aber ich habe noch kein falsches Ergebnis festgestellt.
ProgramFOX

2

JavaScript, 35

Funktioniert für Bytes.

alert((+prompt()).toString(2)%9==1)

46-stellige Version , funktioniert für 16-Bit-Nummern.

x=(+prompt()).toString(2)%99;alert(x==1|x==10)

Der Trick funktioniert in den meisten dynamischen Sprachen.

Erläuterung: Konvertieren Sie die Zahl in Basis 2, interpretieren Sie diese Zeichenfolge als Basis 10, und führen Sie Modulo 9 aus, um die Ziffernsumme zu erhalten, die 1 sein muss.


Was ist mit 0x2ff, was in Basis 2 ist 1111111111?
Peter Taylor

@PeterTaylor Du hast Recht, behoben
Kopie

so die reale Sache für Sie tun Modulo ist die Überprüfung 10 ohne Rest, aber man verwendet 9 ein Zeichen des Codes zu rasieren, +1!
Math Chiller

Dies ist ein bisschen Betrug, aber eine andere Methode:alert(!(Number.MAX_VALUE%prompt()))
Pluto


2

Python 3, 38

print(1==bin(int(input())).count('1'))

Python, 32

Der Code funktioniert jedoch nicht in jeder Version.

print 1==bin(input()).count('1')

Beachten Sie, dass die Lösung auch für 0 funktioniert (print False).


Aufgestimmt, weil das auch meine Lösung war.
Josh Caswell

1
Was passiert , wenn Sie ersetzen ==mit &?
SimonT

@ SimonT Dies ist nicht wahr. Wenn Sie '==' durch '&' ersetzen, wird 1 für jede Zahl ausgegeben, deren Binärdarstellung eine ungerade Zahl von '1' enthält. Überprüfen Sie zum Beispiel 7 = 111. Es gibt 3 = 11. Es wird 11 & 1 = 1 zurückgegeben.
Gari BN

2

Ruby - 17 Zeichen (vierter Versuch)

p /.1/!~'%b'%gets

Mein aktuelles Bestes ist eine Fusion von @steenslag's Antwort mit meiner eigenen. Nachfolgend sind meine bisherigen Versuche aufgeführt.

Ruby - 19 Zeichen (dritter Versuch)

p /10*1/!~'%b'%gets

Ruby - 22 Zeichen (zweiter Versuch)

p !('%b'%gets)[/10*1/]

Ruby - 24 Zeichen (erster Versuch)

p !!('%b'%gets=~/^10*$/)

Es gibt noch ein "+" in Ihrem Programm
phuclv

Ich kenne. : - / Ich habe um Klärung gebeten, ob '+' und '-' strengstens verboten sind oder ob sie in anderen Zusammenhängen als Addition und Subtraktion verwendet werden können. Ich bin dabei, es trotzdem umzuschreiben.
OI

Große Verbesserung. Es scheint das beste Ruby-Ergebnis zu sein, das es bisher gab. Ich habe die Führungstabelle im Fragentext aktualisiert.
gthacoder

@gthacoder Nur die Regex von steenslag mit meiner binären Formatierung kombiniert. Ich kann definitiv nicht alle Kredite aufnehmen.
OI

2

K / Kona ( 24 17)

d:{(+/(2_vs x))~1

Gibt 1 zurück, wenn wahr, und 0, wenn falsch. Jede Potenz von 2 hat ein einzelnes Bit gleich 1:

2_vs'_(2^'(!10))
(,1
1 0
1 0 0
1 0 0 0
1 0 0 0 0
1 0 0 0 0 0
1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0)

(dies gibt alle Potenzen von 2 (von 0 bis 9) in binärer Form aus)

Also fasse ich alle Komponenten des binären Ausdrucks von zusammen xund sehe, ob er gleich 1 ist. wenn ja dann x=2^n, sonst nein.

... wusste, ich könnte es kleiner machen


@gthacoder: Ich habe den Code verkleinert, hoffe, Sie können Ihren Hauptbeitrag aktualisieren, um dies widerzuspiegeln!
Kyle Kanos

Verwendet dies nicht zusätzlich? Und verbietet die Frage das nicht?
zgrep

2

C # (54 Zeichen)

 Math.Log(int.Parse(Console.ReadLine()),2)%1==0?"Y":"N"

Die Aufgabe stellt klar , dass die Eingabe nicht in einer Variablen gespeichert wird, soll es von einem Eingangsstrom von irgendeiner Art (wie stdin) erhalten werden, auch dies ist Code-Golf , versuchen Sie Ihren Code ein wenig zu verkürzen, zumindest durch ein Leerzeichen zu entfernen
Mittwoch,

Ich denke, Sie meinen nur Int32, nicht ToInt32...
Chris

Ya ya. Vielen Dank für den Hinweis auf Chris. Früher war es Convert.ToInt32 und ich wollte es in Int32.Parse ändern, um es zu verkürzen. : D
Merin Nakarmi

2
Verwenden Sie intstatt Int32für 2 weniger Zeichen.
Rik

2

Rebmu (9 Zeichen)

z?MOl2A 1

Prüfung

>> rebmu/args [z?MOl2A 1] 7
== false

>> rebmu/args [z?MOl2A 1] 8 
== true

>> rebmu/args [z?MOl2A 1] 9 
== false

Rebmu ist ein verengter Dialekt von Rebol. Der Code ist im Wesentlichen:

z? mo l2 a 1  ; zero? mod log-2 input 1

Alternative

14 Zeichen - Rebmu hat kein bitweises "Mushed" AND ~

z?AND~aTIddA 3

In Rebol:

zero? a & to-integer a / 3


1

Python, 35

print bin(input()).strip('0')=='b1'

Verwendet nicht nur +/- Operationen, sondern auch mathematische Operationen, abgesehen von der Konvertierung in die Binärform.

Andere Sachen (interessant, aber nicht für den Wettbewerb):

Ich habe auch eine reguläre Version (61) :

import re;print re.match(r'^0b10+$',bin(input())) is not None

(Liebe die Idee, aber Import- und Match-Funktion machen es zu lang)

Und schöne, aber langweilige bitweise Operationen Version (31) :

x=input();print x and not x&~-x

(Ja, es ist kürzer, aber es verwendet ~ -x für die Dekrementierung der Operation)


Die Antworten von boothby verwenden die gleiche Idee wie meine erste, sind aber kürzer :(
Ivan Anishchuk

1

Python 2.7 ( 30 29 39 37)

BEARBEITEN: Aktualisierung aufgrund von Benutzereingabeanforderungen;

a=input()
while a>1:a/=2.
print a==1

Brute Force, versuchen Sie zu teilen, bis = 1 (Erfolg) oder <1 (Misserfolg)


1
not a%2kann geschrieben werden als a%2==0. Zugegeben, dies wäre in vielen Sprachen länger, aber nicht in Python.
Konrad Borowski

@ xfix Danke, getestet und aktualisiert.
Joachim Isaksson

1
oder noch besser a%2<1.
Stand

Sie haben ein Leerzeichen nach dem 2.Entfernen, das ein Byte sparen würde!
Keerthana Prabhakaran

1

Python (33)

print int(bin(input())[3:]or 0)<1

int(bin(input()*2)[3:])<1funktioniert auch aus der Python-Shell mit nur 25 Zeichen.
Gmatht


1

APL (12 für 0/1, 27 für Ja / Nein)

≠/A=2*0,ιA←⍞ 

oder, wenn wir Text ausgeben müssen:

3↑(3x≠/A=2*0,ιA←⍞)↓'YESNO '

Lesen Sie A ein. Bilden Sie einen Vektor 0..A, dann einen Vektor 2 0 ..2 A (ja, das ist weit mehr als nötig), dann einen Vektor, der A mit jedem dieser Vektoren vergleicht (was zu einem Vektor von 0 und höchstens 0 führt) one 1), dann xor that (es gibt keinen xor-Operator in APL, aber ≠, das auf Boolesche Werte angewendet wird, fungiert als eins.) Wir haben jetzt 0 oder 1.

Um JA oder NEIN zu erhalten: Multiplizieren Sie die 0 oder 1 mit 3, entfernen Sie diese Anzahl von Zeichen von 'JA' und nehmen Sie die ersten 3 Zeichen davon.


1

C 65 Bytes

main(k){scanf("%i",&k);while(k&&!(k%2))k/=2;puts(k==1?"T":"F");}

Sie können mit 5 Zeichen abschneiden main(k){..., wobei Sie sich auf die implizite intEingabe verlassen. Es könnte UB sein, aber das ist Code Golf. Natürlich NIEMALS so etwas in der Produktion verwenden.
Kevin

1

Haskell ( 52 50)

k n=elem n$map(2^)[1..n]
main=interact$show.k.read
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.