3/4가 참인지 테스트하는 논리
True
4 개의 부울 값 중 3 개가 true 인 경우에만 반환하고 싶습니다 .
내가 얻은 가장 가까운 것은 (x ^ y) ^ (a ^ b)
:
어떻게해야합니까?
의미를 나타내는 방식으로 코드를 작성하는 것이 좋습니다. 3 개의 값을 true로 원하면 3 값이 어딘가에 나타나는 것이 당연합니다.
예를 들어,에 C++
:
if ((int)a + (int)b + (int)c + (int)d == 3)
...
이는 잘 정의되어 C++
다음은 standard (§4.7/4)
변환 것을 나타낸다 bool
하려면 int
예상 값 0 또는 1을 제공한다.
Java 및 C #에서는 다음 구성을 사용할 수 있습니다.
if ((a?1:0) + (b?1:0) + (c?1:0) + (d?1:0) == 3)
...
# 1 : 분기 사용? : 3 또는 4 작업
A ^ B ? C & D : ( C ^ D ) & A
# 2 브랜칭, 7 가지 작업
(A ^ B ^ C ^ D) & ((A & B) | (C & D))
내가 모든 것을 프로파일 링하는 데 사용했을 때 , CPU가 코드 경로를 더 잘 예측하고 더 많은 작업을 동시에 실행할 수 있기 때문에 비 분기 솔루션이 작동에 훨씬 더 빠르다는 것을 알았습니다 . 그러나 분기 성명서의 작업은 약 50 % 적습니다.
이것이 파이썬 이었다면
if [a, b, c, d].count(True) == 3:
또는
if [a, b, c, d].count(False) == 1:
또는
if [a, b, c, d].count(False) == True:
# In Python True == 1 and False == 0
또는
print [a, b, c, d].count(0) == 1
또는
print [a, b, c, d].count(1) == 3
또는
if a + b + c + d == 3:
또는
if sum([a, b, c, d]) == 3:
부울은 파이썬에서 정수의 서브 클래스이기 때문에이 모든 것이 작동합니다.
if len(filter(bool, [a, b, c, d])) == 3:
또는이 깔끔한 트릭 에서 영감을 얻은
data = iter([a, b, c, d])
if not all(data) and all(data):
길지만 매우 단순하고 (분리형) 일반 형태 :
(~a & b & c & d) | (a & ~b & c & d) | (a & b & ~c & d) | (a & b & c & ~d)
간단하지만 더 많은 생각이 필요합니다 : P
그것이 더 간단하지는 않지만 어쩌면.
((x xor y) and (a and b)) or ((x and y) and (a xor b))
이 논리를 프로그래밍 언어로 사용하려면 제 제안은
bool test(bool a, bool b, bool c, bool d){
int n1 = a ? 1 : 0;
int n2 = b ? 1 : 0;
int n3 = c ? 1 : 0;
int n4 = d ? 1 : 0;
return n1 + n2 + n3 + n4 == 3;
}
또는 원하는 경우 다음을 모두 한 줄에 넣을 수 있습니다.
return (a ? 1 : 0) + (b ? 1 : 0) + (C ? 1 : 0) + (d ? 1 : 0) == 3;
또한이 문제를 n of m
다음과 같이 일반화 할 수 있습니다 .
bool test(bool *values, int n, int m){
int sum = 0;
for(int i = 0; i < m; i += 1){
sum += values[i] ? 1 : 0;
}
return sum == n;
}
이 답변은 표현 시스템에 따라 다르지만 0이 false로 해석되는 유일한 값이고 not(false)
항상 같은 숫자 값을 반환 not(a) + not(b) + not(c) + not(d) = not(0)
하면 트릭을 수행해야합니다.
단지 논리적 문제가 아닌 프로그래밍 질문에 대한 답은 프로그래밍 언어의 선택에 달려 있음을 명심하십시오. 일부 언어는 다른 언어와 다른 기능을 지원합니다.
예를 들어 C ++에서는 다음을 사용하여 조건을 테스트 할 수 있습니다.
(a + b + c + d) == 3
부울에서 정수 유형으로의 자동 (낮은 수준) 변환을 지원하는 언어에서 확인하는 가장 빠른 방법입니다. 그러나 그 문제에 대한 일반적인 대답은 없습니다.
내가 할 수있는 최선은 ((x ^ y) ^ (a ^ b)) && ((a || x) && (b || y))
((a xor b) xor (c xor d)) and ((a or b) and (c or d))
주먹 표현 true
은 4 에서 1 또는 3을 검색합니다 . 두 번째 표현 은 4에서 0 또는 1 (때로는 2)을 제거 true
합니다.
Java 8에서 잘못된 값을 필터링하고 나머지 실제 값을 계산하십시오.
public static long count(Boolean... values) {
return Arrays.stream(values).filter(t -> t).count();
}
그런 다음 다음과 같이 사용할 수 있습니다.
if (3 == count(a, b, c, d)) {
System.out.println("There... are... THREE... lights!");
}
쉽게 확인에 일반화 n
의 m
항목이 진실되고.
적어도 n
모두 를 확인하려면 Boolean
(n은 총 수보다 작거나 같아야 함 Boolean
: p)
if (((a ? 1:0) + (b ? 1:0 ) + (c ? 1:0) + (d ? 1:0 )) >= n) {
// do the rest
}
편집 : @ Cruncher의 의견 후
boolean
4 개 중 3 개 를 확인하려면
if (((a ? 1:0) + (b ? 1:0 ) + (c ? 1:0) + (d ? 1:0 )) == 3) {
// do the rest
}
다른 것 :
((c & d) & (a ^ b)) | ((a & b) & (c ^ d))
( 세부 사항 )
LINQ를 사용하여 C #에서 해결할 수있는 방법은 다음과 같습니다.
bool threeTrue = new[] { a, b, x, y }.Count(x => x) == 3;
이것이 대칭형 부울 함수 S₃(4)
입니다. 대칭 부울 함수는 설정된 입력 수에만 의존하지만 입력에 의존하지 않는 부울 함수입니다. Knuth는 컴퓨터 프로그래밍 기술 4 권 섹션 7.1.2에서이 유형의 기능을 언급합니다.
S₃(4)
다음과 같이 7 가지 연산으로 계산할 수 있습니다.
(x && y && (a || b)) ^ ((x || y) && a && b)
크 누스이 당신이 정상 연산자를 사용하여보다 7 작업에서이 작업을 수행 할 수 있음을 의미 최적임을 보여줍니다 : &&, || , ^, <,
와 >
.
그러나 1
true와 0
false 를 사용하는 언어로 이것을 사용 하려면 쉽게 추가를 사용할 수 있습니다.
x + y + a + b == 3
그것은 당신의 의도를 아주 분명하게 만듭니다.
(a && b && (c xor d)) || (c && d && (a xor b))
순수한 논리 관점에서 이것은 내가 생각해 낸 것입니다.
비둘기 구멍 원리에 따르면 정확히 3이 참이면 a와 b가 참이거나 c와 d가 참입니다. 그런 다음 각 사례를 정확히 다른 하나와 함께 처리하는 문제입니다.
Karnaugh Maps와 같은 논리 시각화 도구를 사용하는 경우 이는 하나의 if (...) 행에 쓰려고한다면 완전한 논리 용어를 피할 수없는 문제입니다. Lopina는 이미 그것을 보여주었습니다. 더 간단하게 작성할 수는 없습니다. 비트를 제외 할 수는 있지만 기계를 읽기 어렵습니다.
계산 솔루션은 나쁘지 않으며 실제로 당신이 무엇을하는지 보여줍니다. 계산을 효율적으로 수행하는 방법은 프로그래밍 언어에 따라 다릅니다. Python 또는 LinQ를 사용한 배열 솔루션은보기에 좋지만 조심하십시오. Wolf 's (a + b + x + y) == 3은 훌륭하고 빠르게 작동하지만 언어가 "true"와 1과 같은 경우에만 해당합니다. "true"가 -1로 표시되면 -3을 테스트해야합니다. )
당신의 언어가 진정한 부울을 사용한다면, 당신은 그것을 명시 적으로 프로그램하려고 시도 할 수 있습니다 (나는 XOR 테스트로! =를 사용합니다) :
if (a)
{
if (b)
return (x != y); // a,b=true, so either x or y must be true
else
return (x && y); // a=true, b=false, so x AND y must be true
}
else
{
if (b)
return (x && y); // a=false, b=true, so x and y must be true
else
return false; // a,b false, can't get 3 of 4
}
"x != y" works only if x,y are of a boolean type. If they are some other type where 0 is false and everything else is true, this can fail. Then use a boolean XOR, or ( (bool)x != (bool)y ), or write "if (x) return (y==false) else return (y==true);", which is a bit more work for the computer.
If your programming language provides the ternary ?: operator, you can shorten it to
if (a)
return b ? (x != y) : (x && y);
else
return b ? (x && y) : false;
which keeps a bit of readability, or cut it aggressively to
return a ? (b ? (x != y) : (x && y)) : (b ? (x && y) : false);
This code does exactly three logic tests (state of a, state of b, comparison of x and y) and should be faster than most of the other answers here. But you need to comment it, or you won't understand it after 3 months :)
There are a lot of good answers here; here is an alternate formulation which no one else has posted yet:
a ? (b ? (c ^ d) : (c && d)) : (b && c && d)
Similar to the first answer, but pure Java:
int t(boolean b) {
return (b) ? 1 : 0;
}
if (t(x) + t(y) + t(a) + t(b) == 3) return true;
return false;
I prefer counting them as integers because it makes for more readable code.
In Python, to see how many of an iterable of elements are True, use sum
(it's quite straightforward):
Setup
import itertools
arrays = list(itertools.product(*[[True, False]]*4))
Actual Test
for array in arrays:
print(array, sum(array)==3)
Output
(True, True, True, True) False
(True, True, True, False) True
(True, True, False, True) True
(True, True, False, False) False
(True, False, True, True) True
(True, False, True, False) False
(True, False, False, True) False
(True, False, False, False) False
(False, True, True, True) True
(False, True, True, False) False
(False, True, False, True) False
(False, True, False, False) False
(False, False, True, True) False
(False, False, True, False) False
(False, False, False, True) False
(False, False, False, False) False
If you're after the on-the-paper (non-programming) solution, then K-maps and Quine-McCluskey algorithms are what you're after, they help you minify your boolean function.
In your case, the result is
y = (x̄3 ^ x2 ^ x1 ^ x0) ∨ (x3 ^ x̄2 ^ x1 ^ x0) ∨ (x3 ^ x2 ^ x̄1 ^ x0) ∨ (x3 ^ x2 ^ x1 ^ x̄0)
If you want to do this programmatically, non-fixed amount of variables and a custom "threshold", then simply iterating thru a list of boolean values and counting occurrences of "true" is pretty simple and straightforward.
I want to return true if and only if 3 out of 4 boolean values are true.
Given the 4 boolean values, a, b, x, y, this task translates into the following C statement:
return (a+b+x+y) == 3;
((a^b)^(x^y))&((a|b)&(x|y))
is what you want. Basically I took your code and added checking if actually 3 are true and not 3 are false.
A programming question without an answer involving recursion? Inconceivable!
There are enough "exactly 3 out of 4 trues" answers, but here's a generalised (Java) version for "exactly m out of n trues" (otherwise recursion isn't really worth it) just because you can:
public static boolean containsTrues(boolean[] someBooleans,
int anIndex, int truesExpected, int truesFoundSoFar) {
if (anIndex >= someBooleans.length) {
return truesExpected == truesFoundSoFar; // reached end
}
int falsesExpected = someBooleans.length - truesExpected;
boolean currentBoolean = someBooleans[anIndex];
int truesFound = truesFoundSoFar + (currentBoolean ? 1 : 0);
if (truesFound > truesExpected) {
return false;
}
if (anIndex - truesFound > falsesExpected) {
return false; // too many falses
}
return containsTrues(someBooleans, anIndex + 1, truesExpected,
truesFound);
}
This could be called with something like:
boolean[] booleans = { true, false, true, true, false, true, true, false };
containsTrues(booleans, 0, 5, 0);
which should return true
(because 5 of 8 values were true, as expected). Not quite happy with the words "trues" and "falses", but can't think of a better name right now.... Note that the recursion stops when too many true
or too many false
values have been found.
Since readability is a big concern, you could use a descriptive function call (wrapping any of the suggested implementations). If this calculation needs to be done in multiple places, a function call is the best way to achieve reuse, and makes it clear exactly what you are doing.
bool exactly_three_true_from(bool cond1, bool cond2, bool cond3, bool cond4)
{
//...
}
In PHP, making it more dynamic (just in case you change number of conditions, etc.):
$min = 6;
$total = 10;
// create our boolean array values
$arr = array_map(function($a){return mt_rand(0,1)>0;},range(1,$total));
// the 'check'
$arrbools = array_map(function($a){return (int)$a;},$arr);
$conditionMet = array_sum($arrbools)>=$min;
echo $conditionMet ? "Passed" : "Failed";
(((a AND b) OR (x AND y)) AND ((a XOR b) OR (x XOR y)))
While I could show that this is a good solution, Sam Hocevar's answer is easy both to write and understand later. In my book that makes it better.
Here is some c# code I just wrote because you have inspired me:
It takes any amount of arguments and will tell you if n of them are true.
static bool boolTester(int n, params bool[] values)
{
int sum = 0;
for (int i = 0; i < values.Length; i++)
{
if (values[i] == true)
{
sum += 1;
}
}
if( sum == n)
{
return true;
}
return false;
}
and you call it like so:
bool a = true;
bool b = true;
bool c = true;
bool d = false;
bool test = false;
test = boolTester(3, a, b, c, d);
So you can now test 7/9 or 15/100 as you will.
참고URL : https://stackoverflow.com/questions/22240396/logic-to-test-that-3-of-4-are-true
'Programing' 카테고리의 다른 글
ID가 #### 인 프로세스가 Visual Studio Professional 2013 업데이트 3에서 실행되고 있지 않습니다. (0) | 2020.05.31 |
---|---|
현재 위치 권한 대화 상자가 너무 빨리 사라짐 (0) | 2020.05.31 |
인덱싱없이 파일 내에서 문자열을 검색하는 도구 (0) | 2020.05.31 |
Disney의 FastPass가 유효하고 유용한 대기열 이론입니까? (0) | 2020.05.31 |
태깅을위한 데이터베이스 디자인 (0) | 2020.05.31 |