文字列・数値リテラルを使わずに Hello World


CodeIQ で出されていた問題です。タイトル通り,文字列と数値リテラルを使わずに Hello World と標準出力に出力するのが目的です。

C# と R で解いて提出しました。リファクタリングせずに汚い状態で出したのでリファクタリングしたものを以下に示します。

まずは C#。

using System;
using System.Linq;

class HelloWorld
{
   static void Main()
   {
      var hello = typeof(HelloWorld).Name.Aggregate(
         String.Empty,
         (acc, c) =>
         {
            var diff = Char.ToLower(c) - c;
            if (Convert.ToBoolean(diff) && !String.IsNullOrEmpty(acc))
            {
               acc += (char)diff;
            }
            return acc + c;
         }
      );
      Console.WriteLine(hello);
   }
}

文字列や数値のリテラルは禁止されているけど型のリテラルは禁止されていないので typeof を使っています。 typeof が禁止されていたら new して GetType しますが。

問題を解くにあたり,文字コード表を確認しました。アルファベットの大文字と小文字の差がちょうどスペースのコードと同じ (32/0x20) であることを発見したため,上のような回答になっています。リファクタリング前は HelloWorld と helloworld を構成してから先頭の文字を削って Zip して差を取って…という面倒なことをやっていました。それにしても先頭だけの処理や末尾だけの処理って面倒くさいですよね。

そして R です。

#!/usr/bin/Rscript

(function(x, y) cat(substitute(x), substitute(y), fill=TRUE))(Hello, World)

引数シンボルを文字列にするというのは, plot 関数を使っていれば当たり前のように使っている機能です。ちなみに出題者がフィードバックで fill=TRUE をスペースを出力するためのものだと勘違いしていましたが, fill=TRUE は末尾に改行を付けるものです。区切り文字を指定するのは sep ですが,これはデフォルトがスペースなので,いかにもこの問題向きでした。