Encontré este desafío en Edabit y no pude resolver esta solución de operación bit a bit.
notNotNot = (a,b) => !!(a%2 >> b)
El reto:
//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
Investigué un poco que ese operador:
Se desplaza hacia la derecha empujando copias del bit más a la izquierda desde la izquierda, y deja que los bits más a la derecha se caigan.
Creo que entendí (por ejemplo, lo 5 >> 1
mismo 0101 >> 1
que evalúa 0010
), pero no puedo ver cómo funciona eso con un booleano. Sé que true
evalúa a 1
y false
a 0
.
javascript
kiabbott
fuente
fuente
true
=1
(decimal) =01
(binario) desplazado a la izquierda por uno produciría10
binario o2
decimal.notNotNot(2, true)
: volveráfalse
, pero no es cierto (!!true
) debería sertrue
...false
resolucióntrue
.notNotNot = (a,b) => !!((a%2)^b)
cambio ...(a, b) => !!((a + b) % 2)
?Respuestas:
La función que le diste no satisface el desafío. El desplazamiento correcto no hará lo que se le pide. Por ejemplo, su
notNotNot(6,true)
esfalse
, notrue
cuando pasa a través de su función.Sin embargo, su pregunta es sobre la operación bit a bit en un booleano. Como a los operadores les gusta
>>
y<<
trabajan con enteros, Javascript primero convierte el valor booleano en un entero. Entonces setrue
convierte en 1 y sefalse
convierte en 0. Para ver esto, puede cambiar por cero:Usar
!!
es una forma práctica de convertir cualquier cosa en un booleano. Se necesita cualquier cosa que se considere equivalente a falso (como 0null
,undefined
o "") y se devuelvefalse
. Del mismo modo, todo lo que sea verdadero (como 14, "hola", [4], {a: 1}) y devolvertrue
.!!
funciona porque el primer signo de exclamación da el 'no' de la expresión que siempre estrue
ofalse
, luego el segundo signo de exclamación da lo contrario de eso (false
otrue
).Volviendo al desafío, quiere aplicar el no operador 'a' veces y compararlo con el valor 'b'. Entonces algo como esto funcionaría:
fuente
if (a % 2 === 1) return !b else return b
pero allí, como se muestra en otras respuestas, hay maneras de hacerlo sin ramificaciones ni bucles.Los operadores bit a bit siempre convierten sus operandos a un número entero. Entonces,
4 >> true
es lo mismo4 >> 1
que hará un poco de cambio en una posiciónEntonces, usar
true
ofalse
es solo una forma indirecta de usar1
o0
.La
notNotNot
función tiene una operación muy simple, en general:a%2
convierte el primer número en0
par o1
impar.>> b
desplaza a la derecha por0
posiciones parafalse
o1
posición paratrue
.a
es impar (1) yb
esfalse
=1
a
es impar (1) yb
estrue
=0
1
se desplaza hacia la derecha y se descarta.a
es par (0) yb
esfalse
=0
a
es par (0) yb
estrue
=0
0
que no tiene ningún bit establecido, por lo que desplazar a la derecha cualquier cantidad no lo cambia.!!()
convierte el resultado a booleano.Dicho esto, la solución aquí es incorrecta, ya
notNotNot(2, true)
que produciráfalse
,a
es uniforme yb
estrue
. La expectativa es que producirátrue
desde entonces!!true = true
. El mismo problema está presente para cualquier número par ytrue
.Se puede arreglar fácilmente usando XOR bit a bit en lugar del desplazamiento a la derecha:
a
es impar (1) yb
esfalse
=1
0
a
es impar (1) yb
estrue
=0
1
a
es par (0) yb
esfalse
=0
0
a
es par (0) yb
estrue
=1
1
Solo por completo, en caso de que desee una operación totalmente bit a bit:
La operación del módulo
%2
se puede cambiar a bit a bit Y&1
obtener el bit más bajo. Para números pares, esto produciría0
ya que estarías calculandoque es cero Y para números impares se aplica lo mismo, pero como resultado obtendría uno:
Entonces los resultados de
a&1
ya%2
son idénticos. Además, a pesar de que las operaciones bit a bit convierten el número a un entero con signo de 32 bits que no importa, ya que se preservaría la paridad .Mostrar fragmento de código
fuente
En primer lugar,
(a,b) => !!(a%2 >> b)
no coincide con los resultados de los ejemplos. Desglosaré exactamente lo que está haciendo usandonotNotNot(6, true) ➞ true
.a%2
, simplementea
divide entre 2 y devuelve el resto. Entonces obtendremos 0 para un número par y 1 para un número impar.a = 6
a%2 = 0
en este caso.0 >> b
desplace 1 número desde la derecha porque, como dijo, setrue
evalúa como1
. Entonces lo conseguimos0 >> 1 = 0
.!!(0)
, es simple y puede desglosarse así!0 = true
, entonces!true = false
.Así que si pensamos en esto el tiempo que
b
estrue
, que siempre llegan regresamosfalse
. Digamos que tenemos a = 5, b = true evaluar a5%2 = 1
,1 >> 1 = 0
. Puede ver que debido al mod (%2
) solo tendremos 1 o 0 (solo tendremos 1 dígito) y verdadero siempre se desviará del 1 cuando lo tengamos.Una manera simple de ver este problema es como una
isEvenOrNot
función. Entonces,a
es el número que estamos verificando yb
es un valor booleano para verificar si es par (verdadero) o incluso par (falso). Esto funciona porque cada segundonot
agregado será cierto.Por lo tanto el uso de una solución a nivel de bits podría ser algo como:
(a,b) => !!(a&1 ^ b)
. ¡Te dejaré divertirte al analizar por qué funciona! :)Un poco más para explicar cómo funciona shift con un booleano. Entonces,
true
como dijiste, será 1 y falso será 0. Entonces, como se muestra en tu ejemplo,0101 >> true
es lo mismo que0101 >> 1
.Espero que esto ayude.
Usé lo siguiente como referencia para bitwise: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
fuente
Nota: para cualquier booleano, un número par de NOT da como resultado el booleano original y un número impar de NOT da como resultado el booleano opuesto
El LSB de cualquier número dicta si el número es impar o par. (0 par, 1 impar)
fuente
Veo que tu tarea es:
No sé por qué estás escribiendo una
notnotnot
función para mí que no es lo que pide la tarea.Entonces, de acuerdo con la tarea, hice esa función
not
que acepta una serie de "nots" y los evalúa.La primera forma
La segunda forma usando XOr (^)
La tercera forma usando Mod (%) señalado por @VLAZ
La cuarta forma usando bitwise Y (&)
Prueba
fuente
n
, solo si es par o impar, ya que cualquiera de los dos NOT se cancela, por lo que!!!!!b
es lo mismo!b
. Por lo tanto, no necesitamos un bucle si solo tomamosn%2
: obtendríamos1
NOT y0
para "mantenerlo igual". Como tenemos un número, solo podemos hacer operaciones bit a bit.Deja la solución de análisis primero
Ahora analice el para
(a,b) => !!(a%2 >> b)
Thats medios esto no está funcionando para
notNotNot(6, true)
estrue
, pero da solución actualfalse
.Podemos usted
^
(XOR) operador para que sea correcto Me gusta(a,b) => !!(a%2 ^ b)
Ahora analice el para
(a,b) => !!(a%2 ^ b)
Ejemplo:
fuente