not a ^ not b ^ not c ^ not d
された値の1つが真であるときに真です。これは、元の値から、正確に1つが偽であったことを意味します。
(!a&&b&&c&&d) || (a&&!b&&c&&d) || (a&&b&&!c&&d) || (a&&b&&c&&!d)
です。
not a ^ not b ^ not c ^ not d
された値の1つが真であるときに真です。これは、元の値から、正確に1つが偽であったことを意味します。
(!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%少なくなっています。
これがPythonだったとしたら、
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:
ブール値はPythonでは整数のサブクラスであるため、これらすべてが機能します。
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;
}
または、必要に応じて、これらすべてを1行に入れることができます。
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;
}
SOは、単なる論理的な問題ではなくプログラミングの質問の場合、その答えは明らかにプログラミング言語の選択に依存することを覚えておいてください。一部の言語は、他の言語には珍しい機能をサポートしています。
たとえば、C ++では、次のようにして条件をテストできます。
(a + b + c + d) == 3
これは、ブール型から整数型への自動(低レベル)変換をサポートする言語でチェックを実行する最も速い方法です。しかし、繰り返しになりますが、その問題に対する一般的な答えはありません。
少なくとも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は、Art of Computer Programmingの第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が真です。次に、これらの各ケースを他の1つと正確に結合するだけです。
mine <=> his
、私はこれが予想されるので何を言うべきかわかりません。
Karnaugh Mapsなどのロジック視覚化ツールを使用している場合、これは、if(...)行で記述したい場合、完全な論理用語を回避できない問題であることがわかります。ロピナはそれをすでに示しました、それをより簡単に書くことは不可能です。あなたは少し因数分解できますが、あなたにとってもマシンにとっても読みにくいままです。
カウントソリューションは悪くなく、彼らはあなたが本当に何を求めているかを示します。効率的にカウントする方法は、プログラミング言語によって異なります。Python oder LinQを使用したアレイソリューションはよく見ることができますが、これは遅いことに注意してください。ウルフの(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がfalseで他のすべてがtrueである他のタイプである場合、これは失敗する可能性があります。次に、ブール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);
このコードは正確に3つの論理テスト(aの状態、bの状態、xとyの比較)を実行し、ここでの他のほとんどの回答よりも高速である必要があります。しかし、コメントする必要があります。そうしないと、3か月が経過しても理解できません:)
ではPythonの、要素の反復可能なの何を見ている真、使用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マップと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
再帰を含む答えのないプログラミングの質問?考えられない!
「4つの真のうち3つだけ」という答えは十分ありますが、次のことができるという理由だけで、「真のうち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つが予想どおりtrueだったため)。"true"と "falses"という単語には満足できませんが、現在のところ、より適切な名前を付けることはできません。... 見つかった値が多すぎtrue
たり多すぎたりすると、再帰が停止しますfalse
。
true
。たぶんのようなものcontainsNumberOfTrueValues()
。余談ですが、Smalltalkの命名は、これにははるかに適していますdoesArray: someBooleans startingAt: anIndex containNumberOfTrueValues: anExpectedNumber foundSofar: aNumberFoundSoFar
。おそらく一部のJava開発者の好みには長すぎるかもしれませんが、Smalltalkerは適切な名前を恐れることはありません;-)
containsTruth
、私はそれはかなり大丈夫だと考えているような手段は、文字通り、「真実の一部非公開の量が含まれています」。
読みやすさは大きな懸念事項なので、説明的な関数呼び出しを使用できます(推奨される実装のいずれかをラップします)。この計算を複数の場所で行う必要がある場合は、再利用を実現するための最良の方法は関数呼び出しであり、何をしているのかを明確にします。
bool exactly_three_true_from(bool cond1, bool cond2, bool cond3, bool cond4)
{
//...
}
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をテストできます。