Quero retornar True
se e somente se 3 de 4 valores booleanos forem verdadeiros.
O mais próximo que cheguei é (x ^ y) ^ (a ^ b)
:
O que devo fazer?
boolean-logic
Simon Kuang
fonte
fonte
not a ^ not b ^ not c ^ not d
é verdade quando exatamente um dos valores negados é verdadeiro. Isso significa que, pelos valores originais, exatamente um era falso.(!a&&b&&c&&d) || (a&&!b&&c&&d) || (a&&b&&!c&&d) || (a&&b&&c&&!d)
.Respostas:
Sugiro escrever o código de uma maneira que indique o que você quer dizer. Se você deseja que 3 valores sejam verdadeiros, parece-me natural que o valor 3 apareça em algum lugar.
Por exemplo, em
C++
:Isso está bem definido em
C++
:standard (§4.7/4)
indica que a conversãobool
paraint
fornece os valores esperados 0 ou 1.Em Java e C #, você pode usar a seguinte construção:
fonte
if (!!a + !!b + !!c + !!d == 3)
é mais fácil de escrever, embora eu não sei se compiladores otimizar isso ou não# 1: Usando uma ramificação?: 3 ou 4 operações
# 2 Não ramificação, 7 operações
Na época em que utilizava o perfil de tudo, descobri que as soluções que não eram de ramificação eram operação e operação bastante mais rápidas, pois a CPU podia prever melhor o caminho do código e executar mais operações em conjunto. Há cerca de 50% menos trabalho na declaração de ramificação aqui.
fonte
Se fosse Python, eu teria escrito
Ou
Ou
Ou
Ou
Ou
Ou
Tudo isso funciona, já que os booleanos são subclasses de números inteiros em Python.
Ou, inspirado por esse truque legal ,
fonte
a=5;not not a == 1
. A desvantagem de não ter um tipo booleano real.bool
:) #Forma normal longa, mas muito simples, (disjuntiva):
Pode ser simplificado, mas isso exige mais reflexão: P
fonte
(a & b & (c ^ d)) | ((a ^ b) & c & d)
?Não tenho certeza se é mais simples, mas talvez.
((x xor y) and (a and b)) or ((x and y) and (a xor b))
fonte
Se você quiser usar essa lógica em uma linguagem de programação, minha sugestão é
Ou, se desejar, você pode colocar tudo isso em uma única linha:
Além disso, você pode generalizar esse problema para
n of m
:fonte
Essa resposta depende do sistema de representação, mas se 0 é o único valor interpretado como falso e
not(false)
sempre retorna o mesmo valor numérico, entãonot(a) + not(b) + not(c) + not(d) = not(0)
deve fazer o truque.fonte
Tendo em mente que, para questões de programação, em vez de meros problemas lógicos, a resposta obviamente depende da escolha de uma linguagem de programação. Alguns idiomas suportam recursos incomuns para outros.
Por exemplo, em C ++, você pode testar suas condições com:
Essa deve ser a maneira mais rápida de verificar os idiomas que suportam a conversão automática (de baixo nível) de tipos booleanos para números inteiros. Mas, novamente, não há resposta geral para esse problema.
fonte
O melhor que posso fazer é
((x ^ y) ^ (a ^ b)) && ((a || x) && (b || y))
fonte
A primeira expressão procura 1 ou 3
true
em 4. A segunda elimina 0 ou 1 (e às vezes 2)true
em 4.fonte
Java 8, filtre os valores falsos e conte os demais valores verdadeiros:
Então você pode usá-lo da seguinte maneira:
Generaliza facilmente a verificação
n
dem
itens verdadeiros.fonte
Para verificar se pelo menos
n
todasBoolean
são verdadeiras, (n deve ser menor ou igual ao número total deBoolean
: p)Edit : Após o comentário do @ Cruncher
Para verificar 3
boolean
de 4Outro :
((c & d) & (a ^ b)) | ((a & b) & (c ^ d))
( Detalhes )fonte
Aqui está uma maneira de resolvê-lo em C # com o LINQ:
fonte
Essa é a função booleana simétrica
S₃(4)
. Uma função booleana simétrica é uma função booleana que depende apenas da quantidade de entradas configuradas, mas não depende de quais entradas elas são. Knuth menciona funções desse tipo na seção 7.1.2 do volume 4 de The Art of Computer Programming.S₃(4)
pode ser calculado com 7 operações da seguinte maneira:Knuth mostra que isso é ideal, o que significa que você não pode fazer isso em menos de sete operações usando os operadores normais:
&&, || , ^, <,
e>
.No entanto, se você quiser usar isso em um idioma usado
1
para true e0
false, também poderá usar a adição facilmente:o que deixa sua intenção bem clara.
fonte
Do ponto de vista da lógica pura, é isso que eu criei.
Pelo princípio do buraco do pombo, se exatamente 3 são verdadeiros, então aeb são verdadeiros ou c e d são verdadeiros. Então é só uma questão de combinar cada um desses casos com exatamente um dos outros 2.
Tabela da verdade de Wolfram
fonte
mine <=> his
não sei o que dizer, como seria de esperar.Se você usar uma ferramenta de visualização lógica como o Karnaugh Maps, verá que este é um problema em que não poderá evitar um termo lógico completo se quiser escrevê-lo em uma linha se (...). Lopina já mostrou, não é possível escrever mais simples. Você pode calcular um pouco, mas será difícil ler para você E para a máquina.
As soluções de contagem não são ruins e mostram o que você realmente procura. Como você faz a contagem de maneira eficiente depende da sua linguagem de programação. As soluções de array com o Python ou LinQ são boas de se olhar, mas cuidado, é SLOW. Wolf (a + b + x + y) == 3 funcionará bem e rápido, mas somente se o seu idioma igualar "verdadeiro" a 1. Se "verdadeiro" for representado por -1, você terá que testar -3: )
Se seu idioma usa booleanos verdadeiros, você pode tentar programá-lo explicitamente (eu uso! = Como teste XOR):
"x! = y" funciona apenas se x, y são do tipo booleano. Se eles são algum outro tipo em que 0 é falso e tudo o mais é verdadeiro, isso pode falhar. Em seguida, use um XOR booleano ou ((bool) x! = (Bool) y) ou escreva "if (x) return (y == false) else return (y == true);", que é um pouco mais trabalhar para o computador.
Se sua linguagem de programação fornecer o operador ternário?:, Você poderá reduzi-lo para
que mantém um pouco de legibilidade ou reduz de forma agressiva para
Esse código faz exatamente três testes lógicos (estado de a, estado de b, comparação de xey) e deve ser mais rápido que a maioria das outras respostas aqui. Mas você precisa comentar ou não entenderá depois de 3 meses :)
fonte
Há muitas boas respostas aqui; aqui está uma formulação alternativa que ninguém mais postou ainda:
fonte
Semelhante à primeira resposta, mas puro Java:
Eu prefiro contá-los como números inteiros, porque cria um código mais legível.
fonte
No Python , para ver quantos elementos iteráveis são True, use
sum
(é bem direto):Configuração
Teste Real
Resultado
fonte
Se você está buscando a solução no papel (sem programação), os algoritmos K-maps e Quine-McCluskey são o que você procura, eles ajudam a minimizar sua função booleana.
No seu caso, o resultado é
Se você deseja fazer isso programaticamente, uma quantidade não fixa de variáveis e um "limite" personalizado, simplesmente iterando através de uma lista de valores booleanos e contando ocorrências de "true" é bastante simples e direto.
fonte
Dados os 4 valores booleanos, a, b, x, y, esta tarefa se traduz na seguinte instrução C:
fonte
true
igual a 1. Isso não é verdade (sem trocadilhos) em todos os idiomas / casos. blogs.msdn.com/b/oldnewthing/archive/2004/12/22/329884.aspxé o que você quer. Basicamente, peguei o seu código e adicionei a verificação se na verdade 3 são verdadeiros e não 3 são falsos.
fonte
Uma pergunta de programação sem resposta envolvendo recursão? Inconcebível!
Existem respostas suficientes "exatamente 3 em 4 verdadeiras", mas aqui está uma versão generalizada (Java) para "exatamente m fora de n verdadeiras" (caso contrário, a recursão não vale a pena) apenas porque você pode:
Isso pode ser chamado com algo como:
que deve retornar
true
(porque 5 de 8 valores eram verdadeiros, conforme o esperado). Não está muito satisfeito com as palavras "verdadeiras" e "falsas", mas não consegue pensar em um nome melhor no momento ... Observe que a recursão para quando valores demaistrue
ou muitosfalse
foram encontrados.fonte
true
. Talvez algo parecidocontainsNumberOfTrueValues()
. Como um aparte: nomeação do Smalltalk seria muito mais adequado para isso, porém:doesArray: someBooleans startingAt: anIndex containNumberOfTrueValues: anExpectedNumber foundSofar: aNumberFoundSoFar
. Provavelmente muito tempo para gostos algumas devs Java, mas Smalltalkers não têm medo de nomenclatura adequada ;-)containsTruth
significa "contém uma quantidade não revelada de verdade", literalmente, então eu acredito que está tudo bem.Como a legibilidade é uma grande preocupação, você pode usar uma chamada de função descritiva (envolvendo qualquer uma das implementações sugeridas). Se esse cálculo precisar ser feito em vários locais, uma chamada de função é a melhor maneira de obter a reutilização e deixa claro exatamente o que você está fazendo.
fonte
No PHP, tornando-o mais dinâmico (caso você altere o número de condições, etc.):
fonte
Embora eu possa mostrar que essa é uma boa solução, a resposta de Sam Hocevar é fácil de escrever e entender mais tarde. No meu livro, isso melhora.
fonte
Aqui está um código c # que acabei de escrever porque você me inspirou:
É preciso qualquer quantidade de argumentos e informa se n deles são verdadeiros.
e você chama assim:
Agora você pode testar 7/9 ou 15/100 como desejar.
fonte