Sprawdź, czy liczba całkowita jest potęgą 2, bez użycia operacji +, - [zamknięte]

30

Napisz program, który sprawdzi, czy liczba całkowita jest potęgą 2.


Przykładowe dane wejściowe:

8

Przykładowe dane wyjściowe:

Yes

Przykładowe dane wejściowe:

10

Przykładowe dane wyjściowe:

No

Zasady:

  • Nie używać +, -operacje.

  • Użyj jakiegoś strumienia wejściowego, aby uzyskać liczbę. Dane wejściowe nie powinny być początkowo przechowywane w zmiennej.

  • Najkrótszy kod (w bajtach) wygrywa.

Możesz użyć dowolnej odpowiedzi typu prawda / fałsz (na przykład true/ false). Możesz założyć, że liczba wejściowa jest większa niż 0.

gthacoder
źródło
1
Czy można również wypisywać „prawda” zamiast „tak” i „fałsz” zamiast „nie”?
ProgramFOX
2
Tak, możesz użyć dowolnej pozytywnej / negatywnej odpowiedzi. Pytanie zostało zaktualizowane.
gthacoder
1
predFunkcyjne, gdy stosuje się do liczby całkowitej N, N - 1. powraca to funkcje, takie jak to, które są cienkie, stroje około zakazanego operatora, zakazano?
Wayne Conrad
1
@Wayne, podobnie jak golfscript ), lub większość języków opartych na języku c ” --.
Klamka
2
Wiem, że mamy za 3 lata, ale „+/- operatorów” nie da się zaobserwować, a przynajmniej słabo zdefiniować.
ATaco

Odpowiedzi:

13

GolfScript, 6 znaków, bez dekrecji

~.3/&!

Oto rozwiązanie, które nie wykorzystuje tej x & (x-1)metody w żadnej formie. x & (x/3)Zamiast tego używa . ;-) Wypisuje wartość 0false, 1jeśli true.

Wyjaśnienie:

  • ~ analizuje ciąg wejściowy, aby przekształcić go w liczbę,
  • .powiela to (dla następnych &),
  • 3/ dzieli to przez trzy (obcięcie),
  • & oblicza bitowe ORAZ podzielonej wartości z oryginałem, który będzie wynosił zero wtedy i tylko wtedy, gdy wejście będzie równe zero lub potęgi dwóch (tj. będzie ustawiony najwyżej jeden bit), i
  • ! logicznie to neguje, odwzorowując zero na jedną i wszystkie inne wartości na zero.

Uwagi:

  • Zgodnie z objaśnionymi regułami zero nie jest prawidłowym wejściem , więc ten kod jest OK, nawet jeśli wyprowadza, 1jeśli wejście jest zerowe.

  • Jeśli operator dekrementacji GolfScript (jest dozwolony, wystarczy 5-znakowe rozwiązanie ~.(&! opublikowane przez aditsu . Jednak wydaje się to sprzeczne z duchem zasad , jeśli nie z literą.

  • x & (x/3)Kilka lat temu wpadłem na tę sztuczkę na liście dyskusyjnej Fun With Perl. (Jestem pewien, że nie jestem pierwszym, który to odkrył, ale samodzielnie go wymyśliłem.) Oto link do oryginalnego postu , w tym dowód, że faktycznie działa.

Ilmari Karonen
źródło
Myślę, że to trochę głupie, golfscript pozwala napisać dokładne rozwiązanie, które OP chciał wykluczyć, nie naruszając przy tym reguł.
Tim Seguine
1
@Tim: OK, oto jeden bez dekrecji. ;)
Ilmari Karonen
jak to może działać Na przykład 7/3 = 2 (0010), więc 7 & 2 = 0111 & 0010 = 0010który wyraźnie ostatni bit nie jest 1
phuclv
@ LưuVĩnhPhúc: Nie, ale drugi bit to. Spróbuj wykonać długi podział przez 3 w systemie binarnym i jest całkiem oczywiste, dlaczego tak się zawsze dzieje, jeśli dywidenda ma ustawiony więcej niż jeden bit.
Ilmari Karonen
ah
Źle
15

APL (7)

Tak, to 7 bajtów . Załóżmy na chwilę, że używam strony kodowej IBM 907 zamiast Unicode, a następnie każdy znak jest bajtem :)

0=1|2⍟⎕

to znaczy 0 = mod(log(input(),2),1)

marinus
źródło
Zastanawiam się, co się stanie, jeśli podasz 0 lub liczbę ujemną?
aditsu
@aditsu Nie wiem, co to jest nieskończoność mod 1, ale na pewno nie powinno być zero.
Tim Seguine
1
@TimSeguine Mathematica daje mi, Indeterminategdy próbuję tego.
LegionMammal978
7

GolfScript, 11 (dla 1 (prawda) i 0 (fałsz))

.,{2\?}%?0>

Umieść liczbę na stosie, a następnie uruchom.

GolfScript, 22 (dla Tak / Nie)

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

Uwielbiam, jak konwersja 1/ 0do Yes/ Nozajmuje tyle samo kodu, co samo wyzwanie: D

Ostrzeżenie: NIEZWYKLE nieefektywne;) Działa dobrze dla liczb do 10000, ale gdy osiągniesz tak wysoki poziom, zaczniesz zauważać niewielkie opóźnienie.

Wyjaśnienie:

  • .,: zmienia się nw n 0..n( .duplikat, ,zakres 0..n)
  • {2\?}: do potęgi 2
  • %: mapuje „potęgę 2” na „0..n”, więc staje się n [1 2 4 8 16 ...]
  • ?0>: sprawdza, czy tablica zawiera liczbę (0 jest większe niż indeks)
Klamka
źródło
1
1 bajt krótszy dla Tak / Nie .,{2\?}%?0<'YesNo'3/=:; również myślę, że oszukujesz, prosząc o „Umieść liczbę na stosie”, powinieneś zacząć od ~.
aditsu
1
Nie odpowiada 1, czyli 2 ^ 0
Joachim Isaksson
6

Mathematica 28

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

Dla liczb całkowitych 2, licznikiem logarytmu podstawowego 2 będzie 1 (co oznacza, że ​​log jest ułamkiem jednostkowym).

Tutaj nieznacznie modyfikujemy funkcję, aby wyświetlić przypuszczalne wejście. Używamy #zamiast Input[]i dodajemy, &aby zdefiniować czystą funkcję. Zwraca tę samą odpowiedź, która zostałaby zwrócona, gdyby użytkownik wprowadził numer w powyższej funkcji.

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

Prawda
Fałsz

Testowanie kilku liczb jednocześnie.

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

{Prawda, prawda, fałsz, fałsz}

DavidC
źródło
4

Perl 6 (17 znaków)

say get.log(2)%%1

Ten program pobiera wiersz z getfunkcji STDIN , oblicza logarytm z podstawą 2 na nim ( log(2)) i sprawdza, czy wynik dzieli przez 1 ( %%1, gdzie %%jest dzielony przez operatora). Nie tak krótkie jak rozwiązanie GolfScript, ale uważam to za dopuszczalne (GolfScript i tak wygrywa wszystko i tak), ale o wiele szybciej (nawet biorąc pod uwagę, że Perl 6 jest teraz wolny).

~ $ perl6 -e 'say get.log(2)%%1'
256
True
~ $ perl6 -e 'say get.log(2)%%1'
255
False
Konrad Borowski
źródło
2
Dlatego, że +i -są zabronione na to wyzwanie, dlatego jeśli x & (x - 1)jest równa 0, to xjest potęgą 2.
ProgramFOX
@ProgramFOX: Rozumiem. Ciekawa sztuczka.
Konrad Borowski
1
@ProgramFOX Ale x&~(~0*x)nadal działa. To tylko 2 znaki dłużej.
orlp
4

Oktawa ( 15 23)

EDYCJA: Zaktualizowano ze względu na wymagania użytkownika;

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

Pozwala użytkownikowi wprowadzić wartość i wyprowadza 1 dla wartości true, 0 dla wartości false.

Testowany w Octave, powinien również działać w Matlabie.

Joachim Isaksson
źródło
Działa również w Matlabie :)
jub0bs
4

R 13 13

Na podstawie rozwiązania Perla. Zwraca FALSElub TRUE.

!log2(i)%%1

Ten parametr ireprezentuje zmienną wejściową.

Alternatywna wersja z wejściem użytkownika:

!log2(scan())%%1
Sven Hohenstein
źródło
4

GolfScript, 5

Wyjścia 1 dla wartości true, 0 dla wartości false. Oparty na pomyśle user3142747:

~.(&!

Uwaga: (jest zmniejszeniem, miejmy nadzieję, że nie liczy się jako -:)
Jeśli tak (a komentarze OP sugerują, że może), to zamiast tego zapoznaj się z rozwiązaniem Ilmari Karonen .
W przypadku danych wyjściowych Y / N dołącz 'NY'1/=na końcu (7 kolejnych bajtów).

aditsu
źródło
4

Python, 31

print 3>bin(input()).rfind('1')
boothby
źródło
31 jeśli to zrobiszbin(input()).rfind('1')<3
Blender
@Blender Dobrze zauważony. Użyłem, 2==ponieważ uznałem, że powinien on również działać dla liczb niepozytywnych. Nie jest to wyraźnie wymagane przez zasady, więc ...
stoisko
1
+1. Zamierzałem napisać print bin(input()).count('1')<2w sumie 31 znaków, ale jest zbyt podobny do twojego.
Steven Rumbalski
4

C, 48

main(x){scanf("%i",&x);puts(x&~(x*~0)?"F":"T");}
orlp
źródło
Może być krótszy, jeśli dozwolone jest jednostronne negowanie, jest dłuższy, jeśli stałe ujemne nie są dozwolone. Zakłada uzupełnienie dwóch.
orlp
*ma wyższy priorytet niż binarny &, nie potrzebujesz parenów. A jeśli wartość zwrotu zostanie zaakceptowana (tylko zapytana), exit(x&x*-1)byłaby znacznie krótsza.
Kevin
Jest -: x*-1.
klingt.net
@ klingt.net tak, ale to część stałej liczbowej. Technicznie, jak to jest teraz sformułowane, -zabroniony jest tylko operator .
Kevin
1
@ klingt.net Zastąpił go wersją, która nie używa znaków.
orlp
4

Zdecydowałem się zastosować inne podejście, oparte na liczbie ludności lub na bokach sumy liczby (liczby 1-bitów). Chodzi o to, że wszystkie potęgi dwóch mają dokładnie jeden 1bit, a żadna inna liczba nie. Dodałem wersję JavaScript, ponieważ uważam ją za zabawną, choć na pewno nie wygra żadnej gry w golfa.

J, 14 15 znaków (wyjścia 0 lub 1)

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

JavaScript, 76 znaków (wyniki prawda lub fałsz)

alert((~~prompt()).toString(2).split("").map(Number).filter(Boolean).length)
Robaczek świętojański
źródło
Wykorzystuje to dodawanie, które jest wykluczone przez wyzwanie.
FUZxxl
Huh Nie mam pojęcia, o czym myślałem, kiedy to napisałem ... Naprawiłem to teraz, aby właściwie postępowało zgodnie z zasadami.
FireFly,
4

Klips , 9 8 7

!%lnxWO

Czyta liczbę ze standardowego wejścia.

Wyjaśnienie:

Na początek, Z= 0, W= 2i O= 1. Pozwala to na umieszczanie Wi Oobok siebie, natomiast użycie 2i 1byłoby interpretowane jako liczba 21 bez spacji (niepożądany dodatkowy znak). W Clip funkcja modulo ( %) działa na liczbach niecałkowitych, więc aby sprawdzić, czy jakaś wartość vjest liczbą całkowitą, sprawdź, czy vmod 1 = 0. Za pomocą składni Clipa zapisuje się to jako =0%v1. Jednakże, ponieważ booleany są przechowywane jako 1(lub cokolwiek innego) i 0sprawdzenie, czy coś jest równe, 0to po prostu „nie” to. W tym celu Clip ma !operatora. W moim kodzie vjest lnx2. xjest wejściem ze stdin,nkonwertuje ciąg znaków na liczbę i labjest podstawa log bz a. Dlatego program tłumaczy (bardziej czytelnie) na 0 = ((log base 2 of parseInt(readLine)) mod 1).

Przykłady:

8

wyjścia

1

i

10

wyjścia

0

Edit 1: zastąpić 0, 1i 2z Z, Oi W.

Edycja 2: zastąpiona =Zprzez !.

Również:

Pyth , 5

Kompresuje wersję Clip jeszcze bardziej, ponieważ Pyth ma Q dla już ocenionego wejścia i funkcję log2 (a) zamiast zwykłego dziennika (a, b).

!%lQ1
bcsb1001
źródło
3

JavaScript (37)

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

Prosty skrypt, który dzieli tylko kilka razy i sprawdza resztę.

Joachim Isaksson
źródło
1
ten sam pomysł z forpętlą (także 37 znaków)for(i=prompt();i>1;i/=2){}alert(i==1)
agregat matematyczny
3

Matematyka (21)

IntegerQ@Log2@Input[]

Bez danych wejściowych jest nieco krótszy

IntegerQ@Log2[8]

Prawdziwe

IntegerQ@Log2[7]

Fałszywe

Ybeltukov
źródło
⌊#⌋==#&@Log2@Input[]
alephalpha
1
@alephalpha To kończy się na 24 bajtach dla znaków UTF-8. Kolejny 21-bajtowy program to Log2@Input[]~Mod~1==0.
LegionMammal978
2

JavaScript, 41 40 znaków

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

Jak to działa: bierzesz logarytm z podstawy 2 za pomocą l(prompt()) / l(2), a jeśli ten wynik modulo 1 jest równy zero, to jest to potęga 2.

Na przykład: po przyjęciu logarytmu 8 na podstawie 2dostajesz 3. 3 modulo 1jest równe 0, więc zwraca true.

Po przyjęciu logarytmu 7 na podstawie 2 otrzymujesz 2.807354922057604. 2.807354922057604 modulo 1jest równa 0.807354922057604, więc zwraca false.

ProgramFOX
źródło
Nie musisz rzutować danych wejściowych na liczbę; Math.logzrobi to już : „Każda z następujących funkcji obiektów matematycznych stosuje operator abstrakcyjny ToNumber do każdego z argumentów ...”
apsillers
Czy to nie cierpi na niedokładności liczbowe?
Mark Jeronimus
@MarkJeronimus: Właściwie to nie wiem. Być może, ale nie napotkałem jeszcze niepoprawnego wyniku.
ProgramFOX
2

JavaScript, 35

Działa dla bajtów.

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

Wersja 46 znaków , Działa dla liczb 16-bitowych.

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

Sztuczka działa w najbardziej dynamicznych językach.

Objaśnienie: Konwertuj liczbę na bazę 2, zinterpretuj ten ciąg jako bazę 10, wykonaj modulo 9, aby uzyskać sumę cyfr, która musi wynosić 1.

Kopiuj
źródło
A 0x2ffco z bazą 2 1111111111?
Peter Taylor
@PeterTaylor Masz rację, naprawiono
skopiuj
więc tak naprawdę to robisz, sprawdzając modulo 10 bez reszty, ale użyłeś 9, aby ogolić znak swojego kodu +1,!
Agregat matematyczny
To trochę oszustwo, ale inna metoda:alert(!(Number.MAX_VALUE%prompt()))
Pluton
2

python 3, 38

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

python, 32

Jednak kod nie działa w każdej wersji.

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

Zauważ, że rozwiązanie działa również dla 0 (drukuj False).

Gari BN
źródło
Głosowałem, ponieważ to również było moje rozwiązanie.
Josh Caswell
1
Co zrobić, jeśli zastąpi ==się &?
SimonT
@ SimonT To nie jest prawda. Zastąpienie „==” przez „&” spowoduje wydrukowanie 1 dla każdej liczby, która ma nieparzystą liczbę „1” w swojej reprezentacji binarnej. Sprawdź na przykład 7 = 111. Są 3 = 11. Zwróci 11 i 1 = 1.
Gari BN
2

Ruby - 17 znaków (czwarta próba)

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

Moim obecnym najlepszym jest połączenie odpowiedzi @ steenslag z moją własną. Poniżej znajdują się moje poprzednie próby.

Ruby - 19 znaków (trzecia próba)

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

Rubin - 22 znaków (druga próba)

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

Ruby - 24 znaki (pierwsza próba)

p !!('%b'%gets=~/^10*$/)
OI
źródło
W twoim programie jest jeszcze „+”
phuclv
Wiem. : - / Poprosiłem o wyjaśnienie, czy „+” i „-” są surowo zabronione, czy też można ich używać w innych kontekstach oprócz dodawania i odejmowania. Niezależnie od tego jestem w trakcie przepisywania.
OI
Wielka poprawa. Wygląda na to, że jest to najlepszy jak dotąd wynik Ruby. Zaktualizowałem tabelę liderów w tekście pytania.
gthacoder
@gthacoder Właśnie połączyłem wyrażenie regularne steenslag z moim formatowaniem binarnym. Zdecydowanie nie mogę wziąć całego uznania.
OI
2

K / Kona ( 24 17)

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

Zwraca 1, jeśli prawda, i 0, jeśli fałsz. Każda moc 2 ma pojedynczy bit równy 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)

(to wypisuje wszystkie potęgi 2 (od 0 do 9) binarnie)

Podsumowuję więc wszystkie składniki wyrażenia binarnego xi sprawdzam, czy jest ono równe 1; jeśli tak x=2^n, to w przeciwnym razie nie.

... wiedziałem, że mogę to zmniejszyć

Kyle Kanos
źródło
@gthacoder: Zmniejszyłem kod, mam nadzieję, że możesz zaktualizować swój główny post, aby to odzwierciedlić!
Kyle Kanos
Czy to nie używa dodatku? I czy to pytanie nie jest zabronione?
zgrep
2

C # (54 znaki)

 Math.Log(int.Parse(Console.ReadLine()),2)%1==0?"Y":"N"
Merin Nakarmi
źródło
Zadanie wyraźnie stwierdza, że ​​dane wejściowe nie są przechowywane w zmiennej, należy je uzyskać ze strumienia wejściowego pewnego rodzaju (np. Stdin), to także jest golf-golf , spróbuj nieco skrócić swój kod, przynajmniej usuwając białe znaki
mniip
Myślę, że masz na myśli Int32, a nie ToInt32...
Chris
Tak Dzięki za zwrócenie uwagi na Chrisa. Wcześniej był to Convert.ToInt32 i chciałem go zmienić na Int32.Parse, aby go skrócić. : D
Merin Nakarmi
2
użyj intzamiast o Int322 mniej znaków.
Rik
2

Rebmu (9 znaków)

z?MOl2A 1

Test

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

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

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

Rebmu jest zwężonym dialektem Rebola. Kod jest zasadniczo:

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

Alternatywny

14 znaków - Rebmu nie ma „mushed” bitowego AND ~

z?AND~aTIddA 3

W Rebol:

zero? a & to-integer a / 3
rgchris
źródło
1

GTB , 46 bajtów

2→P`N[@N=Pg;1P^2→P@P>1E90g;2]l;2~"NO"&l;1"YES"
Timtech
źródło
1

Python, 35

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

Nie używa nie tylko operacji +/-, ale również operacji matematycznych oprócz konwersji do postaci binarnej.

Inne rzeczy (ciekawe, ale nie dla konkurencji):

Mam również wersję wyrażenia regularnego (61) :

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

(Podoba mi się ten pomysł, ale funkcja importu i dopasowania powoduje, że jest za długi)

I ładna, ale nudna wersja operacji bitowych (31) :

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

(tak, jest krótszy, ale używa ~ -x do zmniejszenia, co zawiera - operacja)

Ivan Anishchuk
źródło
Odpowiedzi boothby wykorzystują ten sam pomysł, co mój pierwszy, ale jest krótszy :(
Ivan Anishchuk
1

Python 2.7 ( 30 29 39 37)

EDYCJA: Zaktualizowano ze względu na wymagania użytkownika;

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

Brutalna siła, spróbuj podzielić, aż = 1 (sukces) lub <1 (niepowodzenie)

Joachim Isaksson
źródło
1
not a%2można zapisać jako a%2==0. To prawda, że ​​byłoby to dłużej w wielu językach, ale nie w Pythonie.
Konrad Borowski
@xfix Dzięki, przetestowane i zaktualizowane.
Joachim Isaksson
1
lub nawet lepiej a%2<1.
stoisko
po 2.usunięciu masz spację , która oszczędziłaby bajt!
Keerthana Prabhakaran
1

Python (33)

print int(bin(input())[3:]or 0)<1
Mikser
źródło
int(bin(input()*2)[3:])<1działa również z powłoki pytona z tylko 25 znakami.
gmatht
1

Ruby, 33 , 28 , 25

p /.1/!~gets.to_i.to_s(2)
steenslag
źródło
1

APL (12 dla 0/1, 27 dla tak / nie)

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

lub, jeśli musimy wyprowadzić tekst:

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

Wczytaj A. Utwórz wektor 0..A, a następnie wektor 2 0 .2 A. (tak, to bardziej niż to konieczne), a następnie wektorem porównywania każdego z tych (w wyniku tworząc wektor 0 i co najwyżej jeden 1), a następnie xor że (w APL nie ma operatora xor, ale ≠ zastosowane do boolanów będzie działać jak jeden). Mamy teraz 0 lub 1.

Aby uzyskać TAK lub NIE: pomnóż 0 lub 1 przez 3, upuść tę liczbę znaków z „TAK”, a następnie weź pierwsze 3 znaki.

Mark Plotnick
źródło
1

C, 65 bajtów

main(k){scanf("%i",&k);while(k&&!(k%2))k/=2;puts(k==1?"T":"F");}
vershov
źródło
Możesz odciąć 5 znaków przy użyciu main(k){..., polegając na niejawnym intpisaniu. Może to być UB, ale to jest golf golfowy. Oczywiście NIGDY nie używaj czegoś takiego w produkcji.
Kevin
1

Haskell ( 52 50)

k n=elem n$map(2^)[1..n]
main=interact$show.k.read
Zeta
źródło