論理ゲートでのゲリマンダーリング


16

多数決関数は、3つのブール入力を取り、最も一般的な値を返すブール関数です。たとえば、if maj(x,y,z)が多数決関数であり、TtrueをF示し、false を示す場合:

maj(T,T,T) = T
maj(T,T,F) = T
maj(T,F,F) = F
maj(F,F,F) = F

この質問は、ブール関数を多数決関数の構成として記述することに関するものです。多数決関数の5進構成の例は(x1,x2,x3,x4,x5) => maj(x1,x2,maj(x3,x4,x5))です。この関数は、これらのサンプル入力ベクトルで次の出力を返します。

(T,T,F,F,F) => maj(T,T,maj(F,F,F)) = maj(T,T,F) = T
(T,F,T,T,F) => maj(T,F,maj(T,T,F)) = maj(T,F,T) = T
(T,F,T,F,F) => maj(T,F,maj(T,F,F)) = maj(T,F,F) = F
(F,F,F,T,T) => maj(F,F,maj(F,T,T)) = maj(F,F,T) = F

仕事

ブール値の正の整数nと長さnのベクトルのリストを入力し、可能であれば与えられたすべてのベクトルでtrueを返す多数決ゲートのツリーを出力するプログラムを作成します。この関数は、制約のリストにないベクトルに対してtrueまたはfalseを返す場合があります。

  • ベクトルのリストは、任意の形式で入力できます。必要に応じて、ベクトルを入力する代わりに、ベクトル内の真の位置のリストを入力できます。したがって、たとえば、[TTF,TFT,FTT]or [[T,T,F],[T,F,T],[F,T,T]]または[[1,2],[1,3],[2,3]](真の位置のリスト)はすべて問題ありません。

  • 出力は、任意の有効なツリー形式にすることができます。たとえば、maj(maj(x1,x2,x3),x4,x5)動作します。おそらく、単一の数字を変数の代用として使用することになるでしょう[[1,2,3],4,5]123m45mたとえば、リバースポリッシュも大丈夫です。

  • 機能する関数がない場合、プログラムはエラーを生成するか、偽の値を出力する必要があります。

  • 動作する関数が複数ある場合、プログラムはそれらのいずれかを返すことができます。関数を単純化する必要はありません。たとえば、maj(x1,x1,x2)またはx1は同等です。

得点

これはコードゴルフです。バイト単位の最短ソリューションが勝ちです。

テストケース:

これらの各ケースには多くの可能な出力があるため、出力を関数に変換するチェッカースクリプトを記述し、指定した各入力ベクトルで関数がtrueを返すことを確認する必要があります。

Input: 3, [TFF]
Output: 1 or [1,1,2] or [1,[1,2,2],[1,1,3]] or other equivalent

Input: 3, [TFF,FTF]
Output: Falsey or error (it's not possible)

Input: 3, [TTF,TFT]
Output: [1,2,3] or 1 or other equivalent

Input: 3, [TTF,TFT,FTT]
Output: [1,2,3] or [1,3,2] or other equivalent

Input: 4, [TTFF,TFTF,FFTT]
Output: Falsey or error

Input: 4, [TTTF,TTFT,TFTT,FTTT]
Output: [1, 2, 3] or [2,3,4], or many other options

Input: 5, [TTTFF,FTTFT,TFFFT]
Output: [1,[1,[1,2,5],[2,4,5]],3] or many other options 

Input: 6, [TTTFFF,FTFTTF,TFFTFT]
Output: [1, 2, 4] or [1, [1, 2, 4], [2, 3, 4]] or others

Input: 5, [TTTFF,TTFTF,TTFFT,TFTTF,TFTFT,TFFTT,FTTTF,FTTFT,FTFTT,FFTTT]
Output: [[1, [1, 3, 5], 4], [1, 2, [2, 4, 5]], [2, 3, [3, 4, 5]]] or others

Input: 7, [TTTTFFF,TTTFTFF,TTTFFTF,TTTFFFT,TTFTTFF,TTFTFTF,TTFTFFT,TTFFTTF,TTFFTFT,TTFFFTT,TFTTTFF,TFTTFTF,TFTTFFT,TFTFTTF,TFTFTFT,TFTFFTT,TFFTTTF,TFFTTFT,TFFTFTT,TFFFTTT,FTTTTFF,FTTTFTF,FTTTFFT,FTTFTTF,FTTFTFT,FTTFFTT,FTFTTTF,FTFTTFT,FTFTFTT,FTFFTTT,FFTTTTF,FFTTTFT,FFTTFTT,FFTFTTT,FFFTTTT]
Output: [[[1, [1, [1, 4, 7], 6], 5], [1, [1, 3, [3, 6, 7]], [3, 5, [5, 6, 7]]], [3, 4, [4, [4, 5, 7], 6]]], [[1, [1, [1, 4, 7], 6], 5], [1, 2, [2, [2, 5, 7], 6]], [2, [2, 4, [4, 6, 7]], [4, 5, [5, 6, 7]]]], [[2, [2, [2, 4, 7], 6], 5], [2, 3, [3, [3, 5, 7], 6]], [3, [3, 4, [4, 6, 7]], [4, 5, [5, 6, 7]]]]]

「多数決関数の5項合成は(x1、x2、x3、x4、x5)=> maj(x1、x2、maj(x3、x4、x5))」です。x1 = x2 = Fの場合の答えは何ですか。x3 = x4 = x5 = T; ?
tsh

真理値表を追加します。
フッド

1
出力1はどういう意味ですか?
Mhmd

2
推奨タイトル:論理ゲートを備えたゲリマンダーリング
ロバートフレイザー

1
@trichoplaxいいえ、残りのすべてのベクトルの出力は何でもかまいません。これを明示するために更新します。
フード

回答:


2

JavaScript(ES6)、260バイト

入力をブール値の配列の配列として受け取ります。1インデックス付き多数決ゲートのツリーを返すか、解決策が存在しない場合は再帰エラー(1)をスローします。

メイン関数f()は、ソルバーF()を呼び出し、反復ごとに最大の入れ子レベルmをインクリメントすることにより、再帰的に解を見つけようとします。

後に(1)長い時間、そして無限のメモリを想定

f=(a,m)=>(F=(a,d,I=a[i=0].map(_=>++i),g=(a,b)=>b[1]?b.reduce((s,i)=>s+g(a,i),0)>1:a[b-1])=>I.find(i=>a.every(a=>g(a,i)))||d&&(I.reduce((a,x)=>[...a,...a.map(y=>[...y,x])],[[]]).some(b=>r=b.length==3&&F(a.map(a=>[...a,g(a,b)]),d-1,[...I,b]))&&r))(a,m)||f(a,-~m)

デモ

以下は、デモの最後のテストケースで見つかったソリューションの検証表です。

12345 | [5,[1,2,4],[3,4,[1,2,3]]]
------+-------------------------------------------------------------
TTTFF | [F,[T,T,F],[T,F,[T,T,T]]] --> [F,T,[T,F,T]] -> [F,T,T] --> T
TTFTF | [F,[T,T,T],[F,T,[T,T,F]]] --> [F,T,[F,T,T]] -> [F,T,T] --> T
TTFFT | [T,[T,T,F],[F,F,[T,T,F]]] --> [T,T,[F,F,T]] -> [T,T,F] --> T
TFTTF | [F,[T,F,T],[T,T,[T,F,T]]] --> [F,T,[T,T,T]] -> [F,T,T] --> T
TFTFT | [T,[T,F,F],[T,F,[T,F,T]]] --> [T,F,[T,F,T]] -> [T,F,T] --> T
TFFTT | [T,[T,F,T],[F,T,[T,F,F]]] --> [T,T,[F,T,F]] -> [T,T,F] --> T
FTTTF | [F,[F,T,T],[T,T,[F,T,T]]] --> [F,T,[T,T,T]] -> [F,T,T] --> T
FTTFT | [T,[F,T,F],[T,F,[F,T,T]]] --> [T,F,[T,F,T]] -> [T,F,T] --> T
FTFTT | [T,[F,T,T],[F,T,[F,T,F]]] --> [T,T,[F,T,F]] -> [T,T,F] --> T
FFTTT | [T,[F,F,T],[T,T,[F,F,T]]] --> [T,F,[T,T,F]] -> [T,F,T] --> T

効率的なソリューションがありますが、うまくいけば誰かが見つけるでしょう。一方で、私は...作品のブルートフォースの並べ替えを推測する
フード

1

Mathematica、121バイト

ブール値のベクトル内の真の位置のリストのリストとして2番目の引数を取る匿名関数。

f[n_][s_]:=If[n<3,(Intersection@@s)[[1]],{#/. 2->1,#2/.{2->1,3->2},#3}&@@(1+f[n-1]/@(s-1/.{{0->1},{1->2,0->1},{0->2}}))]

少し良いフォーマット:

f[n_][s_] := If[n < 3, (Intersection @@s)[[1]],
   {# /. 2 -> 1, #2 /. {2 -> 1, 3 -> 2}, #3} & @@ 
    (1 + f[n - 1] /@ (s - 1 /. {{0 -> 1}, {1 -> 2, 0 -> 1}, {0 -> 2}}))]

変数が3つより少ない場合は、制約ベクトルを交差させて、すべての制約に共通の「True」があるかどうかを確認します。ある場合、定数関数(x_1、x_2)-> x_iは機能します。そうでない場合は不可能です(空のリストの最初の要素を取得しようとするとエラーがスローされます)。

それ以外の場合、f1=f(x1,x1,x2,x3,,xn1)f2=f(x1,x2,x2,x3,,xn1)、およびf3=f(x1,x2,x1,x3,,xn1))、これらのそれぞれを再帰的に解き、f=maj(f1(x1,x3,x4,,xn),f2(x1,x2,x4,,xn),f2(x2,x3,x4,,xn))

説明:

これは再帰的アルゴリズムであり、n変数問題の解を見つける問題を、n1変数問題の3つの解を見つけることに軽減します。この作業を行う重要な観察結果は、fについて、探している関数の1つが次のようになっていることです f(x1,,xn)=maj(f(x1,x1,x3,x4,,xn),f(x1,x2,x2,),f(x3,x2,x3,))

最初の位置でx2x1に、2番目の位置x3x2に、3番目の位置x1x3に置き換えました。

このアイデンティティがわかれば、アルゴリズムは明確になります。変数が2つ以下の場合、問題は簡単です。そうでない場合は、再帰的に表現する三つの問題解決f(x1,x1,x3,x4,,xn)f(x1,x2,x2,x4,,xn)、及びf(x3,x2,x3,x4,,xn))、それらの大部分を取ります。

なぜこれが本当ですか?多数決関数は次の2つの特性を満たします。

  1. それは「相補的」です。つまり、!xの否定でありxは、maj(!x,!y,!z)=!maj(x,y,z)。結果として、多数決関数から構築できるすべての関数は補完的です。

  2. maj(x,y,False)maj(x,y,True)FalseTrue(x1,,xn)(y1,,yn)xiyiif(x1,xn)(y1,,yn)f(x1,xn)f(y1,,yn)。単調関数の構成は単調であるため、多数決関数から構築できるすべての関数は単調です。

相補的な単調関数は、多数決ゲートから構築できる関数のクラスであることがわかります。

ff(x1,,xn)=maj(f(x1,x1,x3,x4,,xn),f(x1,x2,x2,x4,,xn),f(x3,x2,x3,x4,,xn))

f1(x1,x2,x3,,xn)=f(x1,x1,x3,x4,,xn)f2(x1,,xn)=f(x1,x2,x2,x4,,xn)f3(x1,,xn)=f(x3,x2,x3,x4,,xn)f=maj(f1,f2,f3)f1f2f3fx1x2x3x1=x2=x3f1=f2=f3=f

x1x2x3fx1=x2x3fx1=x2=Falsex3=True(x1,x1,x3)=(False,False,True)=(x1,x2,x3)(x1,x2,x2)=(False,False,False)(x1,x2,x3)(x3,x2,x3)=(True,False,True)(x1,x2,x3)f2f1=ff3f=Falsef2Falsef2=False=ff=Truef3Truef3=Truef1f2f3ff=maj(f1,f2,f3)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.