グリッドベースのデジタルロジック(デュオディアディックタイル)


33

Duodyadicタイルは、2つの入力(1つは上面から、もう1つは左側から)、2つの出力(1つは右側に、もう1つは下面)を備えた正方形の機能ブロックです。それぞれの出力は、両方の入力の個別の関数です。

たとえば、#一般的なタイルを表し、右の出力がR機能でf入力のTL、下の出力はB別の関数であるgTL

 T
L#R         R = f(T, L)
 B          B = g(T, L)

(2つの関数があるため、タイルは「du​​o」と呼ばれ、両方の関数には2つの引数があるため「dyadic」と呼ばれます。)

タイルは、グリッド上で一緒に構成することができ、1つのタイルの出力は、隣接するタイルの入力に直接入ります。ここで、例えば、左の右の出力は右#の左の入力に入ります#

 AB         D = f(f(A, C), B)
C##D        E = g(A, C)
 EF         F = g(f(A, C), B)

それぞれが特定の機能を備えたデュオディアックタイルのセットがあれば、複雑な(潜在的に有用な)コンポジションを作成できると想像できます。

この課題では、すべての入力と出力が1ビットのバイナリ数(ゼロまたは1)である、10個のロジックベースのデュオディアディックタイルの従来のセットのみを考慮します。タイルの各タイプを示すために、個別のASCII文字を使用します。

タイル文字とそれらの入出力関係は次のとおりです
T上入力L用、左入力R用、右出力B用、下出力用)。

  1. ゼロ:0または(スペース)→ R = 0B = 0
  2. 1つ:1R = 1B = 1
  3. クロス:+R = LB = T
  4. ミラー:\R = TB = L
  5. 上部のみ:UR = TB = T
  6. 左のみ:)R = LB = L
  7. しない:!R = not LB = not T
  8. そして:&R = L and TB = L and T
  9. または:|R = L or TB = L or T
  10. Xor:^R = L xor TB = L xor T

チャレンジ

0 1+\U)!&|^10個のロジックベースのデュオディアディックタイルを使用して作成された「回路」を表す文字の長方形グリッドを取り込むプログラムまたは関数を記述します。あなたはまた、の二つの文字列に取る必要がある0のと1の。1つは左側の入力列で、もう1つは上部の入力行です。あなたのプログラム/関数は、下の出力行と右の出力列を印刷/返却する必要があります(同様に0sと1s)。

たとえば、このグリッドでは

+++
+++

すべての入力がグリッドを直進して出力に流れます

 ABC
D+++D
E+++E
 ABC

入力ので、010/が01出力を持っています010/ 01

 010
0+++0
1+++1
 010

あなたのプログラムの正確な出力は次のようになり[bottom output row]\n[right output column][bottom output row]/[right output column]

010
01

または

010/01

関数を作成した場合、タプルまたはリストで2つの文字列を返す(または印刷する)ことができます。

詳細

  • 3つの入力を合理的な方法で文字列として(できればグリッド、一番上の行、左列の順に)、コマンドライン、テキストファイル、sdtin、関数argの順に取ります。
  • 入力行と列の長さはグリッドの寸法と一致し、0'と1' のみを含むと仮定できます。
  • グリッドには適切な文字(0 1+\U)!&|^)を使用する必要があります。それを覚えてい0、同じことを意味します。

テストケース

(I / Oをtop/ leftbottom/ として読み取りrightます。)

ナンド:

&!

00/ 001/ 1
00/ 101/ 1
10/ 001/ 1
10/ 1→→ 11/0

すべてのもの:

1111
1\+\
1+\+
1\+\

入力の結果は1111/になり1111ます。

Xor from Nand:(末尾のスペースの列に注意してください)

\)+\ 
U&!& 
+! ! 
\&!& 
   ! 

00000/ 0000000000/ 00000
00000/ 1000000010/ 00000
10000/ 0000000010/ 00000
10000/ 10000→→ 00000/00000

ジグザグ:

+++\00000000
000\!!!!\000
00000000\+++

左の入力の最初のビットは、右の出力の最後のビットになります。それ以外はすべてです0

000000000000/ 000000000000000/ 000
000000000000/ 100000000000000/001

伝搬:

)))
UUU
U+U
U+U
UUU

左入力の最初のビットはすべての出力に行きます。

000/ 00000000/ 00000
000/ 10000111/11111

すべての1×1グリッドテストケースのペーストビンです。

得点

バイト単位の最短提出勝ちです。

ボーナス:どのようなクールな「回路」を作成できますか?

PSグーグルの「デュオディアディックタイル」を気にしないでください。昨日それらを作りました; D
このアイデアを本格的なプログラミング言語に拡張することについて議論したい場合は、このチャットルームに来てください。


11
クールなチャレンジのために+1を行いましたが、デュオディアックタイルを発明したため、本当にクールです。
アレックスA.

3
+1 Google:goo.gl/zuqfdWをグーグルで検索するのはまったく役に立ちません。ナイスチャレンジ!
BrainSteel

私は彼らと一緒です。この特定のゴルフチャレンジよりも、プログラミング言語としてのタイルに興味があります。PS:タイルは16個あるので、他の6個の文字/名前を考え出すのはいいでしょう。
スパー

異なる方向から出力/入力するブロックがあると面白いでしょう。そうしないと、すべてが右下方向に流れるためラッチを作成できません。
Sp3000

2
T / BをU(p)/ D(own)に変更すると、ルービックキューブ表記に類似した方法でF / Bを使用でき、その後になります。。。トライアドリックキューブ?
ソーハムチョードリー

回答:


8

Pyth、122

モンスターの種類。単純な再帰を使用し、動的プログラミングのような派手なものはありません。

D:NGHR@Cm+d[1HG&GH|GHxGH0),[GH!G)[HG!H)x"+\\!1U)&|^"N#aYw)M:@@YGH?hgGtHHv@eYG?egtGHGv@ePYHjkm+0egtleYklePYjkm+0hgbtlePYleY

オンラインデモ

入力は次のようになります:最初にグリッド(エスケープなし、余分なシンボルなし)、次に2行の入力、たとえば(ジグザグ)

+++\00000000
000\!!!!\000
00000000\+++
000000000000
100

8

Mathematica、331 276 270 267 264 262 252 250バイト

Print@@@{#[[2;;,-1,2]],#[[-1,2;;,1]]}&@MapIndexed[h=Characters;({r@#2,b@#2}=<|##|>&@@Thread[h@"0 1+\\)U!&|^"->{0,0,1,i={##},{#2,#},##,1-i,1##,Max@i,(#-#2)^2}]&[r[#2-{1,0}],b[#2-{0,1}]]@#{1,1})&,Join[h@{"0"<>#3},h@StringSplit[#2<>"
"<>#,"
"]],{2}]&

Mathematicaは上付き文字として使用する私的使用のUnicode文字でT、それは転置演算子のIE。

より読みやすいバージョンは次のとおりです。

Print @@@ {#[[2 ;;, -1, 2]], #[[-1, 2 ;;, 1]]} &@
  MapIndexed[h = Characters;
   (
     {r@#2, b@#2} = <|##|> & @@ Thread[
            h@"0 1+\\)U!&|^" -> {
              0,
              0,
              1,
              i = {##},
              {#2, #},
              ##,
              1 - i,
              1 ##,
              Max@i,
              (# - #2)^2
              }] & [
          r[#2 - {1, 0}],
          b[#2 - {0, 1}]
          ] @ # {1, 1}
     ) &,
   Join[
    h@{"0" <> #3},
    h@StringSplit[#2 <> "\n" <> #, "\n"]\[Transpose]
   ],
   {2}] &

これは、グリッドの3つの文字列、上と左の入力を受け取り、下と右の出力を出力する名前のない関数です。

説明

このステップをステップごとに見ていきましょう(Mathematicaの知識を前提としないようにします)。コードを最初から最後まで読む必要があります。基本的なアルゴリズムは、各関数を計算し、結果を保存fして後続のタイルからアクセスできるように行をスイープするだけです。

入力処理

それはこのビットです:

Join[
  h@{"0" <> #3},
  h@StringSplit[#2 <> "\n" <> #, "\n"]\[Transpose]
]

これは、単にグリッドを文字のネストされたリストに分割し(コードのどこかのhエイリアスとして定義したことに注意してくださいCharacter)、入力を行と列の先頭に追加します。これは機能します。これは、1および0は定数関数タイルの名前でもあるため、実際にタイルを配置すると、入力を手動で入力するのと同じ効果があります。これらは関数であるため、技術的にはグリッドの外部から入力を受け取りますが、それらは重要ではない定数関数であるためです。左上隅にはa 0が表示されますが、そのタイルの結果は使用されないため、これはかなり任意です。

移調にも注意してください。列を追加すると、行を追加するよりも多くの文字が必要になるため、一番上の行を追加した後にグリッドを転置します。これは、プログラムの主要部分で上下/左右が入れ替わることを意味しますが、それらは完全に交換可能であるため重要ではありません。正しい順序で結果を返すようにする必要があります。

グリッドを解く

(このセクションは少し古くなっています。ゴルフが終わったと確信したら修正します。)

次にMapIndexed、このネストされたリストの内部レベルを実行します。これは、グリッド内の各文字の最初の引数として提供された匿名関数を呼び出し、現在の2つの座標を含むリスト提供します。グリッドは順番にトラバースされるため、以前のセルに基づいて各セルを安全に計算できます。

変数r(ight)とb(ottom)を各セルの結果のルックアップテーブルとして使用します。匿名関数の現在の座標は#2であるため、任意のセルへの入力を取得します。

r[#2 - {1, 0}],
b[#2 - {0, 1}]

最初の行と列に、これはの未定義の値にアクセスすることに注意してくださいrとしますb。Mathematicaには実際には問題はなく、代わりに座標を返すだけですが、その行/列のすべてのタイルは定数関数であるため、とにかくこの結果を破棄します。

今、このこと:

<|##|> & @@ Thread[
  h@"0 1+\\U)!&|^" -> {
     z = {0, 0}, z, o = 1 + z, {##}, ...
  }] &

のゴルフ形式です

<|"0" -> (z = {0, 0}), " " -> z, "1" -> (o = 1 + z), "+" -> {##}, ... |> &

これは、2つのタイル入力が与えられると、これらの2つの入力のすべての可能なタイル結果を含むAssociation(他の言語ではハッシュマップまたはテーブルと呼びます)を返す関数です。すべての関数がどのように実装されるかを理解するには、そのような関数の最初の引数にでアクセスでき#、2番目の引数にでアクセスできることを知る必要があります#2。さらに、##引数を「スプラット」するために使用できる両方の引数のシーケンスを提供します。

  • 0:は簡単です。定数{0, 0}を返すだけでなく、z将来の使用のためにこれを割り当てます(たとえば、スペースタイルで)。
  • 1:は本質的にただ{1,1}であるが、これを持つzことはに短縮され1+zます。またo、両方の出力が同一であるすべてのタイルに役立つので、これをに保存します。
  • +:ここでは、シーケンスを使用します。{##}は同じで{#,#2}、両方の入力を変更せずに渡します。
  • \:2つの引数を入れ替えます{#2,#}
  • U:これでを使用できますoo#2つまり{1,1}*#2、両方の出力にtop引数を入れるだけです。
  • ):同様に、左の引数:o#
  • !:Mathematicaではビット単位は面倒ではありませんが、0and しか持っていないため、1単純に両方の入力を減算して1(それによってそれらを反転させ)渡すことができます1-{##}
  • &:これは非常に気の利いたものです。最初に、ビット単位およびfor 0および1乗算が乗算と同一であることに気付きます。さらに、はとo##同じo*#*#2です。
  • |:繰り返しますが、同等の関数を使用します。ビット単位orはMaxこの場合と同じなのでMax、入力引数に適用し、結果をに乗算し{1,1}ます。
  • ^:xorで見つけた最も短いのは、差を取り、それを2乗して(陽性を確保する)ことo(#-#2)^2です。

この機能を完了した後、我々は我々が興味を持っている要素を引き出し、それを保存するために、現在のセルの文字を使用し、完全な関連性を返すrとしますb。これはで使用される匿名関数の戻り値でもあるMapIndexedため、実際にはマッピングによりすべての結果のグリッドが表示されます。

出力処理

MapIndexed3Dグリッドを返します。最初の次元は水平グリッド座標に対応し(以前の転置を思い出してください)、2番目の次元は垂直グリッド座標に対応し、3番目はボトム出力か左出力かを示します。これには、削除する必要がある入力行と入力列も含まれていることに注意してください。したがって、下の行の一番下の出力にアクセスするには

#[[2;;,-1,2]]

最後の列の正しい出力

#[[-1,2;;,1]]

2;;は、2番目から最後の要素までの範囲であることに注意してください。

最後に、Print両方の引数に適用します(@@@第2レベルの構文糖として使用Apply)。これは、すべての引数を連続して出力します(2つの別個の式に適用されるため、bottomと正しい出力)。


8

C、332 309 272 270 266 259 247 225バイト

#define C(x)*c-x?
i,k,T,L,m;f(c,t,l)char*c,*t,*l;{while(L=l[i]){for(k=0;T=t[k];c++)L=C(49)C(43)C(92)C(85)C(41)C(33)C(38)C('|')C(94)T=48:(T^=L-48):(T|=L):(T&=L):(T^=1,L^1):(T=L):T:(m=T,T=L,m):L:(T=49),t[k++]=T;c++;l[i++]=L;}}

ここで結果をオンライン見る

これはfunctionを定義しますvoid f(char*, char*, char*)。これは、ボードを最初の入力として、次に入力の一番上の行、入力の左の行として受け取る必要があります。

これが私がそれをテストするために使用したものです:

#include "stdio.h"
int main() {
    char buf[1024],top[33],left[33];
    /* Copy and paste an example circuit as the first input,
       and put a 'Q' immediately after it. 
       Note that the Q is never touched by the function f, and is used
       solely as a delimiter for input. */
    scanf("%[^Q]Q ",buf);
    /* Then enter your top inputs */
    scanf("%[01]%*[^01]", top);
    /* Then your left ones */
    scanf("%[01]", left);
    /* OUTPUT: Bottom\nRight */
    f(buf, top, left);
    return 0;
}

したがって、Sp3000の2ビット乗算器を入力することにより:

UUUU))))
UU++)))&
UUU+)  U
UU++&))U
U++&+)^U
U)&\&)UU
   U+^UU
   \&UUUQ
11110000
00000000

我々が得る:

00001001
11111111

別のノートでは、心の中でSP3000の半加算器と、私は、全加算器を見てみたいと思います... ワン君たちのは、それをやりました!このシステムがプログラミング言語として独立しているとは思いませんが、非常に興味深いものでした。ただし、これはメタゴルフの優れたターゲットのようです!

簡単な説明:

解かれたコメント付きコードは次のとおりです。

/* We define the first half of the ?: conditional operator because, well,
   it appears over and over again. */
#define C(x)*c-x?
/* i,k are counting variables
   T,L are *current* top and left inputs */
i,k,T,L,m;
f(c,t,l)char*c,*t,*l;{
    /* The outer loop iterates from top to bottom over l and c */
    while(L=l[i]){
        /* Inner loop iterates from left to right over t and c */
        for(k=0;T=t[k];c++)
            /* This line looks awful, but it's just a bunch of character
            comparisons, and sets T and L to the output of the current c */
            L=C(49)C(43)C(92)C(85)C(41)C(33)C(38)C('|')C(94)T=48:(T^=L-48):(T|=L):(T&=L):(T^=1,L^1):(T=L):T:(m=T,T=L,m):L:(T=49),
            /* Write our output to our input, it will be used for the next row */
            t[k++]=T;
        c++; /*Absorbs the newline at the end of every row */
        /* Keep track of our right-most outputs, 
        and store them in the handy string passed to the function. */
        l[i++]=L;
    }
    /* Bottom output is now stored entirely in t, as is right output in l */        
}

c左から右(上から下)で繰り返し、t毎回入力を書き換え、l文字列に押し込まれた右端の出力を押し出します。これは、の一番上の行c1'と0'で繰り返し置き換え、右側に押し出されたビットを追跡することとして想像できます。

行ごとの視覚的なシーケンスを次に示します。

 111                                  
1&+^  =>  110 ->0  =>     ->0  =>     0 Thus, "01" has been written to l,
1+&+     1+&+         110 ->1         1
                                  110   And "110" is stored currently in t.

これは、異なるシンボルとサイズでは明らかに複雑になりますが、中心的な考え方は保持されます。これが機能するのは、データが上または下に流れないためです。


ゴルフの多くの可能性!fto のヘッダーを変更することから始めf(c,t,l)char*c,*t,*lます(戻り値の型についてたわごとを与えないでください)。
FUZxxl

@FUZxxl誰かがチャットでこれについて言及しましたが、動作させることができませんでした。この動作は標準ですか?LLVMは、その行で少なくとも2つのエラーをスローします。
BrainSteel

ごめんなさい。あるべきだったf(c,t,l)char*c,*t,*l;。C11モードでコンパイルしないでください。戻り値の型をドロップできる暗黙のintルールがそのリビジョンでドロップされているためです。
FUZxxl

@FUZxxl C99でも失敗するようです。実際、コンパイラを設定したすべてのモードは、そのコードを拒否しています。
BrainSteel

直後にセミコロンを追加しました*lか?私のマシンではC99モードでコンパイルされます。
-FUZxxl

7

Python 2、316バイト

この関数は、10個のタイルラムダ関数を作成し、グリッドを反復処理して、論理状態を更新します。最終的な垂直および水平ロジック状態が印刷されます。

def b(d,j,g):
 h=enumerate;e=dict((s[0],eval('lambda T,L:('+s[1:]+')'))for s in' 0,0#00,0#11,1#+L,T#\\T,L#UT,T#)L,L#!1-L,1-T#&T&L,T&L#|T|L,T|L#^T^L,T^L'.split('#'));j=list(j+'\n');g=list(g)
 for y,k in h(d.split('\n')):
  L=g[y]
  for x,c in h(k):T=j[x];L,B=e[c](int(T),int(L));j[x]=`B`
  g[y]=`L`
 print''.join(j+g)

テストを含む未コード:

def logic(grid, top, left):
    loop = enumerate;
    func = dict((s[0], eval('lambda T,L:('+s[1:]+')')) for s in ' 0,0#00,0#11,1#+L,T#\\T,L#UT,T#)L,L#!1-L,1-T#&T&L,T&L#|T|L,T|L#^T^L,T^L'.split('#'));
    top = list(top+'\n');
    left = list(left)
    for y,row in loop(grid.split('\n')):
        L = left[y]
        for x,cell in loop(row) :
            T = top[x];
            L, B = func[cell](int(T), int(L));
            top[x] = `B`
        left[y] = `L`
    print ''.join(top + left)

import re
testset = open('test.txt', 'rt').read().strip()
for test in testset.split('\n\n'):
    if test.endswith(':'):
        print '------------------\n'+test
    elif re.match('^[01/\n]+$', test, re.S):
        for run in test.split():
            top, left = run.split('/')
            print 'test', top, left
            logic(grid, top, left)
    else:
        grid = test

test.txt(SP3000によって2つの他のテストを含む)のファイル:

Nand:

&!

00/0
00/1
10/0
10/1

All ones:

1111
1\+\
1+\+
1\+\

1001/1100

Xor from Nand (note the column of trailing spaces):

\)+\ 
U&!& 
+! ! 
\&!& 
   ! 

00000/00000
00000/10000
10000/00000
10000/10000

Half adder:

+))
U&+
U+^

000/000
000/100
100/000
100/100

Right shift:

\\\
\++
\++

001/110
010/101
101/100

テスト出力:

------------------
Nand:
test 00 0
01
1
test 00 1
01
1
test 10 0
01
1
test 10 1
11
0
------------------
All ones:
test 1001 1100
1111
1111
------------------
Xor from Nand (note the column of trailing spaces):
test 00000 00000
00000
00000
test 00000 10000
00010
00000
test 10000 00000
00010
00000
test 10000 10000
00000
00000
------------------
Half adder:
test 000 000
000
000
test 000 100
001
101
test 100 000
101
001
test 100 100
110
110
------------------
Right shift:
test 001 110
000
111
test 010 101
101
010
test 101 100
010
110

7

パイソン2、384の 338 325バイト

def f(G,T,L):
 def g(x,y):
  if x>-1<y:l=g(x-1,y)[1];t=g(x,y-1)[0];r=l,t,1-l,0,0,1,t,l,l&t,l|t,l^t;i="+\\!0 1U)&|^".index(G[y*-~W+x]);return((t,l,1-t)+r[3:])[i],r[i]
  return(int((y<0)*T[x]or L[y]),)*2
 H=G.count("\n")+1;W=len(G)/H;return eval('"".join(map(str,[g(%s]for _ in range(%s)])),'*2%('_,H-1)[0','W','W-1,_)[1','H'))

真剣に、これがおもちゃではない場合、いくつかのおもちゃ工場を鳴らし始める必要があります。

今ではゴルフが増え、効率は大幅に低下していますが、まだCarpetPythonに追いついていません。のような入力f("1111\n1\\+\\\n1+\\+\n1\\+\\","0101","1010")は、2つの文字列のタプルです。ただし、ボードの末尾に改行がないことを確認してください。

テストプログラム

def f(G,T,L):
 def g(x,y):
  if x>-1<y:l=g(x-1,y)[1];t=g(x,y-1)[0];r=l,t,1-l,0,0,1,t,l,l&t,l|t,l^t;i="+\\!0 1U)&|^".index(G[y*-~W+x]);return((t,l,1-t)+r[3:])[i],r[i]
  return(int((y<0)*T[x]or L[y]),)*2
 H=G.count("\n")+1;W=len(G)/H;return eval('"".join(map(str,[g(%s]for _ in range(%s)])),'*2%('_,H-1)[0','W','W-1,_)[1','H'))


import itertools

G = r"""
+))
U&+
U+^
""".strip("\n")

def test(T, L):
    print f(G, T, L)

def test_all():
    W = len(G[0])
    H = len(G)

    for T in itertools.product([0, 1], repeat=len(G.split("\n")[0])):
        T = "".join(map(str, T))

        for L in itertools.product([0, 1], repeat=len(G.split("\n"))):
            L = "".join(map(str, L))

            print "[T = %s; L = %s]" % (T, L)
            test(T, L)
            print ""

test("000", "000")
test("000", "100")
test("100", "000")
test("100", "100")

ですべての可能なケースをテストすることもできtest_all()ます。

追加のテストケース

半加算器

左上のビットを追加して出力する半加算器を次に示します<input bit> <carry> <sum>

+))
U&+
U+^

テスト:

000 / 000  ->  000 / 000
000 / 100  ->  001 / 101
100 / 000  ->  101 / 001
100 / 100  ->  110 / 110

入力の2番目または3番目のビットが変更されても、出力は同じである必要があります。

右シフト

与えられたabc / def、この出力fab / cde

\\\
\++
\++

テスト:

001 / 110 -> 000 / 111
010 / 101 -> 101 / 010
101 / 100 -> 010 / 110

3ビットソーター

上部の最初の3ビットを下部の最後の3ビットにソートします。正しい出力はジャンクです。

UUU)))
UU)U U
U&UU U
U+|&)U
\UU++|
 \)&UU
  \+|U
   UUU

テスト:

000000 / 00000000 -> 000000 / 00000000
001000 / 00000000 -> 000001 / 11111111
010000 / 00000000 -> 000001 / 00001111
011000 / 00000000 -> 000011 / 11111111
100000 / 00000000 -> 000001 / 00001111
101000 / 00000000 -> 000011 / 11111111
110000 / 00000000 -> 000011 / 00001111
111000 / 00000000 -> 000111 / 11111111

2ビットx 2ビット乗算器

topの1番目と2番目のビットを最初の数として、topの3番目と4番目のビットを2番目の数として取ります。下位の最後の4ビットに出力します。正しい出力はジャンクです。

UUUU))))
UU++)))&
UUU+)  U
UU++&))U
U++&+)^U
U)&\&)UU
   U+^UU
   \&UUU

編集:列と2行をゴルフアウトしました。

テスト:

00000000 / 00000000 -> 00000000 / 00000000
00010000 / 00000000 -> 00000000 / 10000000
00100000 / 00000000 -> 00000000 / 00000000
00110000 / 00000000 -> 00000000 / 10000000
01000000 / 00000000 -> 00000000 / 00000000
01010000 / 00000000 -> 00000001 / 11111111
01100000 / 00000000 -> 00000010 / 00000000
01110000 / 00000000 -> 00000011 / 11111111
10000000 / 00000000 -> 00000000 / 00000000
10010000 / 00000000 -> 00000010 / 10000000
10100000 / 00000000 -> 00000100 / 00000000
10110000 / 00000000 -> 00000110 / 10000000
11000000 / 00000000 -> 00000000 / 00000000
11010000 / 00000000 -> 00000011 / 11111111
11100000 / 00000000 -> 00000110 / 00000000
11110000 / 00000000 -> 00001001 / 11111111

1

R、524 517

現時点ではこれを減らす余地はたぶんありますが、これは本当に面白いことです。2つの機能があります。関数dはワーカーであり、fは比較演算子です。

関数dは、Gates、Top、Leftの3つのストリングで呼び出されます。ゲートは、幅によって決定されるマトリックスに配置されます。

I=strtoi;S=strsplit;m=matrix;f=function(L,T,G){O=I(c(0,1,L,T,!L,!T,L&T,L|T,xor(L,T)));X=which(S(' 01+\\U)!&|^','')[[1]]==G);M=m(c(1,1,1,2,1,1,3,2,2,4,3,4,5,4,3,6,4,4,7,3,3,8,5,6,9,7,7,10,8,8,11,9,9),nrow=3);return(c(O[M[2,X]],O[M[3,X]]))};d=function(G,U,L){W=nchar(U);H=nchar(L);U=c(list(I(S(U,'')[[1]])),rep(NA,H));L=c(list(I(S(L,'')[[1]])),rep(NA,W));G=m((S(G,'')[[1]]),nrow=W);for(i in 1:H)for(n in 1:W){X=f(L[[n]][i],U[[i]][n],G[n,i]);L[[n+1]][i]=X[1];U[[i+1]][n]=X[2]};cat(U[[H+1]],' / ',L[[W+1]],sep='',fill=T)}

少しフォーマット済み

I=strtoi;S=strsplit;m=matrix;
f=function(L,T,G){
    O=I(c(0,1,L,T,!L,!T,L&T,L|T,xor(L,T)));
    X=which(S(' 01+\\U)!&|^','')[[1]]==G);
    M=m(c(1,1,1,2,1,1,3,2,2,4,3,4,5,4,3,6,4,4,7,3,3,8,5,6,9,7,7,10,8,8,11,9,9),nrow=3);
    return(c(O[M[2,X]],O[M[3,X]]))
};
d=function(G,U,L){
    W=nchar(U);H=nchar(L);
    U=c(list(I(S(U,'')[[1]])),rep(NA,H));
    L=c(list(I(S(L,'')[[1]])),rep(NA,W));
    G=m((S(G,'')[[1]]),nrow=W);
    for(i in 1:H)
        for(n in 1:W){
            X=f(L[[n]][i],U[[i]][n],G[n,i]);
            L[[n+1]][i]=X[1];
            U[[i+1]][n]=X[2]
        };
    cat(U[[H+1]],' / ',L[[W+1]],sep='',fill=T)
}

いくつかのテスト

> d('&!','00','0')
01 / 1
> d('&!','00','1')
01 / 1
> d('&!','10','0')
01 / 1
> d('&!','10','1')
11 / 0
> d('\\)+\\ U&!& +! ! \\&!&    ! ','00000','00000')
00000 / 00000
> d('\\)+\\ U&!& +! ! \\&!&    ! ','00000','10000')
00010 / 00000
> d('\\)+\\ U&!& +! ! \\&!&    ! ','10000','00000')
00010 / 00000
> d('\\)+\\ U&!& +! ! \\&!&    ! ','10000','10000')
00000 / 00000
> d('+++\\00000000000\\!!!!\\00000000000\\+++','000000000000','100')
000000000000 / 001
> d('+++\\00000000000\\!!!!\\00000000000\\+++','000000000000','000')
000000000000 / 000
> d('+))U&+U+^','000','000')
000 / 000
> d('+))U&+U+^','000','100')
001 / 101
> d('+))U&+U+^','100','000')
101 / 001
> d('+))U&+U+^','100','100')
110 / 110
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.