Ceci est une version du défi récent. Ce nombre est-il une puissance entière de -2? avec un ensemble différent de critères conçus pour mettre en évidence la nature intéressante du problème et rendre le défi plus difficile. J'y ai réfléchi ici .
Le défi merveilleusement énoncé par Toby dans la question connexe est le suivant:
Il existe des moyens intelligents pour déterminer si un entier est une puissance exacte de 2. Ce n'est plus un problème intéressant, alors déterminons si un entier donné est une puissance exacte de -2 . Par exemple:
-2 => yes: (-2)¹ -1 => no 0 => no 1 => yes: (-2)⁰ 2 => no 3 => no 4 => yes: (-2)²
Règles:
- Un entier est de 64 bits, signé, complément à deux. Il s'agit du seul type de données avec lequel vous pouvez travailler.
- Vous ne pouvez utiliser que les opérations suivantes. Chacune de ces opérations compte pour une opération.
n << k
,n >> k
: Décalage gauche / droiten
park
bits. Le bit de signe est étendu dans le décalage à droite.n >>> k
: Décalage à droite mais sans étendre le bit de signe. Les 0 sont décalés.a & b
,a | b
,a ^ b
: Bitwise ET, OU, XOR.a + b
,a - b
,a * b
: Ajouter, soustraire, multiplier.~b
: Inversion au niveau du bit.-b
: Négation du complément à deux.a / b
,a % b
: Diviser (quotient entier, arrondi vers 0) et modulo.- Le module des nombres négatifs utilise les règles spécifiées en C99 :
(a/b) * b + a%b
doit être égala
. Il en5 % -3
est de même2
et-5 % 3
est-2
: 5 / 3
est1
,5 % 3
est2
, comme 1 * 3 + 2 = 5.-5 / 3
est-1
,-5 % 3
est-2
, comme -1 * 3 + -2 = -5.5 / -3
est-1
,5 % -3
est2
, comme -1 * -3 + 2 = 5.-5 / -3
est1
,-5 % -3
est-2
, comme 1 * -3 + -2 = -5.- Notez que l'
//
opérateur de division de plancher de Python ne satisfait pas ici la propriété de "division vers 0" de la division et que l'%
opérateur de Python ne satisfait pas non plus aux exigences.
- Le module des nombres négatifs utilise les règles spécifiées en C99 :
- Les affectations ne comptent pas comme une opération. Comme en C, les affectations sont évaluées à la valeur du côté gauche après l'affectation:
a = (b = a + 5)
définitb
sura + 5
, puis définita
surb
et compte comme une opération. - Les affectations composées peuvent être utilisées comme des
a += b
moyensa = a + b
et comptent comme une opération.
- Vous pouvez utiliser des constantes entières, elles ne comptent pour rien.
- Les parenthèses pour spécifier l'ordre des opérations sont acceptables.
- Vous pouvez déclarer des fonctions. Les déclarations de fonction peuvent être dans n'importe quel style qui vous convient, mais notez que les entiers 64 bits sont le seul type de données valide. Les déclarations de fonction ne comptent pas comme des opérations, mais un appel de fonction compte comme un. En outre, pour être clair: les fonctions peuvent contenir plusieurs
return
instructions et lesreturn
s de n'importe quel point sont autorisés. Lereturn
lui-même ne compte pas comme une opération. - Vous pouvez déclarer des variables sans frais.
- Vous pouvez utiliser des
while
boucles, mais vous ne pouvez pas utiliserif
oufor
. Les opérateurs utilisés dans lawhile
condition comptent pour votre score.while
les boucles s'exécutent tant que leur condition est évaluée à une valeur non nulle (un 0 "véridique" dans les langues qui ont ce concept n'est pas un résultat valide). Le retour anticipé étant autorisé, vous êtes autorisé à utiliserbreak
aussi bien - Le débordement / sous-dépassement est autorisé et aucun serrage de valeur ne sera effectué. Il est traité comme si l'opération s'est réellement déroulée correctement et a ensuite été tronqué à 64 bits.
Critères de pointage / de victoire:
Votre code doit produire une valeur non nulle si l'entrée est une puissance de -2 et zéro sinon.
C'est le golf à code atomique . Votre score est le nombre total d'opérations présentes dans votre code (tel que défini ci-dessus), et non le nombre total d'opérations exécutées au moment de l'exécution. Le code suivant:
function example (a, b) {
return a + ~b;
}
function ispowerofnegtwo (input) {
y = example(input, 9);
y = example(y, 42);
y = example(y, 98);
return y;
}
Contient 5 opérations: deux dans la fonction et trois appels de fonction.
Peu importe la façon dont vous présentez votre résultat, utilisez ce qui est pratique dans votre langage, que ce soit finalement le stockage du résultat dans une variable, le retour d'une fonction, ou autre.
Le gagnant est le poste qui est manifestement correct (fournissez une preuve occasionnelle ou formelle si nécessaire) et qui a le score le plus bas comme décrit ci-dessus.
Bonus en mode très difficile!
Pour avoir une chance de gagner absolument rien, sauf la capacité potentielle d'impressionner les gens lors des fêtes, soumettez une réponse sans utiliser de while
boucles! Si suffisamment de ceux-ci sont soumis, je peux même envisager de diviser les groupes gagnants en deux catégories (avec et sans boucles).
Remarque: Si vous souhaitez fournir une solution dans une langue qui ne prend en charge que les entiers 32 bits, vous pouvez le faire, à condition de justifier suffisamment qu'elle sera toujours correcte pour les entiers 64 bits dans une explication.
Aussi: Certaines fonctionnalités spécifiques à une langue peuvent être autorisées sans frais si elles n'échappent pas aux règles mais sont nécessaires pour contraindre votre langue à se comporter conformément aux règles ci-dessus . Par exemple (artificiel), je permettrai une comparaison libre non égale à 0 dans les while
boucles, lorsqu'elle est appliquée à la condition dans son ensemble, comme solution de contournement pour une langue qui a des «vrais» 0. Des tentatives claires de tirer parti de ces types de choses ne sont pas autorisées - par exemple, le concept de valeurs "véridiques" 0 ou "non définies" n'existe pas dans le jeu de règles ci-dessus, et il est donc possible de ne pas s'y fier.
m ^= s
c'est toujours impressionnant, et je pense que ce serait tout à fait OK de faire la substitution pour l'améliorer encore plus.while
etbreak
nonif
?if (x) { ... }
est équivalent àwhile (x) { ... break; }
.break
et les retours précoces sont la partie regrettable) et c'est une longue histoire et une leçon apprise dans les règles pour les défis futurs. Il y a toujours la version "bonus"! :)if
etfor
sont refusés?int x=condition; while (x) { ... x=0; }
est gratuit, juste plus de code. Même chose avec c stylefor
.Réponses:
C ++, 15 opérations
Je ne sais pas pourquoi les
while
boucles sont autorisées car elles détruisent l'ensemble du défi. Voici une réponse sans aucune:la source
while
boucles détruisent-elles tout le défi ?while
va à l'encontre de cela dans tous les sens.n
ou quelque chose.uint64_t
parce que c'est le seul moyen d'obtenir le bon décalage sans extension de signe.)Python 2 , 3 opérations
Essayez-le en ligne!
Les opérations sont
>>
,&
,/
.L'idée est de diviser à plusieurs reprises par -2. Pouvoirs de -2 à chaîne vers le bas à 1:
-8 -> 4 -> -2 -> 1
. Si nous frappons un1
, acceptez. Si nous frappons un nombre impair avant de frapper1
, rejetez. Nous devons également rejeter0
ce qui va pour toujours à lui-même.Les
while n>>1:
boucles jusqu'àn
est 0 ou 1. Lorsque la boucle se rompt,n
elle-même est renvoyée et1
est une sortie Truthy et0
Falsey. À l'intérieur de la boucle, nous refusons d'appliquer à plusieurs reprisesn -> n/-2
et rejetons toute impairen
.Étant donné que le
/
n'est utilisé que sur des valeurs paires, son comportement d'arrondi n'entre jamais en jeu. Donc, peu importe que Python arrondisse différemment de la spécification.la source
while n&1
au lieu deif n&1
?if
.Rouille,
1412 opérations (pas de boucles)Nécessite une optimisation (
-O
) ou-C overflow-checks=no
pour activer la soustraction débordante au lieu de la panique.(Pour clarifier:
!x
est bit à bit-PAS ici, pas logique-PAS)Cas de test:
Essayez-le en ligne!
L'idée est de vérifier si | x | est une puissance de 2 (à utiliser
(y & (y - 1)) == 0
comme d'habitude). Si x est une puissance de 2, alors nous vérifions en outre (1) quandx >= 0
, ce devrait également être une puissance paire de 2, ou (2) quandx < 0
, ce devrait être une puissance impaire de 2. Nous vérifions cela en&
-ing le "bad_power_of_two
"masque 0x… aaaa quandx >= 0
(produit 0 seulement quand il s'agit d'une puissance paire), ou 0x… 5555 quandx < 0
.la source
~((r | -r) >> 63)
astuce pour finir de corriger ma réponse.Haskell,
23 opérationsDéfinit une fonction récursive
f(n)
. Les opérations utilisées sont appel de fonction (f
), division (div
) et au niveau du bit et (.&.
).Ne contient pas de boucles car Haskell n'a pas d'instructions de boucle :-)
la source
f 0
,f 1
,f n ...
ici parce qu'ils sont essentiellementif
est déguisé, bien que là encore, je ne permetswhile
+break
et au débutreturn
de, il semble donc juste. Bien qu'il semble profiter de mon jeu de règles laissé par inadvertance ouvert à l'interprétation, c'est une bonne solution.|
s sont particulièrement en l'air. Cela dit, cela viole une règle particulière de manière moins discutable: la comparaison==
n'est pas autorisée. Notez toutefois que si mon interprétation de ce code est correct, l'utilisation de booléens ici ne semble acceptable en substituant des valeurs entières arbitraires à leur place ne semble pas changer les résultats, et ils sont plus d'une forme de présentation finale.==
parce qu'il n'y a pas d' autre moyen de fonte deInt
laBool
ou « Truthy » dans Haskell. Que l'appariement des motifs et les gardes enfreignent laif
règle du "non s" est votre appel ;-)Opérations Python 3,
10 ou 119Retourne
5
pour les pouvoirs de-2
,0
sinonla source
C, 5 opérations
C, 10 opérations, sans boucles
C, 1 opération
la source
Assemblage, 1 opération
Utilise une énorme table de recherche pour déterminer si le nombre est une puissance de 2. Vous pouvez l'étendre à 64 bits, mais trouver un ordinateur pour stocker autant de données est laissé au lecteur comme exercice :-P
la source
C, 31 opérations
Démo en direct
Mon idée est simple, si c'est une puissance de deux, alors si son log est pair alors il doit être positif, sinon son log doit être impair.
la source
C, 7 opérations
ou:
C, 13 opérations sans boucles en tant que conditions
Explication:
n&-n
donne le bit de jeu le plus bas den
.a
est la valeur absolue niée den/2
, nécessairement négative car/2
empêche le débordement de la négation.a/x
est nul seulement sia
est une puissance exacte de deux; sinon au moins un autre bit est défini, et il est supérieur àx
au bit le plus bas, ce qui donne un résultat négatif.~(a/x >> 63)
donne alors un masque de bits qui est tout-si sin
ou-n
est une puissance de deux, sinon tout-zéros.^s
est appliqué au masque pour vérifier le signe den
pour voir s'il s'agit d'une puissance de-2
.la source
PHP, 3 opérations
ternaire et
if
sont interdits; alors abusonswhile
:$n>>1
: si le nombre est 0 ou 1, renvoie le numéro$n&1
: si le nombre est impair, retourne 0$n/-2
(+ transtypage en entier)la source
JavaScript ES6, 7 opérations
Essayez-le en ligne!
Explication
Alors que x! = 0 et x% 2 == 0 4 ops
x / x est égal à 1 tant que x n'est pas 0 (0/0 donne NaN qui est évalué comme faux)
& au niveau du bit et
x & 1 ^ 1 est égal à 1 si x est pair (x et 1) xou 1
C'est la forme de division définie par la question 1 op
Tandis que x! = 1 et x! = 0 1 op
La condition requise pour sortir lorsque x == 0 ou x == 1 car ces deux sont les valeurs de retour et entrer dans une boucle infinie ne serait pas productive. Cela pourrait théoriquement être étendu pour des valeurs plus élevées en augmentant le nombre hexadécimal. Fonctionne actuellement jusqu'à ± 2 ^ 32-1
Mettre x à 0 1 op
Alors que j'aurais pu utiliser return 0 pour 0 ops, je sentais que toute boucle while qui est rompue par une autre instruction ressemble trop à de la triche.
renvoie x (1 si puissance de -2, 0 sinon)
la source