ひるあんどんブログ

色々なことに手を出してみるブログ

Boolean Algebra

数学と数学的論理では ブール代数 は代数の部分領域であり、変数の値が真(true)と偽(false)で一般的にそれぞれ1と0で示されます。 変数の値が数字で主な演算が加算と乗算である基本的な代数学の代わりに、ブール代数の主な演算は論理積(conjunction) (∧で示される)と、論理和(disjunction)(∨で示される)と否定(negation)(¬で示される)です。

このミッションではあなたはいくつかのブール演算を実装する必要があります。

  • 論理積 "conjunction" x ∧ y で示され、 x = y = 1 の時は x ∧ y = 1 でそれ以外は x ∧ y = 0 を満たします。
  • 論理和 "disjunction" x ∨ y で示され、x = y = 0 の時は x ∨ y = 0 でそれ以外は x ∨ y = 1 を満たします。
  • 含意 "implication" (具象的含意) x→y で示され ¬ x ∨ y でも表せられます。もしxが真ならば、x → yはyの値です。xが偽ならばyの値は無視されるかもしれません、しかしながらこの演算は多少の真実の値を返さなくてはいけなくて2つの選択肢しかありません、なので返却値は必然的に少なくなり、はっきり言うと真です。
  • 排他 "exclusive" (排他的 or) x ⊕ y で示され、(x ∨ y)∧ ¬ (x ∧ y)でも表せられます。 それはxとy両方の可能性を排除します。算数の用語での定義では足して2で割った余りで、ここでは1+1=0になります。
  • 等価 "equivalence" x ≡ y で示され、¬ (x ⊕ y)でも表せられます。xとyが同じ値を取る時だけ真になります。

これらの演算の真の表は以下のようになります。

x | y | x∧y | x∨y | x→y | x⊕y | x≡y |

0 | 0 | 0 | 0 | 1 | 0 | 1 |
1 | 0 | 0 | 1 | 0 | 1 | 0 |
0 | 1 | 0 | 1 | 1 | 1 | 0 |
1 | 1 | 1 | 1 | 1 | 0 | 1 |


あなたには x と y の2つのブール値が1と0の値として与えられ、先ほど述べた演算の名前が与えられます。あなたはその値を計算し、1か0の値を返さなくてはいけません。

入力 3つの引数。XとYが0か1で与えられ、演算名が文字列で与えられます。

出力 結果を1か0で出力します。

boolean(1, 0, "conjunction") == 0

boolean(0, 1, "exclusive") == 1

1

2

3

どうやって使われるか ここではブール値と演算がどうやって扱われるかを学ぶでしょう。ブール値としての数字についても考えることになるでしょう。

事前条件 x in (0, 1)
y in (0, 1)
operation in ("conjunction", "disjunction", "implication", "exclusive", "equivalence")

OPERATION_NAMES = ("conjunction", "disjunction", "implication", "exclusive", "equivalence")

def boolean(x, y, operation):
    if operation == "conjunction":
        if x == y == 1:
            return 1
        return 0
    elif operation == "disjunction":
        if x == y == 0:
            return 0
        return 1
    elif operation == "implication":
        if x == 1:
            return y
        return 1
    elif operation == "exclusive":
        return (x + y) % 2
    elif operation == "equivalence":
        if x == y:
            return 1
        return 0
        

if __name__ == '__main__':
    #These "asserts" using only for self-checking and not necessary for auto-testing
    assert boolean(1, 0, "conjunction") == 0, "and"
    assert boolean(1, 0, "disjunction") == 1, "or"
    assert boolean(1, 1, "implication") == 1, "material"
    assert boolean(0, 1, "exclusive") == 1, "xor"
    assert boolean(0, 1, "equivalence") == 0, "same?"

美しさの欠片もないけど、素直に解いた。一回目に exclusiveを return x + y % 2ってやって死んだ。演算子の優先順位を忘れていた。

(優先順位が高い)
  +  -  ~x      (+と-は単項演算子)
  **
  *  /  %  //
  +  -
  <<  >>
  &
  ^
  |
  <  <=  >  >=  ==  !=  <>  is  is not  in  not in
  not
  and
  or
(優先順位が低い)

なので、(x + y) % 2 としないと死ぬ。


Clear 1位

def boolean(x, y, operation):

    if operation == "conjunction": return x & y

    if operation == "disjunction": return x | y

    if operation == "implication": return (1 ^ x) | y

    if operation == "exclusive":   return x ^ y

    if operation == "equivalence": return x ^ y ^ 1

    return 0

これは何だ? ビット演算だ。

通常および長整数型ではさらに、ビット列に対してのみ意味のある演算をサポートしています。負の数はその値の 2 の補数の値として扱われます (長整数の場合、演算操作中にオーバフローが起こらないように十分なビット数があるものと仮定します) 。

2 進のビット単位演算は全て、数値演算よりも低く、比較演算子よりも高い優先度です; 単項演算 ~ は他の単項数値演算 (+ および -) と同じ優先度です。

以下のテーブルでは、ビット列演算を優先度の低いものから順に並べています。 :
演算 	結果 	注釈
x | y 	ビット単位の x と y の 論理和 	 
x ^ y 	ビット単位の x と y の 排他的論理和 	 
x & y 	ビット単位の x と y の 論理積 	 
x << n 	x の n ビット左シフト 	(1)(2)
x >> n 	x の n ビット右シフト 	(1)(3)
~x 	x のビット反転 	 

注釈:

    負値のシフト数は不正であり、 ValueError が送出されます。
    n ビットの左シフトは、 pow(2, n) による乗算と等価です。結果が通常の整数の範囲を越えるときには、長整数が返されます。
    n ビットの右シフトは、 pow(2, n) による除算と等価です。

speedly

OPERATION_NAMES = ("conjunction", "disjunction", "implication", "exclusive", "equivalence")


boolean=lambda x,y,o:{'co':x and y,'di':x or y,'im':y if x else 1,'ex':x!=y,'eq':x==y}[o[:2]]

creative

boolean=lambda x,y,o:1&~"dimpleqonx".index(o[1])>>y>>x>>y

なにがなんだか、わからないよ!!(この回答は数学者によるものなんだって〜)