J'ai rencontré ce défi sur Edabit et je n'ai pas pu trouver cette solution d'opération au niveau du bit.
notNotNot = (a,b) => !!(a%2 >> b)
Le défi:
//Something which is not true is false, but something which is not not true is true!
//Create a function where given n number of "not", evaluate whether it's true or false.
//Examples:
notNotNot(1, true) ➞ false
// Not true
notNotNot(2, false) ➞ false
// Not not false
notNotNot(6, true) ➞ true
// Not not not not not not true
J'ai fait des recherches sur cet opérateur:
Décale vers la droite en poussant des copies du bit le plus à gauche à partir de la gauche et laisse tomber les bits le plus à droite.
Que je pense avoir compris (par exemple, le 5 >> 1
même que celui 0101 >> 1
qui évalue 0010
), mais je ne vois pas comment cela fonctionne avec un booléen? Je sais true
évalue vers 1
et false
vers 0
.
javascript
kiabbott
la source
la source
true
=1
(décimal) =01
(binaire) décalé de gauche de un produirait du10
binaire ou du2
décimal.notNotNot(2, true)
: cela reviendrafalse
, mais ce n'est pas vrai (!!true
) devrait êtretrue
...false
se résoudretrue
.notNotNot = (a,b) => !!((a%2)^b)
plutôt ...(a, b) => !!((a + b) % 2)
?Réponses:
La fonction que vous avez donnée ne répond pas au défi. Le décalage à droite ne fera pas ce qui est demandé. Par exemple, votre
notNotNot(6,true)
estfalse
, pastrue
lorsque vous exécutez votre fonction.Votre question concerne le fonctionnement au niveau du bit sur un booléen. Puisque les opérateurs aiment
>>
et<<
travaillent sur des entiers, Javascript convertit d'abord la valeur booléenne en un entier. Devient donctrue
1 etfalse
devient 0. Pour voir cela, vous pouvez décaler de zéro:L'utilisation
!!
est un moyen pratique de convertir n'importe quoi en booléen. Il prend tout ce qui serait considéré comme équivalent à faux (comme 0null
,undefined
ou "") et redonnefalse
. De même, tout ce qui est véridique (comme 14, "bonjour", [4], {a: 1}) et redonnertrue
.!!
fonctionne parce que le premier point d'exclamation donne le «non» de l'expression qui est toujourstrue
oufalse
, alors le deuxième point d'exclamation donne l'opposé de celui (false
outrue
).Pour en revenir au défi, il veut appliquer les temps non-opérateur «a» et comparer à la valeur «b». Donc, quelque chose comme ça fonctionnerait:
la source
if (a % 2 === 1) return !b else return b
mais comme indiqué dans d'autres réponses, il existe des moyens de le faire sans branchement ni boucle.Les opérateurs au niveau du bit convertissent toujours leurs opérandes en un entier. Donc,
4 >> true
c'est la même chose que celle4 >> 1
qui fera un peu de décalage vers la droite d'une positionDonc, utiliser
true
oufalse
n'est qu'un moyen détourné d'utiliser1
ou0
.La
notNotNot
fonction a un fonctionnement très simple, dans l'ensemble:a%2
convertit le premier nombre en0
pair ou1
en impair.>> b
décale vers la droite par des0
positions pourfalse
ou une1
position pourtrue
.a
est impair (1) etb
estfalse
=1
a
est impair (1) etb
esttrue
=0
1
est décalé vers la droite et rejeté.a
est pair (0) etb
estfalse
=0
a
est pair (0) etb
esttrue
=0
0
qui n'a pas de bits, donc le décalage vers la droite ne change rien.!!()
convertit le résultat en booléen.Cela dit, la solution ici est fausse, car
notNotNot(2, true)
produirafalse
-a
est pair etb
esttrue
. On s'attend à ce qu'il produisetrue
depuis!!true = true
. Le même problème est présent pour tout nombre pair ettrue
.Il peut être facilement corrigé en utilisant XOR au niveau du bit au lieu du décalage vers la droite:
a
est impair (1) etb
estfalse
=1
0
a
est impair (1) etb
esttrue
=0
1
a
est pair (0) etb
estfalse
=0
0
a
est pair (0) etb
esttrue
=1
1
Par souci d'exhaustivité, au cas où vous souhaiteriez une opération entièrement au niveau du bit:
L'opération modulo
%2
peut être changée en bit à bit ET&1
obtenir le bit le plus bas. Pour les nombres pairs, cela donnerait0
puisque vous calculeriezce qui est nul. Et pour les nombres impairs, la même chose s'applique, mais vous en obtiendriez un en conséquence:
Les résultats de
a&1
eta%2
sont donc identiques. De plus, même si les opérations au niveau du bit convertissent le nombre en un entier signé 32 bits, cela n'a pas d'importance car la parité serait préservée.Afficher l'extrait de code
la source
Premièrement,
(a,b) => !!(a%2 >> b)
ne correspond pas aux résultats des exemples. Je décomposerai exactement ce qu'il fait en utilisantnotNotNot(6, true) ➞ true
.a%2
, obtenez simplementa
diviser par 2 pour retourner le reste. Nous obtiendrons donc 0 pour un nombre pair et 1 pour un nombre impair.a = 6
a%2 = 0
dans ce cas.0 >> b
passer 1 numéro hors du droit parce que vous avez dittrue
evalue à1
. Donc, nous obtenons0 >> 1 = 0
.!!(0)
, est simple et peut être décomposé comme tel!0 = true
, alors!true = false
.Donc , si nous pensons à ce aussi longtemps que
b
esttrue
, nous seront toujours retournésfalse
. Disons que nous avons a = 5, b = true5%2 = 1
,1 >> 1 = 0
. Vous pouvez voir à cause du mod (%2
) que nous n'aurons que 1 ou 0 (seulement 1 chiffre) et true décalera toujours le 1 lorsque nous l'aurons.Une façon simple de voir ce problème est comme une
isEvenOrNot
fonction. Touta
comme le nombre que nous vérifions etb
vérifions est un booléen pour vérifier s'il est pair (vrai) ou pas (faux). Cela fonctionne car chaque secondenot
ajoutée sera vraie.Ainsi , une solution à l' aide pourrait être quelque chose bitwise comme:
(a,b) => !!(a&1 ^ b)
. Je vous laisse vous amuser à expliquer pourquoi cela fonctionne! :)Un peu plus pour expliquer comment fonctionne shift avec un booléen. Donc,
true
comme vous l'avez dit, ce sera 1 et false sera 0. Ainsi, comme le montre votre exemple,0101 >> true
c'est la même chose que0101 >> 1
.J'espère que ça aide.
J'ai utilisé ce qui suit comme référence pour bitwise: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
la source
NB Pour chaque booléen, un nombre pair de NOTs donne le booléen d'origine et un nombre impair de NOTs donne le booléen opposé
Le LSB de n'importe quel nombre dicte si le nombre est pair ou impair. (0 pair, 1 impair)
la source
Je vois que votre tâche est:
Je ne sais pas pourquoi vous écrivez une
notnotnot
fonction pour moi, ce n'est pas ce que la tâche demande.Donc, selon la tâche que j'ai faite cette fonction
not
qui accepte un certain nombre de «non» et les évalue.La première façon
La deuxième façon d'utiliser XOr (^)
La troisième façon d'utiliser Mod (%) pointée par @VLAZ
La quatrième façon d'utiliser And au niveau du bit (&)
Tester
la source
n
- seulement s'il est pair ou impair, puisque deux NOTs s'annulent,!!!!!b
c'est la même chose que!b
. Par conséquent, nous n'avons pas besoin d'une boucle si nous prenons simplementn%2
- nous obtiendrions1
pour NOT et0
pour "garder la même chose". Puisque nous avons un nombre, nous pouvons simplement effectuer des opérations au niveau du bit.Permet d'abord une solution d'analyse
Maintenant, analyse le pour
(a,b) => !!(a%2 >> b)
Des moyens de Thats cela ne fonctionne pas pour
notNotNot(6, true)
est ,true
mais la solution actuelle donnefalse
.Nous pouvons vous
^
(XOR) opérateur pour le rendre correct(a,b) => !!(a%2 ^ b)
Maintenant, analyse le pour
(a,b) => !!(a%2 ^ b)
Exemple:
la source