c# でQuine(クワイン)実装
出来ました。何故かFizzBuzz付きです。
using System;using System.Linq;class Program { static void Main() { var l = new System.Collections.Generic.List<char>(); l.Add((char)0x46); l.Add((char)0x69); l.Add((char)0x7a); l.Add((char)0x7a); l.Add((char)0x42); l.Add((char)0x75); l.Add((char)0x7a); l.Add((char)0x7a); var fb = new string(Enumerable.Range(1, 50).Select(i => (i % 15 == 0) ? l.Aggregate(string.Empty, (s, x) => s + x) : (i % 5 == 0) ? l.Skip(4).Aggregate(string.Empty, (s, x) => s + x) : (i % 3 == 0) ? l.Take(4).Aggregate(string.Empty, (s, x) => s + x) : i.ToString()).Aggregate(string.Empty, (s, x) => s + x + (char)0x7c).ToArray()); var zz = @"1|2|Fizz|4|Buzz|Fizz|7|8|Fizz|Buzz|11|Fizz|13|14|FizzBuzz|16|17|Fizz|19|Buzz|Fizz|22|23|Fizz|Buzz|26|Fizz|28|29|FizzBuzz|31|32|Fizz|34|Buzz|Fizz|37|38|Fizz|Buzz|41|Fizz|43|44|FizzBuzz|46|47|Fizz|49|Buzz|"; var str = "using System;using System.Linq;class Program {{ static void Main() {{ var l = new System.Collections.Generic.List<char>(); l.Add((char)0x46); l.Add((char)0x69); l.Add((char)0x7a); l.Add((char)0x7a); l.Add((char)0x42); l.Add((char)0x75); l.Add((char)0x7a); l.Add((char)0x7a); var fb = new string(Enumerable.Range(1, 50).Select(i => (i % 15 == 0) ? l.Aggregate(string.Empty, (s, x) => s + x) : (i % 5 == 0) ? l.Skip(4).Aggregate(string.Empty, (s, x) => s + x) : (i % 3 == 0) ? l.Take(4).Aggregate(string.Empty, (s, x) => s + x) : i.ToString()).Aggregate(string.Empty, (s, x) => s + x + (char)0x7c).ToArray());var zz = {1}{2}{1};var str = {1}{0}{1};Console.WriteLine(str,str,(char)34, fb); }} }}"; Console.WriteLine(str, str, (char)34, fb); } }
QuineFizzBuzz/Program.cs at master · kamiyaowl/QuineFizzBuzz · GitHub
最小記述のc# Quine
var s = "var s = var s = ...;;";
となってしまうのが再帰的定義の難点。これを解決してくれるのがConsole.WriteLine
様ですね*1
var s = "var s = \"{0}\";"; Console.WriteLine(s,s);
でもこれだとエスケープシーケンスが消えてしまう。
var s = "var s = {1}{0}{1};"; Console.WriteLine(s,s,"\"");
お、行けそう。とおもいきやQuineなので他のコードも出力しなければいけないわけで
var s = "var s = {1}{0}{1};Console.WriteLine(s,s,"\"");"; Console.WriteLine(s,s,"\"");
ダメですね。文字列のエスケープは荷が重すぎる。
var s = "var s = {1}{0}{1};Console.WriteLine(s,s,(char)34);"; Console.WriteLine(s,s,(char)34);
これでよし。
気をつけるべきはConsole.WriteLine
で{
は{{
でエスケープしなければいけないことと、ダブルクォーテーションの処理。後は適当にやれば最初のコードになりました。めでたし。
*1:string.Formatでも行けるかも