Questo numero è una potenza intera di -2?


41

Esistono modi intelligenti per determinare se un numero è una potenza di 2. Questo non è più un problema interessante, quindi determiniamo se un dato numero intero è una potenza intera di -2 . Per esempio:

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

Regole

  • È possibile scrivere un programma o una funzione e utilizzare uno dei metodi standard per ricevere input e fornire output.

  • L'input è un singolo intero e l'output deve essere un valore di verità se l'intero è una potenza intera di -2 e un valore di falsa in caso contrario. Nessun altro output (ad es. Messaggi di avviso) è consentito.

  • Si applicano le solite regole di overflow dei numeri interi: la soluzione deve essere in grado di funzionare per numeri interi arbitrariamente grandi in una versione ipotetica (o forse reale) della lingua in cui tutti i numeri interi non sono associati per impostazione predefinita, ma se il programma non riesce in pratica a causa dell'implementazione non supportando numeri interi così grandi, ciò non invalida la soluzione.

  • È possibile utilizzare qualsiasi linguaggio di programmazione , ma si noti che queste scappatoie sono vietate per impostazione predefinita.

Condizioni vincenti

Questa è una gara di : la risposta che ha il minor numero di byte (nella codifica scelta) è il vincitore.


17
@KritixiLithos Non vedo perché dovrebbe. Non esiste un numero intero itale che(-2)^i = 2
Fatalizza il

2
Gli esponenti sono positivi o -0.5dovrebbero essere validi poiché è 2 ^ (- 1) .
Mr. Xcoder,

1
@ Mr.Xcoder, Poiché gli input sono sempre valori interi , non sarà richiesto (o possibile) un esponente negativo.
Toby Speight,

1
@SIGSEGV forse mentre inon è naturale
Mr. Xcoder

2
@Jason, quanti sono supportati / naturali nella tua lingua - vedi la terza regola. Ed è code-golf perché ha bisogno di un criterio vincente oggettivo per essere in tema qui - "una soluzione piacevole" non lo taglia (anche se mi piace la risposta di Mathematica - che mi ha sorpreso).
Toby Speight,

Risposte:


26

Mathematica, 22 byte

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

Provalo online! (Usando invece la matematica, dove funziona anche questa soluzione.)

Ho provato a trovare una soluzione con operatori bit a bit per un po ', e mentre uno sicuramente esiste, ho finito per trovare qualcosa che probabilmente è più semplice:

  • Max[#,-2#]moltiplica l'input per -2 se è negativo. Moltiplicare per un altro fattore di -2 non cambia se il valore è una potenza di -2 o meno. Ma ora tutti i poteri dispari di -2 sono stati trasformati in poteri pari di -2 .
  • Ma anche le potenze di -2 sono anche potenze di 2 , quindi possiamo usare un semplice Log2@...e verificare se il risultato è un numero intero (per verificare se è una potenza di 2 ). Ciò consente di risparmiare già due byte Log[4,...](un altro modo per visualizzare anche i poteri di -2 ).
  • Come bonus aggiuntivo, verificare se un valore è un numero intero pari è più breve del semplice verificare se si tratta di un numero intero: è possibile salvare altri tre byte utilizzando EvenQinvece di IntegerQ.

Aiuta a considerare che anche i poteri di -2 sono poteri interi di 4? Mi piace l'idea di moltiplicare per -2 per ottenere tutto ciò che è positivo, anche se deluso di non aver visto fino ad ora un po 'di bagliori.
Toby Speight,

5
@TobySpeight Considerandoli come potenze di 2, si risparmiano effettivamente 5 byte. All'inizio ho usato poteri di 4, ma Log[4,...]è più lungo di Log2@...ed IntegerQè più lungo di EvenQ.
Martin Ender,

16

Gelatina , 5 byte

æḟ-2=

Provalo online!

Come funziona

æḟ-2=  Main link. Argument: n

æḟ-2   Round n towards 0 to the nearest power of -2.
    =  Test if the result is equal to n.

12

Python , 46 byte

-2 byte grazie a @ovs.

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

Funzione con utilizzo:

g(4) # put your number between the brackets

Provalo online!


print g(8)stampeFalse
Felipe Nardi Batista

2
@FelipeNardiBatista non dovrebbe?
Mr. Xcoder,

2
scusate, il mio esempio è stato negativo, print g(4)fa lo stesso
Felipe Nardi Batista,

Aspetta, c'è un piccolo errore, risolverlo a breve
Mr. Xcoder

1
Ho messo un al ;posto di una nuova riga ... mi dispiace per quello. Risolto @FelipeNardiBatista
Mr. Xcoder

11

Gelatina , 6 byte

b-2S⁼1

Provalo online!

Questo si basa su come Jelly converte un numero intero N in qualsiasi base B arbitraria , facendo ciò convertendo N in un array, in cui ogni numero intero è una cifra d di ( N ) B , che può avere un valore 0≤ V d < B . Qui, avremo cifre 0-index da destra, quindi ogni cifra aggiunge V d B d per formare N . V d < B V d B d < BB d = B d +1 , quindi ogni possibileN ha una sola rappresentazione unica, se ignoriamo 0 non significativi in ( N ) B .

Qui, d = input, B = -2.N = B d = 1 B d = V d B d ⇔1 = V dV d = 1 e, poiché non stiamo aggiungendo altri multipli di potenze di B , ogni altra V sarebbe 0. In questo momento, l'array dovrebbe essere un 1 concatenato con d 0s. Poiché Jelly 1-indicizza da sinistra, dovremmo verificare se il primo elemento dell'array è 1 e tutti gli altri elementi sono 0.

Hmm ... tutto bene, vero? No? Cosa sta succedendo? Oh sì, ho un'idea migliore! Innanzitutto, prendiamo la somma di tutti gli interi nell'array, trattandolo come se fosse un array intero e non un numero nella base -2. Se è 1, significa che esiste un solo 1 e tutti gli altri numeri interi sono 0. Dato che non possono esserci zero iniziali, tranne nel caso di 0 -2(dove la somma sarebbe comunque 0 ≠ 1), il 1o numero intero deve essere diverso da zero. L'unico numero intero diverso da zero nell'array è 1, quindi deve essere il primo. Pertanto, questo è l'unico caso in cui la somma di tutti i numeri interi nella matrice sarebbe 1, poiché la somma più piccola possibile di una coppia di numeri interi positivi è Σ {1,1} = 2, poiché il numero intero positivo più piccolo è 1 Ogni numero intero in una rappresentazione di base non è negativo, quindi l'unico modo in cui la somma è 1 è di avere solo 1, e tutti gli altri numeri interi sono 0. Pertanto, possiamo solo verificare se la somma di tutti i numeri interi nella l'array è 1.

Ecco cosa fa il codice:

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
Accidenti, quella spiegazione ha richiesto del tempo per scrivere ...
Erik the Outgolfer

Odierei vedere come sarebbe una spiegazione per un lungo programma allora ...
Odierei

1
@boboquack Qui sto spiegando perché uso le cose di conversione di base. Non credo che la spiegazione di programmi lunghi sarebbe così lunga. Un post può contenere fino a 30000 caratteri di markdown e le spiegazioni per i programmi più lunghi sarebbero comunque più concise. Inoltre, ho letto spiegazioni molto più lunghe e non sono poi così noiose.
Erik the Outgolfer



10

Excel, 40 36 byte

Salvato 4 byte da CallumDA

Excel può certamente farlo, ma la correzione degli errori aggiunge 11 byte

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

L'input è nella cella A1. L'output è TRUEoFALSE

Se fosse consentito restituire uno FALSEo un #NUM!errore per i valori falsi, sarebbe solo 25 byte:

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

Ecco un piccolo miglioramento:=IFERROR(-2^IMREAL(IMLOG2(A1)),1)=A1
CallumDA

1
@CallumDA Grazie! Ho cercato di immaginare un modo per usare le complesse funzioni numeriche, ma tutto quello che mi è venuto in mente era più lungo.
Ingegnere Toast

9

05AB1E , 8 byte

Y(IÄÝm¹å

Provalo online! o come una suite di test

Spiegazione

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

Perché il downvote?
Kritixi Lithos,

@KritixiLithos: sembra che qualcuno abbia ridimensionato tutte le lingue del golf.
Emigna,

6
Ho notato anche quello. Anche se non sono in giro per PPCG da molto tempo, ho imparato che le soluzioni creative e interessanti nei linguaggi standard sono molto più apprezzate delle soluzioni a 3 byte nei linguaggi del golf. Tuttavia, ci sono alcune persone che (sfortunatamente) declassano soluzioni molto creative nei linguaggi del golf, semplicemente perché pensano che tutto sia integrato e non capiscono quanto siano buoni gli algoritmi (sebbene scritti nelle lingue del golf). +1 per l'incredibile soluzione @Emigna
Mr. Xcoder

ÄLY(småOper 8. Y(sÄLm¢Zper 8 ... Nevermind, all 8.
Magic Octopus Urn

9

JavaScript (ES6), 37 28 24 byte

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

Salvato 4 byte grazie ad Arnauld.

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));


Perché visualizzo alcuni errori (prima dei valori true / false) quando faccio clic su "Esegui snippet di codice"?
numbermaniac,

@numbermaniac Non sono sicuro, forse stai usando un browser che non supporta completamente ES6?
Tom,

Welp, aggiornato e riprovato, nessun errore. Non sono sicuro di cosa sia successo la prima volta.
numbermaniac,


8

MATL , 9 8 byte

2_y|:q^m

Provalo online! Oppure verifica tutti i casi di test.

Come funziona

Considera l'input -8come esempio

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

Se capisco correttamente la tua spiegazione, quindi ho dato input n, questo crea una matrice di dimensioni ncome passaggio intermedio. Ottimo lavoro che l'efficienza non è un criterio qui!
Toby Speight,

2
@Toby Of course! This is code golf, who cares about efficiency? :-D
Luis Mendo


6

PHP, 41 Bytes

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

PHP, 52 Bytes

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

PHP, 64 Bytes

Working with a Regex

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

5

Python 3, 34 bytes

lambda n:n==(-2)**~-n.bit_length()

5

JavaScript (ES6), 21 bytes

A recursive function that returns 0 or true.

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

How it works

This doesn't include any explicit test -- like n being odd or abs(n) being less than one -- to stop the recursion early when the input is not an exact power of -2.

We exit only when n is exactly equal to either 1 or 0.

This does work however because any IEEE-754 float will eventually be rounded to 0 when divided by 2 (or -2) enough times, because of arithmetic underflow.

Test cases



4

Java 7, 55 bytes

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

Explanation:

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

Test code:

Try it here.

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));
    }
  }
}

Output:

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

The non-recursive way is shorter by 5 bytes: boolean c(int n){while(0==n%-2)n/=-2;return 1==n;}.
Olivier Grégoire

@OlivierGrégoire Unfortunately that one doesn't work for n=0 in Java, because 0%-2==0 will be true and 0/-2 is still 0, causing an infinite loop, which is why I added the n==0?0>1 part to my recursive method.
Kevin Cruijssen

Nicely spotted!
Olivier Grégoire

4

Haskell, 24 23 bytes

f 0=0
f 1=1
f n=f(-n/2)

Defines a function f which returns 1 for powers of -2 and 0 otherwise.

A golfed version of my first submission to the other challenge.


3

Javascript(ES7), 45 bytes

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

Math.abs(x) is longer than x>0?x:-x, 11 bytes to 8 bytes. You should also be able to do -2**... instead of -1... to remove the second Math.abs(x)
fəˈnɛtɪk

What's ES7 specific in this?
Arjun

@DobbyTheFree-Elf, ** is.
Qwertiy

3

Perl 6, 21 bytes

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

Try it

Expanded:

{  # 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
}

Note that 0.lsb returns Nil which produces a warning when used as a number, so the defined or operator // is used.
(Think of // as || with a different slant)

A method call with no invocant where a term is expected is implicitly called on $_. (.lsb)

Also works with .msb.


I like this one!
tale852150


3

Python, 24 bytes

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

Try it online!

The bit trick k&k-1==0 checks whether k is a power of 2 (or k==0). Checking this for k=n*n as n*n&n*n-1==0 tells us whether abs(n) is a power of 2.

To further see if n is a power of -2, we need only check that n%3==1. This works because mod 3, the value -2 is equal to 1, so its powers are 1. In contrast, their negations are 2 mod 3, and of course 0 gives 0 mod 3.

We combine the checks n*n&n*n-1==0 and n%3==1 into a single expression. The first can be written with <1 for ==0, since it's never negative. The n%3==1 is equivalent to n%3%2, giving 0 or 1. So, we can combine them as n*n&n*n-1<n%3%2.


2

R, 22 bytes

Takes input from stdin, returns TRUE or FALSE accordingly.

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

I'm not 100% sure that this is a valid answer, as it only works for integers up to R's size limit, and if the integers were unbounded it wouldn't work. However, the rules state:

The usual integer overflow rules apply: your solution must be able to work for arbitrarily large integers in a hypothetical (or perhaps real) version of your language in which all integers are unbounded by default, but if your program fails in practice due to the implementation not supporting integers that large, that doesn't invalidate the solution.

In a hypothetical version of R which does allow unbounded integers, then we could use the following code, for the same byte count:

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

Of course, in real R, the above code just gives Error in 0:Inf : result would be too long a vector.


2

bc 88 bytes

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"

I have this in a file neg2.sh and it prints 1 for powers of -2 and 0 otherwise

I know it's really long, but it was fun

Test

$ 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

Explanation

The main body has two halves, both are trying to equal zero for powers of -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

I never expected trigonometry! Good answer!
Toby Speight


2

Fourier, 53 bytes

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

I'll work on golfing this later, but the outline of this is:

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

Where the output is 0 for falsey and 1 for truthy.

Try it online!


In the algo description not would be better not use P variable and write If G*G > X*X then...?
RosLuP

@RosLuP That would be better, but Fourier would simply treat that as (G*G > X)*X
Beta Decay

2

Casio BASIC, 76 bytes

Note that 76 bytes is what it says on my calculator.

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

This is my first venture into Casio BASIC... I never realised I could write such decent programs on a calculator :D


1

Python 2.7, 40 bytes

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

Credits to Mr. Xcoder for the original code of length 43 bytes. Had to post as a separate answer since I don't have enough reputation to comment.


It's kind of the same thing, since I've made my answer version-universal, so it works in both Python 2 and 3. If you were to do this in Python 3, you should have added int(input()) which would have gone over the limit of the def-like function. Additionally, In python 3, you must use print() which would of wasted 1 byte. That's why I chose that way, because in Python 3 it gets longer...
Mr. Xcoder

1

Retina, 27 bytes

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

Try it online!

Takes input in unary, which is fairly standard for Retina. The first two lines do partial unary to binary conversion based on the first two lines of code from the Tutorial entry (any extraneous 1s will cause the match to fail anyway), while the last line checks for a power of four or a negative odd power of two.

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

Try it online!

This time I do partial unary to base four conversion. Powers of four end up as ^1_*$ while negative odd powers of two end up as ^-11_*$.

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

Try it online!

This time I just keep dividing by four as much as I can and check for 1 or -11 at the end.

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

Try it online!

Another way of dividing by four. And still annoyingly 27 bytes...


1

Scheme, 60 bytes

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

Recursive solution.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.