Чи є це число цілою потужністю -2?


41

Існують розумні способи визначення того, чи число є потужністю 2. Це вже не є цікавою проблемою, тому давайте визначимось, чи задане ціле число є цілою силою -2 . Наприклад:

-2 => yes: (-2)¹
-1 => no
0 => no
1 => yes: (-2)⁰
2 => no
3 => no
4 => yes: (-2)²

Правила

  • Ви можете написати програму або функцію та використовувати будь-який із стандартних методів отримання вводу та надання виводу.

  • Ваш вхід - це одне ціле число, а вихід має бути триєдним значенням, якщо ціле число - ціла сила -2, а фальш-значення - в іншому випадку. Не допускається жоден інший вихід (наприклад, попереджувальні повідомлення).

  • Застосовуються звичайні правила переповнення цілих чисел: ваше рішення повинно бути в змозі працювати для довільно великих цілих чисел у гіпотетичній (або, можливо, реальній) версії вашої мови, в якій всі цілі числа за замовчуванням не пов'язані, але якщо ваша програма не працює на практиці через впровадження не підтримуючи великі цілі числа, це не може визнати недійсним рішення.

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

Умова виграшу

Це змагання з : відповідь, яка має найменше байтів (у вибраному кодуванні), є переможцем.


17
@KritixiLithos Я не бачу, чому це повинно. Немає цілого числа iтакого, що(-2)^i = 2
Fatalize

2
Чи показники позитивні чи -0.5повинні бути дійсними, оскільки це 2 ^ (- 1) .
Містер Xcoder

1
@ Mr.Xcoder, Оскільки вхідні дані завжди є цілими значеннями , негативний показник не буде потрібен (або можливий).
Toby Speight

1
@SIGSEGV, можливо, тоді iце не природно
містер Xcoder

2
@Jason, якомога більше підтримуваних / природних у вашій мові - див. Третє правило. І це код-гольф, тому що для його обговорення потрібен об'єктивний критерій виграшу - "приємне рішення" не вирішує це (хоча мені подобається відповідь Mathematica - це мене здивувало).
Toby Speight

Відповіді:


26

Математика, 22 байти

EvenQ@Log2@Max[#,-2#]&

Спробуйте в Інтернеті! (Замість цього використовується Mathics, де це рішення також працює.)

Я деякий час намагався знайти рішення з побітними операторами, і, хоча один, безумовно, існує, я знайшов щось, що, мабуть, простіше:

  • Max[#,-2#]помножує вхід на -2, якщо він від'ємний. Помноження на інший коефіцієнт -2 не змінює, чи є значення потужністю -2 чи ні. Але тепер усі непарні сили -2 перетворилися на парні сили -2 .
  • Але навіть сили -2 - це навіть сили 2 , тому ми можемо використовувати просте Log2@...і перевірити, чи є результат цілим числом (щоб перевірити, чи це сила 2 ). Це вже економить два байти Log[4,...](ще один спосіб переглянути рівні сили -2 ).
  • Як додатковий бонус, перевірка того, чи є ціле ціле число, коротше, ніж просто перевірка, чи це ціле число: ми можемо зберегти ще три байти, використовуючи EvenQзамість IntegerQ.

Чи допомагає це врахувати, що навіть сили -2 - це цілі сили 4? Мені подобається ідея множення на -2, щоб отримати все позитивне, хоча і розчароване, що поки що не бачило жодного біту.
Toby Speight

5
@TobySpeight Трактуючи їх як сили 2, насправді економиться 5 байт. Я спочатку використовував потужності 4, але Log[4,...]довше Log2@...і IntegerQдовше, ніж EvenQ.
Мартін Ендер


12

Пітон , 46 байт

-2 байти завдяки @ovs.

def g(x):
 while x%-2==0!=x:x/=-2
 return x==1

Функція із використанням:

g(4) # put your number between the brackets

Спробуйте в Інтернеті!


print g(8)принтиFalse
Феліпе Нарді Батіста

2
@FelipeNardiBatista чи не так?
Містер Xcoder

2
Вибачте, мій приклад був поганий, print g(4)робить те саме
Феліпе Нарді Батіста

Зачекайте, є невелика помилка, її виправляйте невдовзі
містер Xcoder

1
Я ;замість нового рядка поставив ... вибачте за це. Виправлено @FelipeNardiBatista
Містер Xcoder

11

Желе , 6 байт

b-2S⁼1

Спробуйте в Інтернеті!

Це ґрунтується на тому, як Jelly перетворює ціле число N в будь-яку довільну базу B , роблячи це шляхом перетворення N в масив, в якому кожне ціле число є цифрою d ( N ) B , яка може мати значення 0≤ V d < B . Тут ми будемо 0-індексні цифри з правого боку , так що кожна цифра додає V d B D з утворенням N . V d < BV d B d < BB d = B d +1 , тому всі можливіN має тільки один унікальну виставу, якщо ми будемо ігнорувати провідні 0s в ( N ) B .

Тут d = вхід, B = -2. N = B d = 1 B d = V d B d ⇔1 = V dV d = 1, і, оскільки ми не додаємо жодних інших кратних потужностей B , кожен інший V буде дорівнює 0. Зараз, масив повинен бути 1, з'єднаний з d 0s. Оскільки Jelly 1-індекси зліва, ми повинні перевірити, чи є перший елемент масиву 1, а всі інші елементи - 0.

Хм ... все добре, правда? Ні? Що відбувається? О так, я маю кращу ідею! Спочатку візьмемо суму всіх цілих чисел у масиві, трактуючи його так, ніби це цілий масив, а не число в базі -2. Якщо він дорівнює 1, це означає, що є лише одне, а всі інші цілі числа - 0. Оскільки не можуть бути провідні нулі, за винятком випадків 0 -2(де сума в будь-якому разі буде 0 ≠ 1), перше ціле число повинно бути не нульовим. Єдине ненульове ціле число в масиві - це 1, тому воно повинно бути першим. Отже, це єдиний випадок, коли сума всіх цілих чисел у масиві дорівнюватиме 1, тому що найменша можлива сума пари додатних цілих чисел - {1,1} = 2, оскільки найменше додатне ціле число дорівнює 1 . Кожне ціле число в базовому поданні невід'ємне, тому єдиний спосіб суми 1 - це лише один 1, а всі інші цілі числа - 0. Отже, ми можемо просто перевірити, чи є сума всіх цілих чисел у масив дорівнює 1.

Ось що робить код:

b-2S⁼1 Main link. Arguments: d
b-2    Convert d to base -2.
   S   Take the sum.
    ⁼1 Check if the sum is equal to 1.

1
Фу, це пояснення знадобилося час, щоб написати ...
Ерік Атголфер

Мені б не хотілося побачити, як виглядатиме пояснення для довгої програми тоді ...
boboquack

1
@boboquack Тут я пояснюю, чому я використовую базовий матеріал для перетворення. Я не думаю, що пояснення довгих програм було б таким довгим. Повідомлення може містити до 30000 символів розмітки, і пояснення для довших програм у будь-якому разі були б більш стислими. Також я читав набагато довші пояснення, і вони не такі нудні.
Erik the Outgolfer



10

Excel, 40 36 байт

Збережено 4 байти за допомогою CallumDA

Excel, безумовно, може це зробити, але виправлення помилок додає 11 байт

=IFERROR(-2^IMREAL(IMLOG2(A1)),1)=A1

Введення знаходиться в комірці A1. Вихід є TRUEабоFALSE

Якби дозволено повернути FALSEабо #NUM!помилку для помилкових значень, це було б лише 25 байт:

=-2^IMREAL(IMLOG2(A1))=A1

Ось невелике поліпшення:=IFERROR(-2^IMREAL(IMLOG2(A1)),1)=A1
CallumDA

1
@CallumDA Дякую! Я спробував знайти спосіб використання складних функцій числення, але все, що я придумав, було довше.
Інженер Тост

9

05AB1E , 8 байт

Y(IÄÝm¹å

Спробуйте в Інтернеті! або як тестовий набір

Пояснення

Y(         # push -2
  IÄÝ      # push range [0 ... abs(input)]
     m     # element-wise power
      ¹å   # check if input is in the resulting list

Чому потік?
Kritixi Lithos

@KritixiLithos: Схоже, хтось відмовився від усіх мов для гри в гольф.
Емінья

6
Помітив це теж. Хоча я давно не був навколо PPCG, я дізнався, що творчі та цікаві рішення на стандартних мовах набагато більше цінуються, ніж 3-байтні рішення в гольф-мовах. Однак є люди, які (на жаль) відмовляються від творчих рішень з мов гольфу, просто тому, що вони думають, що все вбудовано, і не розуміють, наскільки хороші алгоритми (хоча написані в гольф-мовах). +1 за неймовірне рішення @Emigna
Містер Xcoder

ÄLY(småOдля 8. Y(sÄLm¢Zдля 8 ... Не забудьте, всі 8.
Чарівний восьминога Урн

9

JavaScript (ES6), 37 28 24 байт

f=x=>!x|x%2?x==1:f(x/-2)

Збережено 4 байти завдяки Арнольду.

f=x=>!x|x%2?x==1:f(x/-2)

console.log(f(-2));
console.log(f(-1));
console.log(f(0));
console.log(f(1));
console.log(f(2));
console.log(f(3));
console.log(f(4));


Чому я бачу деякі помилки (перед значеннями true / false), коли натискаю кнопку "Запустити фрагмент коду"?
numbermaniac

@numbermaniac Я не впевнений, можливо, ви використовуєте браузер, який не підтримує ES6 повністю?
Том

Welp, оновлений та повторений, без помилок. Не впевнений, що сталося вперше.
numbermaniac


8

MATL , 9 8 байт

2_y|:q^m

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Як це працює

Розглянемо вклад -8як приклад

2_    % Push -2
      % STACK: -2
y     % Implicit input. Duplicate from below
      % STACK: -8, -2, -8
|     % Absolute value
      % STACK: -8, -2, 8
:     % Range
      % STACK: -8, -2, [1 2 3 4 5 6 7 8]
q     % Subtract 1, element-wise
      % STACK: -8, -2, [0 1 2 3 4 5 6 7]
^     % Power, element-wise
      % STACK: -8, [1 -2 4 -8 16 -32 64 -128]
m     % Ismember. Implicit display
      % STACK: 1

Якщо я правильно зрозумів ваше пояснення, тоді, якщо вводити дані n, це створює масив розмірів nяк проміжний крок. Хороша робота, що ефективність тут не є критерієм!
Toby Speight

2
@Toby Звичайно! Це кодовий гольф, хто дбає про ефективність? :-D
Луїс Мендо


6

PHP, 41 байт

for(;$argn%-2==0;)$argn/=-2;echo$argn==1;

PHP, 52 байти

echo($l=log(abs($argn),2))==($i=$l^0)&&$argn>0^$i%2;

PHP, 64 байти

Робота з Regex

echo preg_match("#^".($argn>0?1:"1+0")."(00)*$#",decbin($argn));


5

JavaScript (ES6), 21 байт

Рекурсивна функція, яка повертає 0або true.

f=n=>n==1||n&&f(n/-2)

Як це працює

Це не включає явний тест - наприклад n, непарний або abs(n)менший, ніж один - для припинення рекурсії на ранній стадії, коли вхід не має точної потужності -2.

Ми виходимо лише тоді, коли nрівно дорівнює 1або 0.

Це все-таки працює, тому що будь-який поплавок IEEE-754 в кінцевому підсумку буде округлений до, 0якщо його розділити на 2 (або -2) достатньо разів через арифметичний перелив .

Тестові справи



4

Java 7, 55 байт

boolean c(int n){return n==0?0>1:n%-2==0?c(n/-2):n==1;}

Пояснення:

boolean c(int n){  // Method with integer parameter and boolean return-type
  return n==0 ?    //  If n is zero:
    0>1//false     //   Return false
   : n%-2==0 ?     //  Else-if n mod -2 is zero:
    c(n/-2)        //   Recursive call for the input divided by -2
   :               //  Else:
    n==1;          //   Return if n is one
}                  // End of method

Код тесту:

Спробуйте тут.

class M{
  static boolean c(int n){return n==0?0>1:n%-2==0?c(n/-2):n==1;}

  public static void main(String[] a){
    for(int i = -2; i <= 4; i++){
      System.out.println(i + ": " + c(i));
    }
  }
}

Вихід:

-2: true
-1: false
0: false
1: true
2: false
3: false
4: true

Нерекурсівние шлях коротший на 5 байт: boolean c(int n){while(0==n%-2)n/=-2;return 1==n;}.
Олів'є Грегоар

@ OlivierGrégoire На жаль, це не працює n=0в Java, тому що 0%-2==0буде trueі 0/-2є 0, викликаючи нескінченний цикл, саме тому я додав n==0?0>1частину до мого рекурсивного методу.
Кевін Кройсейсен

Приємно помічений!
Олів'є Грегоар


3

Javascript (ES7), 45 байт

x=>-1**Math.log2(Math.abs(x))*Math.abs(x)==x

Math.abs (x) довше x> 0? X: -x, від 11 байт до 8 байт. Ви також можете зробити -2 ** ... замість -1 ... видалити другий Math.abs (x)
fəˈnɛtɪk

Що специфічного для цього ES7?
Арджун

@ DobbyTheFree-Elf, **є.
Qwertiy

3

Perl 6 , 21 байт

{$_==(-2)**(.lsb//0)}

Спробуй це

Розширено:

{  # bare block lambda with implicit parameter 「$_」

  $_                  # is the input
  ==                  # equal to
  (-2)**( .lsb // 0 ) # -2 to the power of the least significant bit of the input
}

Зверніть увагу, що 0.lsbповертається, Nilщо створює попередження, коли використовується як число, тому використовується визначений або оператор  //.
(Подумайте, //як ||з іншим нахилом)

Виклик методу без фактора, де очікується термін, неявно викликається $_. ( .lsb)

Також працює з.msb .


Мені це подобається!
tale852150


3

Пітон , 24 байти

lambda n:n*n&n*n-1<n%3%2

Спробуйте в Інтернеті!

Біт-трюк k&k-1==0перевіряє, чи kє потужність 2 (або k==0). Перевірка цього на k=n*nяк n*n&n*n-1==0говорить нам, чи abs(n)є сила 2.

Щоб далі зрозуміти, чи nє сила -2, нам потрібно лише перевірити це n%3==1. Це працює тому, що мод 3, значення -2 дорівнює 1, тому його потужності дорівнюють 1. На відміну від них, заперечення їх 2 мод 3, і звичайно 0 дає 0 мод 3.

Ми поєднуємо чеки n*n&n*n-1==0і n%3==1в єдиний вираз. Перший може бути написаний <1за ==0, оскільки він ніколи не є негативним. n%3==1Еквівалентно n%3%2, що дає 0 або 1. Таким чином, ми можемо об'єднати їх n*n&n*n-1<n%3%2.


2

R, 22 байти

Бере вхід зі стдіна, повертає TRUEабо FALSEвідповідно.

scan()%in%(-2)^(0:1e4)

Я не на 100% впевнений, що це правильна відповідь, оскільки вона працює лише для цілих чисел до граничного розміру R, і якби цілі числа були без обмежень, це не спрацювало. Однак у правилах зазначено:

Застосовуються звичайні правила переповнення цілих чисел: ваше рішення повинно бути в змозі працювати для довільно великих цілих чисел у гіпотетичній (або, можливо, реальній) версії вашої мови, в якій всі цілі числа за замовчуванням не пов'язані, але якщо ваша програма не працює на практиці через впровадження не підтримуючи великі цілі числа, це не може визнати недійсним рішення.

У гіпотетичній версії R, яка дозволяє не обмежувати цілі числа, тоді ми могли б використовувати наступний код для того ж числа байтів:

scan()%in%(-2)^(0:Inf)

Звичайно, в реальному R вищезазначений код просто дає Error in 0:Inf : result would be too long a vector.


2

bc 88 байт

bc -l <<< "n=$1;q=l(sqrt(n*n));p=4*a(1);((n<1)*c(q/l(2)*p/2)+(n>1)*(s(q/l(4)*p)))^2==0"

Я маю це у файлі, neg2.shі він друкує 1для повноважень -2і в 0іншому випадку

Я знаю, що це насправді довго, але це було весело

Тест

$ for i in {-129..257}; do echo -n "$i: "; ./neg2.sh $i; done | grep ': 1'
-128: 1
-32: 1
-8: 1
-2: 1
1: 1
4: 1
16: 1
64: 1
256: 1

Пояснення

Головний корпус має дві половинки, обидві намагаються дорівнювати нулю для потужностей -2.

q=l(sqrt(n*n))               % ln of the absolute value of the input
p=4*a(1)                     % pi: arctan(1) == pi/4
q/l(2) -> l(sqrt(n*n))/l(2)  % change of base formula -- this gives
                             % the power to which 2 is raised to equal
                             % sqrt(n*n). It will be an integer for 
                             % numbers of interest
n<1                          % 1 if true, 0 if false. for negative
                             % numbers check for powers of 2
n>1                          % for positive numbers, check for powers
                             % of 4
c(q/l(2)*p/2)                % cos(n*pi/2) == 0 for integer n (2^n)
s(q/l(4)*p)                  % sin(n*pi) == 0 for integer n (4^n)
(....)^2==0                  % square the result because numbers are
                             % not exactly zero and compare to 0

Я ніколи не очікував тригонометрії! Гарна відповідь!
Toby Speight


2

Фур’є , 53 байти

I~X1~N~G0(0-2*G~GX*X~PG*G>P{1}{0~O~N}G{X}{1~O0~N}N)Oo

Я над цим попрацюю пізніше, але контур цього:

X = User input
G = N = 1
Loop until N = 0
    G = -2 * G
    P = X*X 
    If G*G > P then
        N = O = 0
    End if
    If G = X then
        O = 1
        N = 0
    End if
End loop
Print O

Там, де вихід - 0на фальси та 1на трити .

Спробуйте в Інтернеті!


В описі algo не було б краще не використовувати змінну P і написати, якщо G * G> X * X, то ...?
RosLuP

@RosLuP Це було б краще, але Фур'є просто вважав би це(G*G > X)*X
Beta Decay

2

Casio BASIC , 76 байт

Зауважте, що 76 байт - це те, що написано на моєму калькуляторі.

?→X
0→O
While Abs(X)≥1
X÷-2→X
If X=1
Then 1→O
IfEnd
WhileEnd
O

Це моє перше зайняття Casio BASIC ... Я ніколи не зрозумів, що можу написати такі пристойні програми на калькуляторі: D


1

Python 2.7, 40 байт

a=input()
while a%-2==0:a/=-2
print a==1

Кредити г Xcoder для вихідного коду довжиною 43 байт. Довелося публікувати як окрему відповідь, оскільки мені не вистачає репутації для коментарів.


Це щось те саме, оскільки я зробив свою відповідь універсальною версією, тому вона працює як в Python 2, так і 3. Якби ви це робили в Python 3, ви мали б додати те, int(input())що перейшло б за межі defподібна функція. Крім того, у python 3 ви повинні використовувати, print()який би витратив 1 байт. Ось чому я вибрав саме такий шлях, адже в Python 3 він стає довше ...
Містер Xcoder

1

Сітківка , 27 байт

+`(1+)\1
$1_
^(1|-1_)(__)*$

Спробуйте в Інтернеті!

Вводиться в одинарному режимі, що досить стандартно для сітківки. Перші два рядки роблять частково невідповідним бінарне перетворення на основі перших двох рядків коду з підручника (будь-які сторонні 1s призведуть до збігу в будь-якому випадку), тоді як останній рядок перевіряє потужність у чотири чи негативну непарну потужність з двох.

+`(1+)\1\1\1
$1_
^(-1)?1_*$

Спробуйте в Інтернеті!

Цього разу я роблю часткове унітарне базування на чотири перетворення. Повноваження чотирьох закінчуються як, ^1_*$тоді як негативні непарні сили двох закінчуються як ^-11_*$.

+`\b(1111)*$
$#1$*
^(-1)?1$

Спробуйте в Інтернеті!

Цього разу я просто продовжую ділити на чотири, наскільки я можу, і перевіряю на 1чи -11в кінці.

+`\b(1+)\1\1\1$
$1
^(-1)?1$

Спробуйте в Інтернеті!

Ще один спосіб поділу на чотири. І ще дратує 27 байт ...


1

Схема, 60 байт

(define(f n)(cond((= 1 n)#t)((<(abs n)1)#f)(#t(f(/ n -2)))))

Рекурсивне рішення.

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