AccessViolation Exception

仕事でもはんだづけ、家でもはんだづけ

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でも行けるかも