擬似乱数から「hello world」表示できるのをLINQで探してみた
まずはじめに。
元ネタ様→java - Why does this code print "hello world"? - Stack Overflow
先駆者様→ランダム関数による hello world | 札幌ワークス
を踏まえた上でLINQでやってみた。
とりあえず、参考サイトを見る限り、
「h, e, l, l, o, 0」と「w, o, r, l, d, 0」となるような並びになる
乱数の種をみつけるとのこと。
JavaとC#の擬似乱数のアルゴリズムは違うので別途求めようってのが趣旨!
まずはじめに、差分を取得するために計算
List<int> numList = new List<int>(); numList.Clear(); for ( c in "hello" ) { numList.Add( (char)(c - '_') ); } numList.Add(0);
同様なことを"world"でも実施する。
それぞれ、
「hello」→「9,6,13,13,16,0」
「world」→「24,16,19,13,5,0」
となる。
ここから、アスキー値の配列に合致する乱数の種を取得
List<int> seedList = new seedList(); seedList.Add( Enumerable.Range(int.MinValue, int.MaxValue) .Select(p => new { r = new Random(p), n = p }) .First(p => numList.All(q => q == p.r.Next(27))) .n );
待つこと10分ほどで回答を得ることができます。
※PCスペックによる差があります。
以下、ソースコード全文と実行結果です
using System; using System.Collections.Generic; using System.Linq; class Program { static void Main(string[] args) { List<int> numList = new List<int>(); List<int> seedList = new List<int>(); foreach (var str in new string[] { "hello", "world" }) { numList.Clear(); foreach (var c in str) { numList.Add((char)(c - '_')); } numList.Add(0); Console.WriteLine(string.Join(",", numList.Select(p => p.ToString()))); seedList.Add( Enumerable.Range(int.MinValue, int.MaxValue) .Select(p => new { r = new Random(p), n = p }) .First(p => numList.All(q => q == p.r.Next(27))) .n ); } Console.WriteLine("result"); foreach (var seed in seedList) { Random r = new Random(seed); int n = r.Next(27); do { Console.Write((char)('_' + n)); } while ((n = r.Next(27)) != 0); Console.Write(" "); } Console.WriteLine(); Console.WriteLine(string.Join("\n", seedList.Select((p, i) => string.Format("seedList[{0}] = {1}", i, p)))); Console.ReadKey(); } }
9,6,13,13,16,0
24,16,19,13,5,0
result
hello world
seedList[0] = -2039859520
seedList[1] = -2038483644