Перевірте, чи ціле число є потужністю 2, не використовуючи операцій +, - [закрито]


30

Напишіть програму, яка перевіряє, чи є ціле число 2.


Зразок введення:

8

Вибірка зразка:

Yes

Зразок введення:

10

Вибірка зразка:

No

Правила:

  • Не використовуйте +, -операції.

  • Використовуйте якийсь потік введення, щоб отримати число. Вхід не повинен спочатку зберігатися у змінній.

  • Виграє найкоротший код (у байтах).

Ви можете використовувати будь-яку правдиву / хибну відповідь (наприклад, true/ false). Ви можете припустити, що число введення більше, ніж 0.


1
Чи дозволено також виводити "true" замість "так" і "false" замість "ні"?
ProgramFOX

2
Так, ви можете використовувати будь-яку позитивну / негативну відповідь. Питання оновлено.
gthacoder

1
predФункція, коли застосовується до цілого числа п, п - повертає 1. Існують такі функції, як це, які є тонкими маскує навколо забороненого оператора, також заборонено?
Уейн Конрад

1
@Wayne так само, як гольфскрипт ), або більшість мов на базі c ' --.
Дверна ручка

2
Я знаю, що зараз у нас 3 роки, але "+/- оператори" не спостерігаються або, принаймні, слабо визначені.
Атако

Відповіді:


13

GolfScript, 6 символів, без декрементів

~.3/&!

Ось рішення, яке не використовує x & (x-1)метод у будь-якій формі. Він використовує x & (x/3)замість цього. ;-) Виводить 0якщо false, 1якщо true.

Пояснення:

  • ~ оцінює вхідний рядок, щоб перетворити його на число,
  • .дублює його (для подальшого &),
  • 3/ ділить його на три (обрізаючи вниз),
  • & обчислює побітове І розділеного значення з оригіналом, яке буде нульовим тоді і тільки тоді, коли вхід дорівнює нулю або потужність два (тобто має максимум один біт), і
  • ! логічно це заперечує, зіставляючи нуль до одного, а всі інші значення - до нуля.

Примітки:

  • Згідно з уточненими правилами, нуль не є дійсним вводом , тому цей код є нормальним, навіть якщо він видає, 1якщо вхід дорівнює нулю.

  • Якщо дозволений оператор декларації GolfScript (, то 5-символьного рішення, ~.(&! розміщеного aditsu , достатньо. Однак, схоже, це суперечить духу правил , якщо не літера.

  • Я вигадав x & (x/3)трюк років тому у списку розсилки Fun With Perl. (Я впевнений, що я не перший виявив це, але я (пере) вигадав його самостійно.) Ось посилання на оригінальний пост , включаючи доказ того, що він насправді працює.


Я думаю, що це справді трохи нерозумно, golfscript дозволяє написати точне рішення, яке ОП хотіла виключити, фактично не порушуючи правила.
Тім Сегуїн

1
@Tim: Гаразд, ось один без декрементів, значить. ;)
Ільмарі Каронен

як це може працювати? Наприклад 7/3 = 2 (0010), так 7 & 2 = 0111 & 0010 = 0010що явно останній біт не 1
phuclv

@ LưuVĩnhPhúc: Ні, але другий біт є. Спробуйте зробити тривалий поділ на 3 у двійкових, і цілком очевидно, чому це завжди відбувається, якщо в дивіденді встановлено більше одного біта.
Ільмарі Каронен

ах я це неправильно
прочитав

15

APL (7)

Так, це 7 байт . Припустимо на даний момент, що я використовую кодову сторінку IBM 907 замість Unicode, і тоді кожен символ є байтом :)

0=1|2⍟⎕

тобто 0 = mod(log(input(),2),1)


Цікаво, що станеться, якщо ви дасте 0 або від’ємне число?
aditsu

@aditsu Я не знаю, що таке нескінченність mod 1, але це, звичайно, не повинно бути нулем.
Тім Сегуїн

1
@TimSeguine Mathematica дає мені, Indeterminateколи я спробую це.
LegionMammal978

7

GolfScript, 11 (для 1 (вірно) та 0 (помилково))

.,{2\?}%?0>

Поставте число в стек і потім запустіть.

GolfScript, 22 (для Так / Ні)

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

Мені подобається, як перетворення 1/ 0на Yes/ Noприймає стільки коду, скільки й виклик: D

Попередження: НАЙКРАЙНО неефективний;) Він працює чудово для цифр до 10000, але як тільки ви досягнете такої висоти, ви починаєте помічати незначне відставання.

Пояснення:

  • .,: перетворюється nна n 0..n( .дублікат, ,діапазон 0..n)
  • {2\?}: до сили 2
  • %: карта "потужність 2" над "0..n", так це стає n [1 2 4 8 16 ...]
  • ?0>: перевіряє, чи містить масив число (0 більше, ніж індекс)

1
1 байт коротше для Так / Ні .,{2\?}%?0<'YesNo'3/=:; Також я думаю, що ви обманюєте, попросивши "Покласти число в стек", ви повинні почати з а ~.
aditsu

1
Збій на 1, що становить 2 ^ 0
Йоахім Ісакссон

6

Математика 28

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

Для цілих потужностей 2 чисельник журналу основи 2 буде дорівнює 1 (означає, що журнал - це одинична частка).

Тут ми трохи модифікуємо функцію для відображення передбачуваного вводу. Ми використовуємо #замість Input[]та додаємо &для визначення чистої функції. Він повертає ту саму відповідь, яку буде повернуто, якщо користувач введе номер у вищевказаній функції.

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

Справжня
хибність

Тестування декількох цифр одночасно.

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

{Правда, правда, помилково, хибно}


4

Perl 6 (17 символів)

say get.log(2)%%1

Ця програма отримує рядок від getфункції STDIN , обчислює логарифм з базою 2 на ньому ( log(2)) і перевіряє, чи результат ділиться на 1 ( %%1, де %%ділиться оператором). Не таке коротке, як рішення GolfScript, але я вважаю це прийнятним (у будь-якому випадку GolfScript все виграє), але набагато швидше (навіть враховуючи, що Perl 6 зараз повільний).

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

2
Причина, яка +і -заборонена для цього виклику, полягає в тому, що якщо x & (x - 1)дорівнює 0, то xце сила 2.
ProgramFOX

@ProgramFOX: Бачу. Цікава хитрість.
Конрад Боровський

1
@ProgramFOX Але x&~(~0*x)все одно працює. Це лише на 2 символи довше.
orlp

4

Октава ( 15 23)

EDIT: оновлено через потреби введення користувача;

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

Дозволяє користувачеві вводити значення і виводить 1 для true, 0 для false.

Випробуваний в Octave, також повинен працювати в Matlab.


Працює в Matlab також :)
jub0bs

4

R, 13 11

На основі рішення Perl. Повертається FALSEабо TRUE.

!log2(i)%%1

Параметр iпредставляє вхідну змінну.

Альтернативна версія з введенням користувача:

!log2(scan())%%1

4

GolfScript, 5

Виходи 1 для істинного, 0 для хибного. На основі ідеї користувача3142747:

~.(&!

Примітка: (декрет, сподіваємось, він не вважається таким, як -:)
Якщо це так (а коментарі ОП припускають, що це може бути), тоді, будь ласка, зверніться до рішення Ілмарі Каронен .
Для виводу Y / N додайте 'NY'1/=в кінці (ще 7 байт).


4

Пітона, 31

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

31 якщо виbin(input()).rfind('1')<3
Блендер

@Blender Добре помічений. Я використовував, 2==тому що я вважав, що це має працювати і для непозитивних чисел. Це явно не вимагається правилами, тому ...
кабінка

1
+1. Я збирався публікувати print bin(input()).count('1')<2в загальній кількості 31 персонаж, але це занадто схоже на ваше.
Стівен Румбальський

4

С, 48

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

Може бути коротшим, якщо дозволено нерівномірне заперечення, довше, якщо заборонені константи заборонені. Передбачає доповнення двох.
orlp

*має вищий пріоритет, ніж бінарний &, вам не потрібні парони. І якщо значення повернення буде прийнято (тільки запитували), exit(x&x*-1)було б набагато коротше.
Кевін

Існує -: x*-1.
klingt.net

@ klingt.net так, але це частина числової константи. Технічно, як сказано зараз, -заборонено лише оператор .
Кевін

1
@ klingt.net Замінив його версією, яка не використовує жодних знаків.
orlp

4

Я вирішив використати інший підхід, заснований на підрахунку чисельності чи вбік суми числа (кількість 1-біт). Ідея полягає в тому, що всі сили двох мають рівно один 1біт, а жодне інше число не має. Я додав версію JavaScript, тому що вважаю це забавним, хоча він, безумовно, не виграє жодного змагання з гольфу.

J, 14 15 символів (виходи 0 або 1)

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

JavaScript, 76 символів (виводить true або false)

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

Для цього використовується доповнення, яке виключається викликом.
FUZxxl

Ага. Я поняття не маю, про що я думав, коли писав це ... Я це виправив зараз, щоб він насправді відповідав правилам.
FireFly

4

Кліп , 9 8 7

!%lnxWO

Читає число від stdin.

Пояснення:

Для початку, Z= 0, W= 2і O= 1. Це дозволяє розміщувати Wта Oпоруч один з одним, тоді як використання 2та 1інтерпретація буде як число 21 без роздільного простору (небажаний додатковий символ). У Clip, функція modulo ( %) працює на не цілі числа, тож, щоб обробити, чи є якесь значення vцілим числом, ви перевіряєте, чи vmod 1 = 0. Використовуючи синтаксис Clip, це записується як =0%v1. Однак, оскільки булеві файли зберігаються як 1(або що-небудь інше), і 0перевірити, чи щось дорівнює, 0це просто "не робити" цього. Для цього Clip має !оператора. У моєму коді vє lnx2. xце вхід від stdin,nперетворює рядок в число і labє лог бази bз a. Тому програма перекладається (більш читається) на 0 = ((log base 2 of parseInt(readLine)) mod 1).

Приклади:

8

виходи

1

і

10

виходи

0

Edit 1: замінити 0, 1і 2з Z, Oі W.

Редагувати 2: замінено =Zна !.

Також:

Піта , 5

Ще більше стискає версію Clip, оскільки Pyth має Q для вже оціненого вводу та функцію log2 (a) замість просто загального журналу (a, b).

!%lQ1


3

Математика (21)

IntegerQ@Log2@Input[]

Без введення це трохи коротше

IntegerQ@Log2[8]

Правда

IntegerQ@Log2[7]

помилковий


⌊#⌋==#&@Log2@Input[]
алефальфа

1
@alephalpha У результаті використовується 24 байти для символів UTF-8. Ще одна 21-байтна програма Log2@Input[]~Mod~1==0.
LegionMammal978

2

JavaScript, 41 40 символів

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

Як це працює: ви берете логарифм на основі 2, використовуючи l(prompt()) / l(2) , і якщо цей результат по модулю 1 дорівнює нулю, то це сила 2.

Наприклад: взявши логарифм 8 на базі 2, ви отримаєте 3.3 modulo 1дорівнює 0, тому це повертає істину.

Після взяття логарифму 7 на основі 2 ви отримуєте 2.807354922057604. 2.807354922057604 modulo 1дорівнює 0.807354922057604, тому це повертає хибне.


Вам не потрібно вводити дані до числа; Math.logзробить це вже : "Кожна з наведених нижче функцій об'єкта Math застосовує абстрактний оператор ToNumber до кожного свого аргументу ..."
apsillers

Чи не страждає вона від чисельних неточностей?
Марк Єронімус

@MarkJeronimus: Я насправді не знаю. Це могло бути, але я ще не стикався з неправильним результатом.
ProgramFOX

2

JavaScript, 35

Працює за байтами.

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

46-символьна версія , працює для 16-бітових чисел.

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

Трюк працює в більшості динамічних мов.

Пояснення: Перетворіть число в базу 2, інтерпретуйте цей рядок як базу 10, зробіть модуль 9, щоб отримати цифру суми, яка повинна бути 1.


А як щодо того 0x2ff, що в базі 2 є 1111111111?
Пітер Тейлор

@PeterTaylor Ви маєте рацію, виправлено
скопіюйте

тож справжньою вашою справою є перевірка модуля 10 без залишку, але ви використали 9 для гоління символу свого коду +1!
Математичний чиллер

Це свого роду обман, але інший метод:alert(!(Number.MAX_VALUE%prompt()))
Плутон

2

Perl 5,10+, 13 + 1 = 14 символів

say!($_&$_/3)

Використовується той самий метод із старої нитки FWP, як і моя запис GolfScript . Друкує1 якщо вхід має потужність дві, а порожній рядок - інакше.

Потреби, з якими потрібно працювати perl -nE; n варто один додатковий символ , в цілому 14 символів. Крім того, ось версія з 18 символів , яка не потребує n:

say!(($_=<>)&$_/3)

2

пітон 3, 38

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

пітон, 32

Однак код працює не в кожній версії.

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

Зауважте, що рішення також працює для 0 (друкувати помилково).


Прихильне, тому що це було і моє рішення.
Джош Касвелл

1
Що робити , якщо ви заміните ==з &?
SimonT

@SimonT Це неправда. Якщо замінити '==' на '&', буде надруковано 1 для кожного числа, яке має непарне число '1' у своєму двійковому зображенні. Перевірте, наприклад, 7 = 111. Є 3 = 11. Він повернеться 11 і 1 = 1.
Гарі БН

2

Ruby - 17 символів (четверта спроба)

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

Моє поточне найкраще - це злиття відповіді @ steenslag з моєю власною. Нижче наведені мої попередні спроби.

Ruby - 19 символів (третя спроба)

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

Ruby - 22 символи (друга спроба)

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

Ruby - 24 символи (перша спроба)

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

у вашій програмі все ще є "+"
phuclv

Я знаю. : - / Я попросив роз'яснити, чи "+" і "-" категорично заборонено, чи вони можуть бути використані в інших контекстах, крім додавання та віднімання. Я в процесі переписування незалежно.
OI

Велике поліпшення. Здається, це найкращий результат Рубі досі. Я оновив таблицю лідерів у тексті запитання.
gthacoder

@gthacoder Якраз поєднав регекс steenslag з моїм бінарним форматуванням. Однозначно не можна взяти весь кредит.
OI

2

К / Кона ( 24 17)

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

Повертає 1, якщо істинно, і 0, якщо невірно. Будь-яка потужність 2 має один біт, рівний 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)

(це виводить усі сили 2 (від 0 до 9) у двійковій)

Отже, я підсумовую всі компоненти двійкового вираження xі бачу, чи дорівнює він 1; якщо так, то в x=2^nіншому випадку немає.

... знав, що можу зробити його меншим


@gthacoder: Я зробив код меншим, сподіваюся, ви можете оновити основну публікацію, щоб це відобразити!
Кайл Канос

Це не використовує додаток? І питання, помилково, не забороняє цього?
zgrep

2

C # (54 символи)

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

У задачі чітко зазначено, що вхід не зберігається у змінній, його слід отримувати з якогось вхідного потоку (наприклад, stdin), також це код-гольф , спробуйте трохи скоротити код, принаймні, видаливши пробіл
mniip

Я думаю, ти просто маєш на увазі Int32, а не ToInt32...
Кріс

Я та Дякуємо, що вказали на Кріса. Раніше це було Convert.ToInt32, і я хотів змінити його на Int32.Parse, щоб скоротити його. : D
Мерін Накармі

2
використовувати intзамість Int32для 2 менших символів.
Рік

2

Ребму (9 годин)

z?MOl2A 1

Тест

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

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

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

Ребму - звужений діалект Ребола. Код по суті:

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

Альтернатива

14 символів - у Ребму немає битового зразка AND ~

z?AND~aTIddA 3

У Реболі:

zero? a & to-integer a / 3


1

Пітона, 35

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

Не використовує не тільки +/- операції, але й будь-які математичні операції, окрім перетворення у бінарну форму.

Інші речі (цікаві, але не для конкуренції):

У мене також є версія regexp (61) :

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

(Люблю ідею, але функція імпорту та відповідності робить її занадто довгою)

І приємна, але нудна бітова версія версії (31) :

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

(так, він коротший, але він використовує ~ -x для декременту, який містить - операція)


Відповіді бутбі використовують ту саму ідею, що і моя перша, але коротша :(
Іван Аніщук

1

Python 2.7 ( 30 29 39 37)

EDIT: оновлено через потреби введення користувача;

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

Груба сила, спробуйте розділити, поки = 1 (успіх) або <1 (невдача)


1
not a%2можна записати як a%2==0. Зрозуміло, це було б довше в багатьох мовах, але не Python.
Конрад Боровський

@xfix Спасибі, протестована та оновлена.
Йоахім Ісакссон

1
або навіть краще, a%2<1.
кабінка

після 2.видалення у вас є пробіл, який би врятував байт!
Кеертана Прабхакаран

1

Пітон (33)

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

int(bin(input()*2)[3:])<1також працює з оболонки пітона з лише 25 символами.
gmatht


1

APL (12 за 0/1, 27 за так / ні)

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

або, якщо нам потрібно вивести текст:

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

Прочитайте в А. Сформуйте вектор 0..A, потім вектор 2 0 ..2 A (так, це набагато більше, ніж потрібно), потім вектор, порівнюючи A з кожним із них (в результаті чого вектор 0 і максимум один 1), потім xor, що (в APL немає оператора xor, але ≠, застосований до булевих, діятиме як один.) Зараз у нас 0 або 1.

Щоб отримати ТАК або НІ: помножте 0 або 1 на 3, видаліть цю кількість символів з 'YESNO', а потім візьміть перші 3 символи цього.


1

C, 65 байт

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

Ви можете відрізати 5 символів за допомогою використання main(k){..., покладаючись на неявне intвведення тексту. Це може бути UB, але це код гольфу. НІКОЛИ не використовуйте щось подібне у виробництві, звичайно.
Кевін

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.