operator operadores not logicos diferente bitwise language-agnostic logic boolean xor boolean-expression

language-agnostic - operadores - xor c#



XOR de tres valores (7)

¿Cuál es la forma más simple de hacer un quirófano exclusivo de tres vías?

En otras palabras, tengo tres valores, y quiero una declaración que evalúe a IFF verdadero, solo uno de los tres valores es verdadero.

Hasta ahora, esto es lo que se me ocurrió:

((a ^ b) && (a ^ c) &&! (b && c)) || ((b ^ a) && (b ^ c) &&! (a && c)) || ((c ^ a) && (c ^ b) &&! (a && b))

¿Hay algo más simple para hacer lo mismo?

Aquí está la prueba de que lo anterior logra la tarea:

a = true; b = true; c = true ((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b)) => false a = true; b = true; c = false ((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b)) => false a = true; b = false; c = true ((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b)) => false a = true; b = false; c = false ((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b)) => true a = false; b = true; c = true ((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b)) => false a = false; b = true; c = false ((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b)) => true a = false; b = false; c = true ((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b)) => true a = false; b = false; c = false ((a ^ b) && (a ^ c) && !(b && c)) || ((b ^ a) && (b ^ c) && !(a && c)) || ((c ^ a) && (c ^ b) && !(a && b)) => false


Aquí hay una implementación general que falla rápidamente cuando se encuentra que más de un bool es true .

Uso :

XOR(a, b, c);

Código :

public static bool XOR(params bool[] bools) { return bools.Where(b => b).AssertCount(1); } public static bool AssertCount<T>(this IEnumerable<T> source, int countToAssert) { int count = 0; foreach (var t in source) { if (++count > countToAssert) return false; } return count == countToAssert; }


Otra posibilidad:

a ? !b && !c : b ^ c

que resulta ser 9 caracteres más cortos que la respuesta aceptada :)


Para exactamente tres términos, puede usar esta expresión:

(a ^ b ^ c) && !(a && b && c)

La primera parte es true si uno o tres de los términos son true . La segunda parte de la expresión garantiza que no todos los tres son true .

Tenga en cuenta que la expresión anterior NO se generaliza a más términos. Una solución más general es contar realmente cuántos términos son true , así que algo como esto:

int trueCount = (a ? 1 : 0) + (b ? 1 : 0) + (c ? 1 : 0) + ... // more terms as necessary return (trueCount == 1); // or some range check expression etc


También puedes probar (en C):

!!a + !!b + !!c == 1


a^b^c es solo 1 si un número impar de variables es 1 (dos ''1'' se cancelarían mutuamente). Entonces solo necesita verificar el caso "los tres son 1":

result = (a^b^c) && !(a&&b&&c)


bool result = (a?1:0)+(b?1:0)+(c?1:0) == 1;


f= lambda{ |a| [false, false, true].permutation.to_a.uniq.include? a } p f.call([false, true, false]) p f.call([false, true, true])

$ true

$ falso

Porque puedo.