読者です 読者をやめる 読者になる 読者になる

擬似乱数から「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」となるような並びになる
乱数の種をみつけるとのこと。
JavaC#擬似乱数のアルゴリズムは違うので別途求めようってのが趣旨!


まずはじめに、差分を取得するために計算

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