Questa è una versione della recente sfida Questo numero è un potere intero di -2? con una serie diversa di criteri progettati per evidenziare la natura interessante del problema e rendere la sfida più difficile. Ho preso in considerazione qui .
La sfida, meravigliosamente dichiarata da Toby nella domanda collegata, è:
Esistono modi intelligenti per determinare se un numero intero è una potenza esatta di 2. Questo non è più un problema interessante, quindi determiniamo se un dato numero intero è una potenza esatta di -2 . Per esempio:
-2 => yes: (-2)¹ -1 => no 0 => no 1 => yes: (-2)⁰ 2 => no 3 => no 4 => yes: (-2)²
Regole:
- Un numero intero è 64 bit, firmato, complemento a due. Questo è l' unico tipo di dati con cui puoi lavorare.
- È possibile utilizzare solo le seguenti operazioni. Ognuno di questi conta come un'operazione.
n << k
,n >> k
: Spostamento sinistro / destron
dik
bit. Il bit di segno viene esteso con lo spostamento a destra.n >>> k
: Spostamento a destra ma non estendere il bit di segno. Gli 0 vengono spostati.a & b
,a | b
,a ^ b
: Bitwise AND, OR, XOR.a + b
,a - b
,a * b
: Aggiungere, sottrarre, moltiplicare.~b
: Inverti bit a bit.-b
: Negazione del complemento a due.a / b
,a % b
: Divide (quoziente intero, arrotondamenti verso 0) e modulo.- Modulo di numeri negativi utilizza le regole specificate in C99 :
(a/b) * b + a%b
deve essere ugualea
. Così5 % -3
è2
ed-5 % 3
è-2
: 5 / 3
è1
,5 % 3
è2
, come 1 * 3 + 2 = 5.-5 / 3
è-1
,-5 % 3
è-2
, come -1 * 3 + -2 = -5.5 / -3
è-1
,5 % -3
è2
, come -1 * -3 + 2 = 5.-5 / -3
è1
,-5 % -3
è-2
, come 1 * -3 + -2 = -5.- Notare che qui l'
//
operatore di divisione del pavimento di Python non soddisfa la proprietà di "arrotondamento verso 0" della divisione e che anche l'%
operatore di Python non soddisfa i requisiti.
- Modulo di numeri negativi utilizza le regole specificate in C99 :
- Le assegnazioni non contano come un'operazione. Come in C, le assegnazioni valutano il valore del lato sinistro dopo l'assegnazione:
a = (b = a + 5)
impostab
sua + 5
, quindi impostaa
sub
e conta come un'operazione. - Le assegnazioni composte possono essere usate come
a += b
mezzia = a + b
e contano come un'unica operazione.
- Puoi usare costanti intere, non contano come nulla.
- Le parentesi per specificare l'ordine delle operazioni sono accettabili.
- È possibile dichiarare funzioni. Le dichiarazioni di funzioni possono essere in qualsiasi stile conveniente per te, ma tieni presente che gli interi a 64 bit sono l' unico tipo di dati valido. Le dichiarazioni di funzione non contano come operazioni, ma una chiamata di funzione conta come una. Inoltre, per essere chiari: le funzioni possono contenere più
return
istruzioni ereturn
sono consentite da qualsiasi punto. Ilreturn
stesso non conta come un'operazione. - È possibile dichiarare le variabili gratuitamente.
- È possibile utilizzare i
while
loop, ma non è possibile utilizzareif
ofor
. Gli operatori utilizzati nellawhile
condizione contano per il tuo punteggio.while
i loop vengono eseguiti fintanto che la loro condizione restituisce un valore diverso da zero (uno 0 "veritiero" in lingue che hanno questo concetto non è un risultato valido). Dall'inizio del ritorno è consentito, si è permesso di usarebreak
pure - Overflow / underflow è consentito e non verrà eseguito alcun blocco del valore. Viene trattato come se l'operazione fosse effettivamente avvenuta correttamente e quindi veniva troncata a 64 bit.
Punteggio / criteri vincenti:
Il tuo codice deve produrre un valore diverso da zero se l'ingresso è una potenza di -2 e zero altrimenti.
Questo è il golf atomico-codice . Il punteggio è il numero totale di operazioni presenti nel codice (come definito sopra), non il numero totale di operazioni eseguite in fase di esecuzione. Il seguente codice:
function example (a, b) {
return a + ~b;
}
function ispowerofnegtwo (input) {
y = example(input, 9);
y = example(y, 42);
y = example(y, 98);
return y;
}
Contiene 5 operazioni: due nella funzione e tre chiamate di funzione.
Non importa come si presenta il risultato, si utilizza qualsiasi cosa sia conveniente nella propria lingua, sia che si tratti in definitiva di archiviare il risultato in una variabile, restituendolo da una funzione o altro.
Il vincitore è il post che è dimostrabilmente corretto (fornire una prova casuale o formale se necessario) e ha il punteggio più basso come descritto sopra.
Bonus Sfida in modalità molto difficile!
Per avere la possibilità di vincere assolutamente nulla, tranne la potenziale capacità di impressionare le persone alle feste, inviare una risposta senza usare while
loop! Se ne vengono presentate abbastanza, potrei anche considerare di dividere i gruppi vincitori in due categorie (con e senza loop).
Nota: se si desidera fornire una soluzione in una lingua che supporta solo numeri interi a 32 bit, è possibile farlo, purché si giustifichi sufficientemente che sarà comunque corretta per i numeri interi a 64 bit in una spiegazione.
Inoltre: alcune funzionalità specifiche della lingua possono essere consentite gratuitamente se non eludono le regole ma sono necessarie per costringere la tua lingua a comportarsi secondo le regole di cui sopra . Ad esempio (inventato), permetterò un confronto libero non uguale a 0 nei while
cicli, se applicato alla condizione nel suo insieme, come soluzione alternativa per un linguaggio che ha "verità" 0. Non sono consentiti chiari tentativi di trarre vantaggio da questi tipi di cose - ad esempio, il concetto di "verità" 0 o di valori "non definiti" non esiste nel set di regole di cui sopra e pertanto non è possibile fare affidamento su di essi.
m ^= s
che sia ancora impressionante, e penso che sarebbe del tutto OK fare la sostituzione per migliorarla ancora di più.
while
e break
ma no if
? if (x) { ... }
è equivalente a while (x) { ... break; }
.
break
e i primi ritorni sono la parte spiacevole) ed è una lunga storia e una lezione appresa nelle regole per le sfide future. C'è sempre la versione "bonus"! :)
if
e for
non sono consentiti? int x=condition; while (x) { ... x=0; }
è gratuito, solo più codice. Stessa cosa con lo stile c for
.