Cómo definir "o" lógicamente

36

Recientemente, me encontré con un problema que me obligaba a definir el operador lógico "OR" mediante programación, pero sin usar el operador en sí.

Lo que se me ocurrió es esto:

OR(arg1, arg2)
  if arg1 = True and arg2 = True
     return True

  else if arg1 = True and arg2 = False
     return True

  else if arg1 = False and arg2 = True
     return True

  else:
     return False

¿Es correcta esta lógica o me perdí algo?

logicNoob
fuente
10
@gnat: Para ser justos, una tabla de verdad enumera los resultados para cada combinación de las entradas y el artículo de Wikipedia da una descripción de la función. Creo que lo que realmente pregunta el OP es cómo definir un OR lógico o programáticamente sin el uso del operador en sí.
Blrfl
66
@ user3687688 ¿Puede aclarar las primitivas que podemos usar?
fredoverflow
44
esta pregunta ha comenzado un espasmo colectivo de micro-optimización;)
Rob
8
Podrías usar el operador ternarioreturn arg1 ? arg1 : arg2;
Matthew
44
Tengo que saber por qué necesita redefinir el oroperador.
Kyle Strand

Respuestas:

102

Yo diría que es correcto, pero ¿no podrías condensarlo en algo como esto?

or(arg1, arg2)
    if arg1 == true
        return true
    if arg2 == true
        return true

    return false

Como estás haciendo una comparación, no creo que realmente necesites verificar la combinación. Solo importa si uno de ellos es verdadero para volverlo verdadero. De lo contrario, queremos devolver falso.

Si está buscando una versión más corta que sea menos detallada, esto también funcionará:

or(arg1, arg2)
    if arg1
        return arg1
    return arg2
Elliot Blackburn
fuente
66
También puede eliminar el "else" en la línea 4 (dejando solo if arg2 == true).
Dawson Toth
1
@DawsonToth Hay muchas maneras diferentes en que puedes girarlo, depende si realmente quieres ser detallado o condensado. Sería feliz con lo demás si, pero parece que esta es una pregunta de pseudocódigo, por lo que probablemente lo dejaría así para mayor claridad. Muy cierto sin embargo!
Elliot Blackburn
@BlueHat Parece un poco inconsistente usar un if si, pero no un else al final.
SBoss
1
@Mehrdad Gracias! He incluido la respuesta anterior solo porque siento que es un poco más detallado y explica la solución un poco más clara. Pero su solución es mucho más pequeña y hace el mismo trabajo.
Elliot Blackburn
1
aún mejor (peor):or(a, b): a ? a : b
sara
149

Aquí hay una solución sin o, y, no, comparaciones y literales booleanos:

or(arg1, arg2)
  if arg1
    return arg1
  else
    return arg2

Probablemente no sea mucho más fundamental que eso;)

flujo libre
fuente
32
+1 para una respuesta un poco más corta que la mía. Sin embargo, estaría tentado a soltar el "más" también por elegancia.
Elliot Blackburn
10
@BlueHat Pero entonces los dos retornos se
sangrarían de manera
55
Me gustaría obtener un EUR cada vez que alguien compara algo con trueo false.
JensG
1
@JensG Bueno, ¿de dónde crees que provienen los ingresos de Bill Gates?
Kroltan
1
||Operador de JavaScript en pocas palabras (cuando se implementa en un lenguaje de tipo dinámico).
rinoceronte
108

Una línea de código:

return not (not arg1 and not arg2)

Sin ramificaciones, sin OR.

En un lenguaje basado en C, sería:

return !(!arg1 && !arg2);

Esto es simplemente una aplicación de las leyes de De Morgan :(A || B) == !(!A && !B)


fuente
66
Creo que este enfoque es la mejor solución ya que (en mi opinión) una if/elseconstrucción es lo mismo que usar OR, solo que con un nombre diferente.
Nick
2
@Nick usando ifes equivalente a la igualdad. Normalmente, en el código de máquina, un ifse implementa como aritmética seguido de una comparación a cero con un salto.
66
Para referencia: en.wikipedia.org/wiki/De_Morgan%27s_laws
Mephy
1
Me gusta este enfoque porque cortocircuita los cortocircuitos IFF and, proporcionando así consistencia entre los operadores.
Kyle Strand
1
@Snowman Eso es cierto. Quise decir que if (a) return true; else if (b) return true;parece más o menos moralmente equivalente a if (a OR b) return true;, pero esa opinión puede estar abierta a disputas.
Nick
13

Si solo tiene andy not, puede usar la ley de DeMorgan para cambiar and:

if not (arg1 = False and arg2 = False)
  return True
else
  return False

... o (aún más simple)

if arg1 = False and arg2 = False
  return false
else
  return true

...

Y dado que aparentemente todos nos hemos obsesionado con la optimización de algo que casi siempre está disponible como una instrucción de máquina, eso se reduce a:

return not(not arg1 and not arg2)

return arg1 ? true : arg2

etc. etc. etc. etc.

Como la mayoría de los idiomas proporcionan un condicional y, las probabilidades son el operador "y" implica una rama de todos modos.

...

Si todo lo que tienes es nand(ver wikipedia ):

return nand (nand (arg1, arg1), nand (arg2, arg2))

Robar
fuente
77
Simplifique:return not (not arg1 and not arg2)
@Snowman, realmente deberías responder eso para que yo pueda votarlo. Usted es (actualmente) el único aquí que no fue con ramificación.
Lawtonfogle
44
Iba a agregar la solución NAND, pero me ganaste. Todo debe implementarse en términos de NAND.
Andy
2
@Andy: En realidad, todo debería definirse en términos de NOR. ;-)
Pieter Geerkens
1
Buen trabajo con la nandsolución pura .
AAT
13

Funciones (ECMAScript)

Todo lo que necesita son definiciones de funciones y llamadas a funciones. No necesita ninguna ramificación, condicionales, operadores o funciones integradas. Demostraré una implementación usando ECMAScript.

Primero, definamos dos funciones llamadas truey false. Podríamos definirlos de la forma que queramos, son completamente arbitrarios, pero los definiremos de una manera muy especial que tiene algunas ventajas como veremos más adelante:

const tru = (thn, _  ) => thn,
      fls = (_  , els) => els;

trues una función con dos parámetros que simplemente ignora su segundo argumento y devuelve el primero. flsTambién es una función con dos parámetros que simplemente ignora su primer argumento y devuelve el segundo.

¿Por qué codificamos truy de flsesta manera? Bueno, de esta manera, las dos funciones no solo representan los dos conceptos truey false, no, al mismo tiempo, también representan el concepto de "elección", en otras palabras, ¡también son una expresión if/ then/ else! Evaluamos la ifcondición y le pasamos el thenbloque y el elsebloque como argumentos. Si la condición se evalúa como tru, devolverá el thenbloque, si se evalúa como fls, devolverá el elsebloque. Aquí hay un ejemplo:

tru(23, 42);
// => 23

Esto vuelve 23, y esto:

fls(23, 42);
// => 42

vuelve 42, tal como es de esperar.

Sin embargo, hay una arruga:

tru(console.log("then branch"), console.log("else branch"));
// then branch
// else branch

Esto imprime ambos then branch y else branch! ¿Por qué?

Bueno, devuelve el valor de retorno del primer argumento, pero evalúa ambos argumentos, ya que ECMAScript es estricto y siempre evalúa todos los argumentos de una función antes de llamar a la función. IOW: evalúa el primer argumento que es console.log("then branch"), que simplemente regresa undefinedy tiene el efecto secundario de imprimir then branchen la consola, y evalúa el segundo argumento, que también regresa undefinede imprime en la consola como un efecto secundario. Luego, devuelve el primero undefined.

En el cálculo λ, donde se inventó esta codificación, eso no es un problema: el cálculo λ es puro , lo que significa que no tiene efectos secundarios; por lo tanto, nunca notarías que el segundo argumento también se evalúa. Además, el cálculo λ es perezoso (o al menos, a menudo se evalúa en orden normal), lo que significa que en realidad no evalúa argumentos que no son necesarios. Entonces, IOW: en el cálculo λ, el segundo argumento nunca sería evaluado, y si lo fuera, no lo notaríamos.

ECMAScript, sin embargo, es estricto , es decir, siempre evalúa todos los argumentos. Bueno, en realidad, no siempre: el if/ then/ else, por ejemplo, solo evalúa la thenrama si la condición es truey solo evalúa la elserama si la condición es false. Y queremos replicar este comportamiento con nuestro iff. Afortunadamente, a pesar de que ECMAScript no es perezoso, tiene una forma de retrasar la evaluación de un fragmento de código, de la misma manera que lo hace casi cualquier otro idioma: envolverlo en una función, y si nunca llama a esa función, el código lo hará Nunca ser ejecutado.

Entonces, envolvemos ambos bloques en una función, y al final llamamos a la función que se devuelve:

tru(() => console.log("then branch"), () => console.log("else branch"))();
// then branch

impresiones then branchy

fls(() => console.log("then branch"), () => console.log("else branch"))();
// else branch

impresiones else branch.

Podríamos implementar el if/ then/ tradicional de elseesta manera:

const iff = (cnd, thn, els) => cnd(thn, els);

iff(tru, 23, 42);
// => 23

iff(fls, 23, 42);
// => 42

Nuevamente, necesitamos un ajuste de función adicional al llamar a la ifffunción y los paréntesis de llamada de función adicional en la definición de iff, por la misma razón que arriba:

const iff = (cnd, thn, els) => cnd(thn, els)();

iff(tru, () => console.log("then branch"), () => console.log("else branch"));
// then branch

iff(fls, () => console.log("then branch"), () => console.log("else branch"));
// else branch

Ahora que tenemos esas dos definiciones, podemos implementar or. Primero, miramos la tabla de verdad para or: si el primer operando es verdadero, entonces el resultado de la expresión es el mismo que el primer operando. De lo contrario, el resultado de la expresión es el resultado del segundo operando. En resumen: si el primer operando es true, devolvemos el primer operando, de lo contrario devolvemos el segundo operando:

const orr = (a, b) => iff(a, () => a, () => b);

Veamos que funciona:

orr(tru,tru);
// => tru(thn, _) {}

orr(tru,fls);
// => tru(thn, _) {}

orr(fls,tru);
// => tru(thn, _) {}

orr(fls,fls);
// => fls(_, els) {}

¡Excelente! Sin embargo, esa definición se ve un poco fea. Recuerde, truy flsya actúa como un condicional por sí mismo, por lo que realmente no es necesario iffy, por lo tanto, toda esa función se ajusta:

const orr = (a, b) => a(a, b);

Ahí lo tiene: or(más otros operadores booleanos) definidos con nada más que definiciones de funciones y llamadas de funciones en solo un puñado de líneas:

const tru = (thn, _  ) => thn,
      fls = (_  , els) => els,
      orr = (a  , b  ) => a(a, b),
      nnd = (a  , b  ) => a(b, a),
      ntt = a          => a(fls, tru),
      xor = (a  , b  ) => a(ntt(b), b),
      iff = (cnd, thn, els) => cnd(thn, els)();

Desafortunadamente, esta implementación es bastante inútil: no hay funciones u operadores en ECMAScript que regresen truo fls, todos regresan trueo false, por lo que no podemos usarlos con nuestras funciones. Pero todavía hay mucho que podemos hacer. Por ejemplo, esta es una implementación de una lista vinculada individualmente:

const cons = (hd, tl) => which => which(hd, tl),
      car  = l => l(tru),
      cdr  = l => l(fls);

Objetos (Scala)

Es posible que haya notado algo peculiar: truy flsdesempeñan un doble papel, actúan como valores de datos truey false, al mismo tiempo, también actúan como una expresión condicional. Son datos y comportamiento , agrupados en un ... uhm ... "cosa" ... ¡u (me atrevo a decir) objeto !

De hecho, truy flsson objetos. Y, si alguna vez ha utilizado Smalltalk, Self, Newspeak u otros lenguajes orientados a objetos, habrá notado que implementan booleanos exactamente de la misma manera. Demostraré tal implementación aquí en Scala:

sealed abstract trait Buul {
  def apply[T, U <: T, V <: T](thn: ⇒ U)(els: ⇒ V): T
  def &&&(other:Buul): Buul
  def |||(other:Buul): Buul
  def ntt: Buul
}

case object Tru extends Buul {
  override def apply[T, U <: T, V <: T](thn: ⇒ U)(els: ⇒ V): U = thn
  override def &&&(other:Buul) = other
  override def |||(other:Buul): this.type = this
  override def ntt = Fls
}

case object Fls extends Buul {
  override def apply[T, U <: T, V <: T](thn: ⇒ U)(els: ⇒ V): V = els
  override def &&&(other:Buul): this.type = this
  override def |||(other:Buul) = other
  override def ntt = Tru
}

object BuulExtension {
  import scala.language.implicitConversions
  implicit def boolean2Buul(b:Boolean) = if (b) Tru else Fls
}

import BuulExtension._

(2 < 3) { println("2 is less than 3") } { println("2 is greater than 3") }
// 2 is less than 3

Por cierto, la refactorización Reemplazar condicional por polimorfismo siempre funciona: siempre puede reemplazar todos y cada uno de los condicionales en su programa con envío de mensajes polimórficos, porque como acabamos de mostrar, el envío de mensajes polimórficos puede reemplazar condicionales simplemente implementándolos. Idiomas como Smalltalk, Self y Newspeak son prueba de la existencia de eso, porque esos idiomas ni siquiera tienen condicionales. (Tampoco tienen bucles, por cierto, o realmente ningún tipo de estructuras de control incorporadas en el lenguaje, excepto el envío de mensajes polimórficos, también llamadas de método virtual).


Coincidencia de patrones (Haskell)

También podría definir el oruso de la coincidencia de patrones, o algo así como las definiciones de funciones parciales de Haskell:

True ||| _ = True
_    ||| b = b

Por supuesto, la coincidencia de patrones es una forma de ejecución condicional, pero, de nuevo, también lo es el envío de mensajes orientado a objetos.

Jörg W Mittag
fuente
2
¿Qué tal False ||| False = Falsey en su _ ||| _ = Truelugar? :)
fredoverflow
3
@FredOverflow: Eso requeriría siempre evaluar el operando correcto. Por lo general, se espera que los operadores booleanos no sean estrictos en su argumento correcto, también conocido como "cortocircuito".
Jörg W Mittag
Ah, por supuesto. Sabía que tenía que haber una razón más profunda :)
fredoverflow
La primera parte me recordó de inmediato la gran serie de Eric Lippert sobre el estilo de pase de continuación . Pura coincidencia pero aún divertido :)
Voo
1
La definición de @ JörgWMittag FredOverflow está apropiadamente en cortocircuito. Pruébalo True ||| undefineden ghci para ver!
Daniel Wagner
3

Aquí hay otra forma de definir OR, o de hecho cualquier operador lógico, usando la forma más tradicional de definirlo: use una tabla de verdad.

Por supuesto, esto es bastante trivial en lenguajes de nivel superior como Javascript o Perl, pero estoy escribiendo este ejemplo en C para mostrar que la técnica no depende de las características del lenguaje de alto nivel:

#include <stdio.h>

int main (void) {
    // Define truth table for OR:
    int OR[2][2] = {
        {0,   // false, false
         1},  // false, true
        {1,   // true, false
         1}   // true, true
    }

    // Let's test the definition
    printf("false || false = %d\n",OR[1==2]['b'=='a']);
    printf("true || false = %d\n",OR[10==10]['b'=='a']);

    // Usage:
    if (OR[ 1==2 ][ 3==4 ]) {
        printf("at least one is true\n");
    }
    else {
        printf("both are false\n");
    }
}

Puede hacer lo mismo con AND, NOR, NAND, NOT y XOR. El código es lo suficientemente limpio como para parecerse a la sintaxis, de modo que puede hacer cosas como esta:

if (OR[ a ][ AND[ b ][ c ] ]) { /* ... */ }
slebetman
fuente
Creo que este es el enfoque "más puro" en cierto sentido matemático. El operador OR es una función después de todo, y la tabla de verdad es realmente la esencia de esa función como una relación y un conjunto. Por supuesto, esto también podría escribirse de una manera divertida:BinaryOperator or = new TruthTableBasedBinaryOperator(new TruthTable(false, true, true, true));
VENIDO DEL
3

Otra forma de expresar los operadores lógicos como expresiones aritméticas de enteros (cuando sea posible). De esta manera puede evitar muchas ramificaciones para una expresión más amplia de muchos predicados.

Deje que True sea 1 Deje que False sea 0

Si la suma de ambos es mayor que 1, es verdadero o falso ser devuelto.

boolean isOR(boolean arg1, boolean arg2){

   int L = arg1 ? 1 : 0;
   int R = arg2 ? 1 : 0;

   return (L+R) > 0;

}
Senthu Sivasambu
fuente
66
booleanExpression ? true : falsees trivialmente igual a booleanExpression.
Keen
Me gusta su metodología, pero un simple error es que la suma de ambos argumentos debe ser mayor que CERO para ser verdad, no mayor que UNO.
gracia el
1
return (arga+argb)>0
Grantly
1
Solo estaba corrigiendo tu texto. Su código es perfecto, pero podría estar en una línea: return (((arg1 ? 1 : 0)+(arg2 ? 1 : 0)) > 0); :)
Grantly
1
@SenthuSivasambu No tengo objeciones a su uso de arg1 ? 1 : 0;. Esas son expresiones confiables para transformar un booleano en un número. Es solo la declaración de devolución la que se puede refactorizar trivialmente.
Keen
1

Las dos formas:

OR(arg1, arg2)
  if arg1
     return True
  else:
     return arg2

O

OR(arg1, arg2)
  if arg1
     return arg1
  else:
     return arg2

Además del código, tiene la ventaja de ser un poco más pequeño que las otras sugerencias hasta ahora, una rama menos. Ni siquiera es tan tonto una microopción para reducir el número de ramas si consideramos la creación de una primitiva que, por lo tanto, se usaría mucho.

La definición de Javascript de ||es similar a esto, lo que combinado con su escritura suelta significa que la expresión false || "abc"tiene el valor "abc"y 42 || "abc"tiene el valor 42.

Sin embargo, si ya tiene otros operadores lógicos, los gustos de nand(not(arg1), not(arg2))podría tener la ventaja de no tener ninguna ramificación.

Jon Hanna
fuente
¿Cuál es el punto de repetir la respuesta anterior ( como admitiste )?
mosquito
@gnat está lo suficientemente cerca como para no haberme molestado si hubiera visto esa respuesta, pero todavía tiene algo que no se encuentra en ninguno de ellos, así que lo dejo.
Jon Hanna
@gnat, considerando realmente "Estamos buscando respuestas largas que brinden alguna explicación y contexto". Estoy más feliz con esta respuesta ahora.
Jon Hanna
1

Además de todas las soluciones programadas que utilizan la construcción if, es posible construir una puerta OR combinando tres puertas NAND. Si quieres ver cómo se hace en wikipedia, haz clic aquí .

De esto, la expresión,

NO [NO (A Y A) Y NO (B Y B)]

que usa NOT y AND da la misma respuesta que OR. Tenga en cuenta que el uso de NOT y AND es solo una forma oscura de expresar NAND.

Walter Mitty
fuente
NO (A Y A) == ¿NO (A)?
Charlie
Sí exactamente. En el mismo artículo de Wikipedia, puedes ver cómo reducen una puerta NO a las puertas NAND. Lo mismo para una puerta AND. Elegí no editar la fórmula que presentaron para la puerta OR.
Walter Mitty
1

Todas las buenas respuestas ya han sido dadas. Pero no dejaré que eso me detenga.

// This will break when the arguments are additive inverses.
// It is "cleverness" like this that's behind all the most amazing program errors.
or(arg1, arg2)
    return arg1 + arg2
    // Or if you need explicit conversions:
    // return (bool)((short)arg1 + (short)arg2)

Alternativamente:

// Since `0 > -1`, negative numbers will cause weirdness.
or(arg1, arg2)
    return max(arg1, arg2)

Espero que nadie use enfoques como estos. Están aquí solo para promover el conocimiento de las alternativas.

Actualizar:

Dado que los números negativos pueden romper los dos enfoques anteriores, aquí hay otra sugerencia horrible:

or(arg1, arg2)
    return !(!arg1 * !arg2)

Esto simplemente usa las Leyes de DeMorgan y abusa del hecho que *es similar a &&cuándo truey falseson tratados como 1y 0respectivamente. (Espera, ¿estás diciendo que esto no es código golf?)

Aquí hay una respuesta decente:

or(arg1, arg2)
    return arg1 ? arg1 : arg2

Pero eso es esencialmente idéntico a otras respuestas ya dadas.

Afilado
fuente
3
Estos enfoques son fundamentalmente defectuosos. Considere -1 + 1 para arg1+arg2, -1 y 0 para max(arg1,arg2), etc.
mullido
@fluffy Este enfoque supone argumentos booleanos, y luego simplemente funciona correctamente con la mayoría de los tipos de entrada de basura. Es bueno de su parte señalar que todavía hay algo de basura que produce problemas. Este tipo de cosas es exactamente la razón por la que debemos tratar de modelar el dominio del problema real lo más directamente posible (y evitar dejarnos llevar por nuestra propia inteligencia) en la práctica.
Keen
Si está haciendo valores booleanos puros de 1 bit, entonces la suma aún no funciona, ya que 1 + 1 = 0. :)
esponjoso
@fluffy Ahí es donde entran las conversiones explícitas. El hecho de que sean necesarias o no depende de los detalles de la implementación (que es exactamente por qué es una idea tonta).
Keen
0

Una forma de definir ores a través de una tabla de búsqueda. Podemos hacer esto explícito:

bool Or( bool a, bool b } {
  bool retval[] = {b,true}; // or {b,a};
  return retval[a];
}

creamos una matriz con los valores que debe tener el valor de retorno dependiendo de lo que asea. Luego hacemos una búsqueda. En lenguajes similares a C ++, se boolpromueve a un valor que puede usarse como un índice de matriz, con trueser 1y falseser 0.

Luego podemos extender esto a otras operaciones lógicas:

bool And( bool a, bool b } {
  bool retval[] = {false,b}; // or {a,b};
  return retval[a];
}
bool Xor( bool a, bool b } {
  bool retval[] = {b,!b};
  return retval[a];
}

Ahora, una desventaja de todo esto es que requiere notación de prefijo.

namespace operators {
  namespace details {
    template<class T> struct is_operator {};
    template<class Lhs, Op> struct half_expression { Lhs&& lhs; };
    template<class Lhs, class Op>
    half_expression< Lhs, Op > operator*( Lhs&&lhs, is_operator<Op> ) {
      return {std::forward<Lhs>(lhs)};
    }
    template<class Lhs, class Op, class Rhs>
    auto operator*( half_expression<Lhs, Op>&& lhs, Rhs&& rhs ) {
    return invoke( std::forward<Lhs>(lhs.lhs), Op{}, std::forward<Rhs>(rhs) );
    }
  }
  using details::is_operator;
}

struct or_tag {};
static const operators::is_operator<or_tag> OR;

bool invoke( bool a, or_tag, bool b ) {
  bool retval[] = {b,true};
  return retval[a];
}

y ahora puedes escribir true *OR* false y funciona.

La técnica anterior requiere un lenguaje que admita búsquedas dependientes de argumentos y plantillas. Probablemente podría hacerlo en un idioma con genéricos y ADL.

Como comentario, puede extender lo *OR*anterior para trabajar con conjuntos. Simplemente cree una función libre invokeen el mismo espacio de nombres que or_tag:

template<class...Ts>
std::set<Ts...> invoke( std::set<Ts...> lhs, or_tag, std::set<Ts...> const& rhs ) {
  lhs.insert( rhs.begin(), rhs.end() );
  return lhs;
}

y ahora set *OR* setdevuelve la unión de los dos.

Yakk
fuente
0

Este me recuerda las funciones de carácter:

or(a, b)
    return a + b - a*b

Esto solo se aplica a los idiomas que pueden tratar booleanos como (1, 0). No se aplica a Smalltalk o Python ya que boolean es una clase. En smalltalk van aún más lejos (esto se escribirá en una especie de pseudocódigo):

False::or(a)
    return a

True::or(a)
    return self

Y existen los métodos duales para y:

False::and(a)
    return self

True::and(a)
    return a

Por lo tanto, la "lógica" es perfectamente válida en la declaración OP, aunque es detallada. Cuidado, no está mal. Es perfecto si necesita una función que actúa como un operador matemático basado, por ejemplo, en un tipo de matriz. Otros implementarían un cubo real (como una declaración de Quine-McCluskey):

or = array[2][2] {
    {0, 1},
    {1, 1}
}

Y usted evaluará o [a] [b]

Entonces, sí, cada lógica aquí es válida (excepto la publicada como que usa el operador OR en lenguaje xDDDDDDDD).

Pero mi favorita es la ley de DeMorgan: !(!a && !b)

Luis Masuelli
fuente
0

Mire la biblioteca estándar de Swift y compruebe su implementación del acceso directo OR y las operaciones de acceso directo AND, que no evalúan los segundos operandos si no son necesarios / permitidos.

gnasher729
fuente
-2

La lógica es perfectamente correcta, pero se puede simplificar:

or(arg1, arg2)
  if arg1 = True
     return True
  else if arg2 = True
     return True
  else
     return False

Y presumiblemente su idioma tiene un operador OR, así que, a menos que esté en contra del espíritu de la pregunta, ¿por qué no?

or(arg1, arg2)
  if arg1 = True or arg2 = True
     return True
  else
     return False
Julia Hayward
fuente
if arg1 = True or arg2 = True { return true } else { return false }Mejor aún, return arg1 = True or arg2 = True. if condition then true else falsees redundante
Doval
44
El autor de la pregunta señaló específicamente que su requisito era "sin usar el operador en sí mismo"
mosquito
2
No dije nada por el estilo. Era un poco a lo que me refería, pero la pregunta no lo dijo hasta que fue editada, y ella respondió como tal, por lo que fue mi culpa.
logicNoob