私たちはその日を記念して、キヌ、ポリグロット、パリンドロームを書きます2 ^ 2 ^ 3

PalidromePolyglotQuine







プロフェッショナルな日を迎えて、人間の言語のすべての翻訳者に機械語へのお祝いを申し上げます。バグが減り、同等以上のクールなアイデアがもたらされることを願っています。 そして、アイデアの贈り物として、私は1つの美しい問題の解決策を提案します-出力で独自のテキストを出力するコードを書くことは、異なる言語のインタープリターとコンパイラーに有効であり、同時にソースコードが逆になったときに正しく実行されます







少し前に、PHPで同時に解釈し、JavaでコンパイルできるコードPhpJava.javaについて学びました 。 結局のところ、この考え方は新しいものではありません。複数のコンパイラーまたはインタープリターに一度に有効なコードは、 ポリグロットと呼ばれます。 さまざまなインタープリターまたはコンパイラーの処理行およびコメントの特性により、このようなコードを作成することは可能です。







たとえば、Javaでは、文字「/」などの通常の形式とUnicodeレコード「u002F」の両方で文字を記述できます。 C#コンパイラでは、このようなエントリは無効になります。 ただし、それらがコメントで「隠されている」場合、一方ではC#コードのコンパイルを妨げず、他方ではJavaコードで有効になります。 たとえば、コードAを C#でのみコンパイルし、Javaでコンパイルせず、コードBを Javaでのみコンパイルし、C#でコンパイルしない場合は、次のスニペットを使用します。







//\u000A\u002F\u002A A//\u002A\u002FB
      
      





C#コンパイラは通常の方法でこのコードを「認識」し、コメントはコメントのままです。







 //\u000A\u002F\u002A A//\u002A\u002FB
      
      





しかし、Javaを使用すると、すべてがより興味深いものになります。 Unicodeレコードが変換され、次のようになります。







 // /* A//*/B
      
      





両方の言語に共通の命令を組み合わせて、異なる言語を共有することにより、任意のプログラムを作成できます。







ただし、トリックはそのようなUnicodeエントリに限定されません。 たとえば、Cライクな言語には、どのコードをコンパイルする必要があるかを決定できるプリプロセッサディレクティブがあります。 コンパイルされていないコードでは、コードをまったく異なる言語で配置できます。 たとえば、次はC ++およびPython( ここから )の多言語コードで、Pythonコードは#if false



セクションに配置されてい#if false



。 そして、シーケンス'''



はPythonコードのコメントを開始および終了します。







 #include <stdio.h> #if false print "Hello world" ''' #endif int main() { printf("Hello world"); return 0; } #if false ''' #endif
      
      





たとえば、HTMLでは、コメントは一連の文字<!--



で始まり、これも使用できます。 6と16の言語で同時に動作するより複雑なポリグロットがあります。 1つ目はすべての言語のメッセージ「hitforum」を表示し、2つ目はより興味深い動作をします。コンパイルまたは解釈される言語の名前を表示します。







C、シェル、Perl、Brainfuck、Befunge、Whitespaceのポリグロットコード



 # define xu /* v # :::::::::::::::::::>>>>>>>$$$a"muroftih"#[>:#,_@] eval 'echo "hitforum";exit';sub echo { print "@_\n"} __END__>++++++++++>++++++++++[>+++++++++++>++++++++++ +<<-]>------.+.>++++++.<---.+++++++++.>--.+++ .<--.<<. */ main() { printf ("hitforum\n"); }
      
      





16言語の多言語コード
 # /* [ <!-- */ include <stdio.h> /* \ #`{{coding=utf-8\ "true" if 0 != 0 and q != """0" ; ` \ \ if [ -n "$ZSH_VERSION" ]; then \ \ echo exec echo I\'ma zsh script.; \ \ elif [ -n "$BASH_VERSION" ]; then \ \ echo exec echo I\'ma bash script.; \ else \ echo exec echo I\'ma sh script.; \ fi`; #!;#\ BEGIN{print"I'm a ", 0 ? "Ruby" :"Perl", " program.\n"; exit; } #\ %q~ set =dummy 0; puts [list "I'm" "a" "tcl" "script."]; exit all: ; @echo "I'm a Makefile." \ #*/ /*: */ enum {a, b}; \ \ static int c99(void) { #ifndef __cplusplus /* bah */ unused1: if ((enum {b, a})0) \ (void)0; #endif unused2: return a; \ } \ static int trigraphs(void) { \ \ return sizeof "??!" == 2; \ } \ char X; \ \ int main(void) { \ \ struct X { \ \ char a[2]; \ };\ if (sizeof(X) != 1) { \ \ printf("I'm a C++ program (trigraphs %sabled).\n", \ \ trigraphs() ? "en" : "dis");\ \ }else if (1//**/2 )unused3 : { ; \ printf("I'm a C program (C%s, trigraphs %sabled).\n", \ c99() ? "89 with // comments" : "99", \ trigraphs() ? "en" : "dis"); \ } else { \ printf("I'm a C program (C89, trigraphs %sabled).\n", \ trigraphs() ? "en" : "dis"); \ } \ return 0; \ } /* # \ \begin{code} import Prelude hiding ((:)); import Data.List (intercalate); import Language.Haskell.TH; import Data.String; default (S, String, Integer, Double); data S = S; instance Eq S where { _ == _ = False }; instance IsString S where { fromString = const S }; ifThenElse cte = case c of True -> t; False -> e cPP = False; {- #define cPP True -} main :: IO () main = putStr ("I'm a Literate Haskell program" ++ bonus ++ ".\n") where _ = (); bonus | null details = "" | otherwise = " (" ++ details ++ ")" details = intercalate ", " [ name | (True, name) <- extensions ] :: String extensions = (bangPatterns, "BangPatterns" ) : (templateHaskell, "TemplateHaskell" ) : (rebindableSyntax, "RebindableSyntax" ) : (magicHash, "MagicHash" ) : (overloadedStrings, "OverloadedStrings" ) : (noMonomorphismRestriction, "NoMonomorphismRestriction") : (scopedTypeVariables, "ScopedTypeVariables" ) : (cPP, "CPP" ) : (unicodeSyntax, "UnicodeSyntax" ) : (negativeLiterals, "NegativeLiterals" ) : (binaryLiterals, "BinaryLiterals" ) : (numDecimals, "NumDecimals" ) : [] (!) = (!!) bangPatterns = [True] ! 0 where foo !bar = False templateHaskell = thc $(return (TupE []) :: ExpQ) rebindableSyntax = null (do { [()]; [()] }) where _ >> _ = [] :: [()] magicHash = foo# () where foo = ['.']; "." # _ = False; foo# _ = True overloadedStrings = "" /= "" noMonomorphismRestriction = show foo == "0" where foo = 0 bar = foo :: Double unicodeSyntax = let (★) = True in (*) where (*) = False negativeLiterals = -1 == NNa binaryLiterals = let b1 = 1 in 0b1 == 1 numDecimals = show 0e0 == "0" scopedTypeVariables = stv (0 :: Double) == "0.0" data{- = -} NN = NNa | NNb deriving Eq; instance Num NN where { fromInteger _ = NNa; negate _ = NNb; _ + _ = NNa; _ * _ = NNa; abs _ = NNa; signum _ = NNa } instance{- = -} (Num a) => Num (e -> a) where { fromInteger = const . fromInteger; negate = (.) negate; abs = (.) abs; signum = (.) signum; x + y = \e -> xe + ye; x * y = \e -> xe * ye } class THC a where { thc :: a -> Bool }; instance THC () where { thc _ = True }; instance THC (Q a) where { thc _ = False }; class (Show a, Num a) => STV a where stv :: a -> String stv = const $ show (f 0) where f = id :: a -> a instance STV Double -- : \ \end{code} # \ ]>++++++++[<+++++++++>-]<+.>>++++[<++++++++++>-]<-.[-]>++++++++++ \ [<+++++++++++>-]<-.>>++++[<++++++++>-]<.>>++++++++++[<++++++++++> \ -]<- - -.<.>+.->>++++++++++[<+++++++++++>-]<++++.<.>>>++++++++++[ \ <++++++++++>-]<+++++.<<<<+.->>>>- - -.<+++.- - -<++.- ->>>>>+++++ \ +++++[<+++++++++++>-]<- - -.<<<<<.<+++.>>>.<<<-.- ->>>>+.<.<.<<.> \ ++++++++++++++.[-]++++++++++""" else 0 # \ from platform import * # \ print("I'm a Python program (%s %s)." % # [-][ \ (python_implementation(), python_version())); """--><html><head> <!--:--><title>I'm a HTML page</title></head><body> <!--:--><h1>I'm a <marquee><blink>horrible HTML</blink></marquee> page</h1> <!--:--><script language="JavaScript"> <!--: # \ setTimeout( // \ function () { // \ document.body.innerHTML = "<h1>I'm a javascript-generated HTML page</h1>"; // \ }, 10000); // \ //--> </script><!--: \ </body></html><!-- }} # \ say "I'm a Perl6 program."; # """ # */ #define FOO ]-->~
      
      





キヌポリグロット



C#とJavaでクインポリグロットを作成するには、クインとポリグロットの開発の原則を組み合わせる必要があります。 結局のところ、このトピックは新しいものではありません。codegolfのWebサイトでは、ユーザーは誰がポリグロットまたはポリキンを短くするかを競います。 ただし、この問題に関するより詳細なC#およびJava言語のオプションはありませんでしたので、修正しました。







このようなキネポリグロットを作成するには、両方の言語の行で禁止されており、プログラム自体の行にある文字をエスケープする必要があります。 これらの文字は引用符、「改行\ n、およびバックスラッシュ\です。コードのサイズを小さくするために、\ u000A、\ u002F、\ u002Aなどの文字の繰り返しシーケンスもエンコード文字列自体の単一文字に置き換えられています。 C#およびJavaコンパイラに有効な結果のキリンポリグロット:







PolyglotQuine.cs.java、757文字:



 //\u000A\u002F\u002A using System;//\u002A\u002F class Program{public static void//\u000A\u002F\u002A Main//\u002A\u002Fmain (String[]z){String s="//@#'^using System;//'#^class Program{public static void//@#'^Main//'#main^(String[]z){String s=!$!,t=s;int[]a=new int[]{33,94,38,64,35,39,36};String[]b=new String[]{!&!!,!&n!,!&&!,!&@!,!&#!,!&'!,s};for(int i=0;i<7;i++)t=t.//@#'^Replace//'#replace^(!!+(char)a[i],b[i]);//@#'^Console.Write//'#System.out.printf^(t);}}",t=s;int[]a=new int[]{33,94,38,64,35,39,36};String[]b=new String[]{"\"","\n","\\","\\u000A","\\u002F","\\u002A",s};for(int i=0;i<7;i++)t=t.//\u000A\u002F\u002A Replace//\u002A\u002Freplace (""+(char)a[i],b[i]);//\u000A\u002F\u002A Console.Write//\u002A\u002FSystem.out.printf (t);}}
      
      





ポリグロットパリンドローム



タスクをさらに複雑にしましょう:quine-polyglot-palindromeを作成してみてください。 回文とは、両方向で等しく読みやすい数字またはテキストであることを思い出させてください。 パリンドロームパイルの開発原理については、 3年前のプログラマーの日の記事説明しました 。 回文コードの原則は、プログラムのミラー部分が単一行または複数行のコメントに配置されることであり、これはコンパイルを妨げません。 C#の最も単純なコードパリンドロームは次のとおりです。







 /**/class P{static void Main(){}};/*/;}}{)(niaM diov citats{P ssalc/**/
      
      





ご覧のとおり、複数行のコメント/*



は中央から始まり、最後まで続き、シーケンス*/



で閉じます。 行が完全に対称になるように、先頭に空のコメントが必要です。







そこで、回文、多声、および馬を作成する原理を組み合わせて、次のコードを作成しました。







PalidromePolyglotQuine.cs.java、1747文字:



 /**///\u000A\u002F\u002A using System;//\u002A\u002F class Program{public static void//\u000A\u002F\u002A Main//\u002A\u002Fmain (String[]z){String s="`**?`@#_^using System;?_#^class Program{public static void?@#_^Main?_#main^(String[]z){String s=!$!,t=s;int i;int[]a=new int[]{33,94,38,64,35,95,96,63,36};String[]b=new String[]{!&!!,!&n!,!&&!,!&@!,!&#!,!&_!,!`!,!?!,s};for(i=0;i<9;i++)t=t.?@#_^Replace?_#replace^(!!+(char)a[i],b[i]);t+='*';for(i=872;i>=0;i--)t=t+t?@#_^[i];Console.Write?_#.charAt(i);System.out.printf^(t);}}/",t=s;int i;int[]a=new int[]{33,94,38,64,35,95,96,63,36};String[]b=new String[]{"\"","\n","\\","\\u000A","\\u002F","\\u002A","/","//",s};for(i=0;i<9;i++)t=t.//\u000A\u002F\u002A Replace//\u002A\u002Freplace (""+(char)a[i],b[i]);t+='*';for(i=872;i>=0;i--)t=t+t//\u000A\u002F\u002A [i];Console.Write//\u002A\u002F.charAt(i);System.out.printf (t);}}/*/}};)t( ftnirp.tuo.metsyS;)i(tArahc.F200u\A200u\//etirW.elosnoC;]i[ A200u\F200u\A000u\//t+t=t)--i;0=>i;278=i(rof;'*'=+t;)]i[b,]i[a)rahc(+""( ecalperF200u\A200u\//ecalpeR A200u\F200u\A000u\//.t=t)++i;9<i;0=i(rof;}s,"//","/","A200u\\","F200u\\","A000u\\","\\","n\",""\"{][gnirtS wen=b][gnirtS;}63,36,69,59,53,46,83,49,33{][tni wen=a][tni;i tni;s=t,"/}};)t(^ftnirp.tuo.metsyS;)i(tArahc.#_?etirW.elosnoC;]i[^_#@?t+t=t)--i;0=>i;278=i(rof;'*'=+t;)]i[b,]i[a)rahc(+!!(^ecalper#_?ecalpeR^_#@?.t=t)++i;9<i;0=i(rof;}s,!?!,!`!,!_&!,!#&!,!@&!,!&&!,!n&!,!!&!{][gnirtS wen=b][gnirtS;}63,36,69,59,53,46,83,49,33{][tni wen=a][tni;i tni;s=t,!$!=s gnirtS{)z][gnirtS(^niam#_?niaM^_#@?diov citats cilbup{margorP ssalc^#_?;metsyS gnisu^_#@`?**`"=s gnirtS{)z][gnirtS( niamF200u\A200u\//niaM A200u\F200u\A000u\//diov citats cilbup{margorP ssalc F200u\A200u\//;metsyS gnisu A200u\F200u\A000u\///**/
      
      





残念ながら、モンスターは大きすぎる(1747文字)ことが判明しましたが、これはUnicode文字の長いチェーンとC#およびJava言語の冗長性によるものです。 他の言語では、はるかに小さいサイズのキリン-パリンドローム-ポリグロットを書くことができると確信しています。







次に、このプログラムがどのように実行されるかを確認しましょう。 開始するには、すべてのコメントを取り除き、コードを正しくフォーマットします。







C#でフォーマットおよびクリアされたPalidromePolyglotQuine.uine.cs.javaコード
 using System; class Program { public static void Main(String[] z) { String s = "`**?`@#_^using System;?_#^class Program{public static void?@#_^Main?_#main^(String[]z){String s=!$!,t=s;int i;int[]a=new int[]{33,94,38,64,35,95,96,63,36};String[]b=new String[]{!&!!,!&n!,!&&!,!&@!,!&#!,!&_!,!`!,!?!,s};for(i=0;i<9;i++)t=t.?@#_^Replace?_#replace^(!!+(char)a[i],b[i]);t+='*';for(i=872;i>=0;i--)t=t+t?@#_^[i];Console.Write?_#.charAt(i);System.out.printf^(t);}}/", t = s; int i; int[] a = new int[] { 33, 94, 38, 64, 35, 95, 96, 63, 36 }; String[] b = new String[] { "\"", "\n", "\\", "\\u000A", "\\u002F", "\\u002A", "/", "//", s }; for (i = 0; i < 9; i++) t = t.Replace("" + (char)a[i], b[i]); t += '*'; for (i = 872; i >= 0; i--) t = t + t[i]; Console.Write(t); } }
      
      





リストから、変数s



には、行で禁止されている文字がエスケープされ、繰り返されるシーケンスが圧縮されているプログラムコードが含まれていることが明らかになります。 以下は、出力文字列t



を形成するために使用される、フォーマットコード-文字-置換の文字の表です。







コード シンボル 交換
33
94 ^ \ n
38 \
64 @ \ u000A
35 \ u002F
95 _ \ u002A
96 ` /
63 //
36 $ s


次の段階で、文字列t



が連結され、出力が回文になるように反転されます。 数字872(文字列の長さt



)は、クインがすでに書き込まれた後に計算する必要があることに注意してください。 このためには、すでに記述されたコードを実行する必要がありますが、これには一定の困難も伴います。







そのようなコードを書くための主な基準は、その純度ではなく、テキスト形式で最小サイズを達成することでした。 したがって、もちろん少し奇妙に見えます。







ご覧のとおり、このようなクインを書くのに複雑なことは何もありません。 これがすべて実際に機能するとは思わない人のために、テストはFreaky-Sourcesリポジトリに書かれています(実行するにはJavaのインストールが必要です)。







あなたのコメントを他の言語や他の興味深い成文化であなたのカインド-パリンドローム-ポリグロットに投げ入れて、私は喜んでそれらを研究します。







もう一度、すべてのプログラマーとシンパサイザーにおめでとうございます!








All Articles