Je veux retourner True
si et seulement si 3 valeurs booléennes sur 4 sont vraies.
Le plus proche que j'ai obtenu est (x ^ y) ^ (a ^ b)
:
Que devrais-je faire?
boolean-logic
Simon Kuang
la source
la source
not a ^ not b ^ not c ^ not d
c'est vrai quand exactement l'une des valeurs négatives est vraie. Cela signifie que, d'après les valeurs d'origine, une seule était fausse.(!a&&b&&c&&d) || (a&&!b&&c&&d) || (a&&b&&!c&&d) || (a&&b&&c&&!d)
.Réponses:
Je suggère d'écrire le code d'une manière qui indique ce que vous voulez dire. Si vous voulez que 3 valeurs soient vraies, il me semble naturel que la valeur 3 apparaisse quelque part.
Par exemple, dans
C++
:Ceci est bien défini dans
C++
: lestandard (§4.7/4)
indique que la conversionbool
enint
donne les valeurs attendues 0 ou 1.En Java et C #, vous pouvez utiliser la construction suivante:
la source
if (!!a + !!b + !!c + !!d == 3)
est plus facile à écrire, même si je ne sais pas si les compilateurs optimisent cela ou non# 1: Utilisation d'un branchement?: 3 ou 4 opérations
# 2 sans branchement, 7 opérations
À l'époque où j'utilisais pour tout profiler, j'ai trouvé que les solutions sans branchement étaient un fonctionnement un peu plus rapide car le processeur pouvait mieux prédire le chemin du code et exécuter plus d'opérations en tandem. Il y a cependant environ 50% de travail en moins dans la déclaration de branchement ici.
la source
Si cela avait été Python, j'aurais écrit
Ou
Ou
Ou
Ou
Ou
Ou
Tout cela fonctionne, puisque les booléens sont des sous-classes d'entiers en Python.
Ou, inspiré par cette astuce soignée ,
la source
a=5;not not a == 1
. L'inconvénient de ne pas avoir un vrai type booléen.bool
:)Forme normale longue mais très simple (disjonctive):
Cela peut être simplifié mais cela demande plus de réflexion: P
la source
(a & b & (c ^ d)) | ((a ^ b) & c & d)
?Pas sûr que ce soit plus simple, mais peut-être.
((x xor y) and (a and b)) or ((x and y) and (a xor b))
la source
Si vous souhaitez utiliser cette logique dans un langage de programmation, ma suggestion est
Ou si vous le souhaitez, vous pouvez mettre tout cela sur une seule ligne:
Vous pouvez également généraliser ce problème à
n of m
:la source
Cette réponse dépend du système de représentation, mais si 0 est la seule valeur interprétée comme fausse, et
not(false)
renvoie toujours la même valeur numérique, alorsnot(a) + not(b) + not(c) + not(d) = not(0)
devrait faire l'affaire.la source
Gardant à l'esprit que SO si pour des questions de programmation, plutôt que de simples problèmes logiques, la réponse dépend évidemment du choix d'un langage de programmation. Certaines langues prennent en charge des fonctionnalités qui ne sont pas communes à d'autres.
Par exemple, en C ++, vous pouvez tester vos conditions avec:
Cela devrait être le moyen le plus rapide de vérifier les langues qui prennent en charge la conversion automatique (de bas niveau) des types booléens en types entiers. Mais encore une fois, il n'y a pas de réponse générale à ce problème.
la source
Le mieux que je puisse faire est
((x ^ y) ^ (a ^ b)) && ((a || x) && (b || y))
la source
La première expression recherche 1 ou 3
true
sur 4. La seconde élimine 0 ou 1 (et parfois 2)true
sur 4.la source
Java 8, filtrez les fausses valeurs et comptez les valeurs vraies restantes:
Ensuite, vous pouvez l'utiliser comme suit:
Se généralise facilement à la vérification
n
desm
éléments.la source
Pour vérifier au moins
n
sur tousBoolean
sont vrais, (n doit être inférieur ou égal au nombre total deBoolean
: p)Edit : Après le commentaire de @ Cruncher
Pour vérifier 3
boolean
sur 4Un autre :
((c & d) & (a ^ b)) | ((a & b) & (c ^ d))
( Détails )la source
Voici un moyen de le résoudre en C # avec LINQ:
la source
C'est la fonction booléenne symétrique
S₃(4)
. Une fonction booléenne symétrique est une fonction booléenne qui ne dépend que de la quantité d'entrées définie, mais ne dépend pas de quelles entrées elles sont. Knuth mentionne des fonctions de ce type dans la section 7.1.2 du volume 4 de The Art of Computer Programming.S₃(4)
peut être calculé avec 7 opérations comme suit:Knuth montre que c'est optimal, ce qui signifie que vous ne pouvez pas le faire en moins de 7 opérations en utilisant les opérateurs normaux:
&&, || , ^, <,
et>
.Cependant, si vous souhaitez l'utiliser dans un langage qui utilise
1
pour vrai et0
pour faux, vous pouvez également utiliser l'addition facilement:ce qui rend votre intention très claire.
la source
D'un point de vue purement logique, c'est ce que j'ai proposé.
Selon le principe du casier, si exactement 3 sont vrais, alors soit a et b sont vrais, soit c et d sont vrais. Ensuite, c'est juste une question de et de chacun de ces cas avec exactement l'un des 2 autres.
Table de vérité Wolfram
la source
mine <=> his
je ne sais pas quoi dire, car cela serait attendu.Si vous utilisez un outil de visualisation logique comme Karnaugh Maps, vous voyez que c'est un problème où vous ne pouvez pas éviter un terme logique complet si vous voulez l'écrire dans une ligne if (...). Lopina l'a déjà montré, il n'est pas possible de l'écrire plus simplement. Vous pouvez tenir compte un peu, mais cela restera difficile à lire pour vous ET pour la machine.
Les solutions de comptage ne sont pas mauvaises et elles montrent ce que vous recherchez vraiment. La manière dont vous comptez efficacement dépend de votre langage de programmation. Les solutions de tableaux avec Python ou LinQ sont agréables à regarder, mais attention, c'est LENT. Wolf's (a + b + x + y) == 3 fonctionnera bien et rapidement, mais seulement si votre langage équivaut à "vrai" avec 1. Si "vrai" est représenté par -1, vous devrez tester -3: )
Si votre langage utilise de vrais booléens, vous pouvez essayer de le programmer explicitement (j'utilise! = Comme test XOR):
"x! = y" ne fonctionne que si x, y sont de type booléen. S'ils sont d'un autre type où 0 est faux et tout le reste est vrai, cela peut échouer. Ensuite, utilisez un XOR booléen, ou ((bool) x! = (Bool) y), ou écrivez "if (x) return (y == false) else return (y == true);", ce qui est un peu plus travailler pour l'ordinateur.
Si votre langage de programmation fournit l'opérateur ternaire?:, Vous pouvez le raccourcir en
qui garde un peu de lisibilité, ou le coupe agressivement pour
Ce code effectue exactement trois tests logiques (état de a, état de b, comparaison de x et y) et devrait être plus rapide que la plupart des autres réponses ici. Mais vous devez le commenter, sinon vous ne le comprendrez pas après 3 mois :)
la source
Il y a beaucoup de bonnes réponses ici; voici une formulation alternative que personne d'autre n'a encore publiée:
la source
Similaire à la première réponse, mais pur Java:
Je préfère les compter comme des entiers car cela rend le code plus lisible.
la source
En Python , pour voir combien d'éléments itérables sont True, utilisez
sum
(c'est assez simple):Installer
Test réel
Production
la source
Si vous recherchez la solution sur papier (sans programmation), alors les algorithmes K-maps et Quine-McCluskey sont ce que vous recherchez, ils vous aident à minimiser votre fonction booléenne.
Dans votre cas, le résultat est
Si vous voulez faire cela par programme, une quantité non fixe de variables et un "seuil" personnalisé, alors simplement itérer à travers une liste de valeurs booléennes et compter les occurrences de "vrai" est assez simple et direct.
la source
Étant donné les 4 valeurs booléennes, a, b, x, y, cette tâche se traduit par l'instruction C suivante:
la source
true
égal à 1. Ce n'est pas vrai (sans jeu de mots) dans toutes les langues / cas. blogs.msdn.com/b/oldnewthing/archive/2004/12/22/329884.aspxest ce que vous voulez. En gros, j'ai pris votre code et ajouté la vérification si en fait 3 sont vrais et non 3 sont faux.
la source
Une question de programmation sans réponse impliquant la récursivité? Inconcevable!
Il y a assez de réponses "exactement 3 sur 4 vrais", mais voici une version généralisée (Java) pour "exactement m sur n vrais" (sinon la récursion n'en vaut pas vraiment la peine) simplement parce que vous pouvez:
Cela pourrait être appelé avec quelque chose comme:
qui devrait retourner
true
(car 5 des 8 valeurs étaient vraies, comme prévu). Pas tout à fait satisfait des mots "vrai" et "faux", mais je ne peux pas penser à un meilleur nom pour le moment .... Notez que la récursion s'arrête quand troptrue
ou trop defalse
valeurs ont été trouvées.la source
true
. Peut-être quelque chose commecontainsNumberOfTrueValues()
. En aparté: la nomination de Smalltalk serait beaucoup plus approprié pour cela, cependant:doesArray: someBooleans startingAt: anIndex containNumberOfTrueValues: anExpectedNumber foundSofar: aNumberFoundSoFar
. Probablement trop long pour les goûts de certains développeurs Java, mais les Smalltalkers n'ont jamais peur de nommer correctement ;-)containsTruth
signifie "contient une quantité non divulguée de vérité", littéralement, donc je pense que c'est tout à fait correct.Puisque la lisibilité est un gros problème, vous pouvez utiliser un appel de fonction descriptive (encapsulant l'une des implémentations suggérées). Si ce calcul doit être effectué à plusieurs endroits, un appel de fonction est le meilleur moyen de réutiliser et indique exactement ce que vous faites.
la source
En PHP, en le rendant plus dynamique (juste au cas où vous changeriez le nombre de conditions, etc.):
la source
Bien que je puisse montrer que c'est une bonne solution, la réponse de Sam Hocevar est facile à la fois à écrire et à comprendre plus tard. Dans mon livre, ça fait mieux.
la source
Voici un code c # que je viens d'écrire parce que vous m'avez inspiré:
Il prend n'importe quelle quantité d'arguments et vous dira si n d'entre eux sont vrais.
et vous l'appelez comme ça:
Vous pouvez donc désormais tester 7/9 ou 15/100 comme vous le souhaitez.
la source