多言語キルト

私は記事「50カインのリレーレース」を読みました。 確かに、人間はすごいこと、ものすごい仕事、本当の芸術作品を書きました。 しかし、コメントから判断すると、多くの人はそのようなことがどのように行われているのか理解しておらず、人間の能力の限界を超えているとは限りませんが、特に難解な言語(Brainfuck、Unlambda、Whitespace)に関する多くの感情がリストにありました。

この記事では、似たようなクインがどのように書かれているかを説明します。



以下は、brainfacでコードを生成するpythonコードです。これにより、anambambdaでコードが生成され、pythonで元のコードが生成されます。



data = 'def brainfuck(st): return "".join(["+"*ord(c)+".>" for c in st])\ndef unlambda(st): return "`r"+"`"*len(st)+"".join(["."+e for e in st])+"i"\nprint brainfuck(unlambda(\'data = %s\'%`data`+chr(10)+data))' def brainfuck(st): return "".join(["+"*ord(c)+".>" for c in st]) def unlambda(st): return "`r"+"`"*len(st)+"".join(["."+e for e in st])+"i" print brainfuck(unlambda('data = %s'%`data`+chr(10)+data))
      
      







コードをできる限り明確にしようとしましたが、念のため、1行ずつ説明します。

最初の行は、Python表現の次のすべての行をエンコードします。 この行は最後に書き込まれ、すべてのプログラムコードが書き込まれた後、エンコードされます。



 >>> data = 'def brainfuck(st): return "".join(["+"*ord(c)+".>" for c in st])\ndef unlambda(st): return "`r"+"`"*len(st)+"".join(["."+e for e in st])+"i"\nprint brainfuck(unlambda(\'data = %s\'%`data`+chr(10)+data))' >>> print data def brainfuck(st): return "".join(["+"*ord(c)+".>" for c in st]) def unlambda(st): return "`r"+"`"*len(st)+"".join(["."+e for e in st])+"i" print brainfuck(unlambda('data = %s'%`data`+chr(10)+data))
      
      







したがって、プログラムテキスト全体は次の行で表すことができます。



 'data = %s'%`data`+chr(10)+data
      
      







unlambda関数はテキストを受け取り、それを印刷するプログラムをunlambdaに返します。

ブレインファック機能は、ブレインファックと同じです。



まあそれに応じて



 brainfuck(unlambda('data = %s'%`data`+chr(10)+data))
      
      







これは、Brainfuck上のプログラム、Unlambda上のプログラムの出力、ソースプログラムの出力を表す行です。

Python。

新しい言語をチェーンに追加するのは簡単です。各言語について、行を受け取り、その行を印刷するその言語のプログラムを返す関数が記述され、この関数が出力行に追加され、それに応じて、データが再計算されます。



更新。



コメントの議論を見て、もっとよく説明する必要があることに気付きました。

quilineのようなデザイン(以下、データとコードを分離できる言語についてのみ説明します)は、2つの部分に分けることができます。

1)データセグメント(重要なポイント、この部分はコードが完了するまで空のままであり、その後、エンコードされます)。

2)コードセグメント

データセグメントは、2つの方法で復号化できる暗号の一種です。復号化の結果、最初のメソッドはデータセグメント自体の文字列表現を生成し、2番目のメソッドを復号化するとコードセグメントの文字列表現が取得されます。 これらの復号化の結果を組み合わせて、プログラムのすべてのソースコードを含む文字列を取得します。

上記の例では、そのような行は'data =%s'% `data` + chr(10)+ dataです。

'data =%s'% `data`はデータセグメントを提供する復号化、 dataはコードセグメントを提供する復号化、 chr(10)はそれらの間の改行です。

そして、この魔法のラインを手にした後、私たちはそれを使って何でもできます。 印刷するだけで、通常のクインが得られます。



 data = "l = 'data = %s'%`data`+chr(10)+data\nprint l" l = 'data = %s'%`data`+chr(10)+data print l
      
      





裏返すと、テキストを前から後ろに印刷するプログラムが得られます。



 data = "l = 'data = %s'%`data`+chr(10)+data\nprint l[-1::-1]" l = 'data = %s'%`data`+chr(10)+data print l[-1::-1]
      
      







16進表現を出力するプログラムを作成できます。



 data = "l = 'data = %s'%`data`+chr(10)+data\nprint ' '.join([hex(ord(e)) for e in l])" l = 'data = %s'%`data`+chr(10)+data print ' '.join([hex(ord(e)) for e in l])
      
      







一般に、変換(この場合のように、変換チェーン)の後、コードを印刷するプログラムを作成できます。 「暗号」は、単に文字列の内部Python表現である必要はありません。たとえば、ASCIIコードの形式で暗号化できます。または、何らかの方法でそれに応じて復号化手順を変更できます。



 data = [108, 32, 61, 32, 39, 100, 97, 116, 97, 32, 61, 32, 37, 115, 39, 37, 100, 97, 116, 97, 43, 99, 104, 114, 40, 49, 48, 41, 43, 39, 39, 46, 106, 111, 105, 110, 40, 91, 99, 104, 114, 40, 101, 41, 32, 102, 111, 114, 32, 101, 32, 105, 110, 32, 100, 97, 116, 97, 93, 41, 10, 112, 114, 105, 110, 116, 32, 108] l = 'data = %s'%data+chr(10)+''.join([chr(e) for e in data]) print l
      
      






All Articles