not a ^ not b ^ not c ^ not d
합니다. 부정 된 값 중 하나만 참이면 참입니다. 이는 원래 값에서 정확히 하나가 거짓임을 의미합니다.
(!a&&b&&c&&d) || (a&&!b&&c&&d) || (a&&b&&!c&&d) || (a&&b&&c&&!d)
입니다.
not a ^ not b ^ not c ^ not d
합니다. 부정 된 값 중 하나만 참이면 참입니다. 이는 원래 값에서 정확히 하나가 거짓임을 의미합니다.
(!a&&b&&c&&d) || (a&&!b&&c&&d) || (a&&b&&!c&&d) || (a&&b&&c&&!d)
입니다.
답변:
의미를 나타내는 방식으로 코드를 작성하는 것이 좋습니다. 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)
...
if (!!a + !!b + !!c + !!d == 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=5;not not a == 1
. 실제 부울 유형이 없다는 단점이 있습니다.
bool
:)
길지만 매우 단순하고 (분리형) 일반 형태 :
(~a & b & c & d) | (a & ~b & c & d) | (a & b & ~c & d) | (a & b & c & ~d)
간단하지만 더 많은 생각이 필요합니다 : P
(a & b & (c ^ d)) | ((a ^ b) & c & d)
?
그것이 더 간단하지는 않지만 어쩌면.
이 논리를 프로그래밍 언어로 사용하려면 제 제안은
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;
}
단지 논리적 문제가 아닌 프로그래밍 질문에 대한 답은 프로그래밍 언어의 선택에 달려 있음을 명심하십시오. 일부 언어는 다른 언어와 다른 기능을 지원합니다.
예를 들어 C ++에서는 다음을 사용하여 조건을 테스트 할 수 있습니다.
(a + b + c + d) == 3
부울에서 정수 유형으로의 자동 (낮은 수준) 변환을 지원하는 언어에서 확인하는 가장 빠른 방법입니다. 그러나 그 문제에 대한 일반적인 대답은 없습니다.
내가 할 수있는 최선은 ((x ^ y) ^ (a ^ b)) && ((a || x) && (b || y))
적어도 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
}
다른 것 :
이것이 대칭형 부울 함수 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가 참입니다. 그런 다음 각 사례를 정확히 다른 하나와 함께 처리하는 문제입니다.
mine <=> his
, 이것이 예상 되는대로 무엇을 말 해야할지 모르겠습니다.
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"는 x, y가 부울 유형 인 경우에만 작동합니다. 그것들이 0이고 다른 모든 것이 참인 다른 유형이라면 실패 할 수 있습니다. 그런 다음 부울 XOR 또는 ((bool) x! = (bool) y)를 사용하거나 "if (x) return (y == false) else return (y == true);"를 쓰십시오. 컴퓨터를 위해 일하십시오.
프로그래밍 언어가 삼항? : 연산자를 제공하면 다음과 같이 단축 할 수 있습니다.
if (a)
return b ? (x != y) : (x && y);
else
return b ? (x && y) : false;
약간의 가독성을 유지하거나 적극적으로
return a ? (b ? (x != y) : (x && y)) : (b ? (x && y) : false);
이 코드는 정확히 세 가지 논리 테스트 (상태 a, 상태 b, x와 y의 비교)를 수행하며 여기에있는 대부분의 다른 답변보다 빠릅니다. 그러나 당신은 그것을 언급해야합니다, 그렇지 않으면 3 개월 후에 그것을 이해하지 못할 것입니다 :)
에서 파이썬 , 요소의 반복자의 얼마나 많은을 볼 수있는 사실, 사용 sum
(그것은 아주 간단합니다)
설정
import itertools
arrays = list(itertools.product(*[[True, False]]*4))
실제 시험
for array in arrays:
print(array, sum(array)==3)
산출
(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
종이 (비 프로그래밍) 솔루션을 따르는 경우 K-maps 및 Quine-McCluskey 알고리즘을 사용하면 부울 함수를 최소화 할 수 있습니다.
귀하의 경우 결과는
y = (x̄3 ^ x2 ^ x1 ^ x0) ∨ (x3 ^ x̄2 ^ x1 ^ x0) ∨ (x3 ^ x2 ^ x̄1 ^ x0) ∨ (x3 ^ x2 ^ x1 ^ x̄0)
프로그래밍 방식으로 고정되지 않은 양의 변수와 사용자 정의 "임계 값"을 수행하려면 부울 값 목록을 통해 반복하고 "true"의 횟수를 계산하는 것은 매우 간단하고 간단합니다.
4 개 중 3 개의 부울 값이 true 인 경우에만 true를 반환하고 싶습니다.
4 개의 부울 값 a, b, x, y가 주어지면이 작업은 다음 C 문으로 변환됩니다.
return (a+b+x+y) == 3;
true
1과 같다고 가정합니다 . 이것은 모든 언어 / 사례에서 사실이 아닙니다. blogs.msdn.com/b/oldnewthing/archive/2004/12/22/329884.aspx
재귀와 관련된 답이없는 프로그래밍 질문? 상상할 수없는!
"정확하게 3 개 중 3 개"답변이 충분하지만, 다음과 같이 할 수있는 "n 개 중 정확히 n 개"(그렇지 않으면 재귀는 실제로 가치가 없음)에 대한 일반화 된 (Java) 버전이 있습니다.
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);
}
이것은 다음과 같이 호출 될 수 있습니다.
boolean[] booleans = { true, false, true, true, false, true, true, false };
containsTrues(booleans, 0, 5, 0);
반환해야합니다 true
(8 값 중 5 개가 예상대로 참 이었기 때문에). "trues"와 "falses"라는 단어에는 만족하지 않지만 지금은 더 나은 이름을 생각할 수 없습니다 ... 재귀는 너무 많 true
거나 너무 많은 false
값이 발견 되면 중지됩니다 .
true
. 아마도 같은 것 containsNumberOfTrueValues()
입니다. 제쳐두고 : 스몰 토크의 이름 지정은 이것에 훨씬 더 적합 할 것입니다 : doesArray: someBooleans startingAt: anIndex containNumberOfTrueValues: anExpectedNumber foundSofar: aNumberFoundSoFar
. 아마 일부 자바 개발자의 취향에 비해 너무 길지만, Smalltalkers는 적절한 이름 지정을 두려워하지 않습니다. ;-)
containsTruth
말 그대로 "알려지지 않은 양의 진실을 포함하고있다"는 뜻이므로, 나는 그것이 옳다고 믿습니다.
PHP에서, 더 동적으로 만들기 (조건의 수 등을 변경하는 경우를 대비하여) :
$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";
다음은 내가 영감을 주었기 때문에 방금 작성한 C # 코드입니다.
그것은 많은 양의 논쟁을 취하고 그들 중 n이 참인지 알려줄 것입니다.
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;
}
그리고 당신은 그렇게 그렇게 부릅니다.
bool a = true;
bool b = true;
bool c = true;
bool d = false;
bool test = false;
test = boolTester(3, a, b, c, d);
이제 원하는대로 7/9 또는 15/100을 테스트 할 수 있습니다.