LoginSignup
8
8

More than 5 years have passed since last update.

hello, worldの戦い 〜 #Min略d の参加者より

Posted at

CodeIQで、「Minority's hello, world」という問題が出題されて、それに回答してみました。

問題

「hello, world」と出力するプログラムを提出して下さい。

提出されたプログラムで使われている文字を、全挑戦者について集計します。

各文字には「(その文字を利用した挑戦者の人数)の2乗」というポイントが割り当てられます。

提出されたプログラムのポイントは、そのプログラムで使われている文字のポイントの合計となります。

提出コードのポイントが少ない順に順位をつけます。最小ポイントの方が優勝です。

詳細

細かいレギュレーションとして、

*コードに書ける文字はASCIIの32〜126のみ、改行やタブ、漢字などは使用不可
*出力は標準出力へ、エラー出力は不可
*出力は「hello, world」もしくは「hello, world(改行)」のどちらか(表記ゆれ、間違いに注意)
というようなことがありました。

自分の回答

自分は、Rubyで回答してみることにしました。戦略としては、多くの人が使いそうな文字を避ける、ということが重要になるので、その辺りを考えて書くことにしました。

1回め

1回め.rb
%@4`1`8`8`B`5K`58`J`B`E`8`0@.split(?`).map{|q|putc(q.to_i(36)+100)}

まずは、二重引用符や角カッコを避けるために、文字列を%記法で表現して、しかも区切り文字には他の言語でも現れなさそうな@を使っています。そして、これまた出番の少なそうなバッククオートでsplitすることで、36進法の文字列配列を生成します。ここでも?+1文字という、あまり見慣れない文字列リテラルとして引用符を避けています。

あとは配列ごとに36進法から10進法に戻して、ASCIIコード指定でputcさせるだけですが、eを使わないためにeachではなくmapとしています(何かが生成されますが、出力されないので無視できます)。

とりあえずはこれでそこそこ上に来たのですが、しばらくすると半分を超えるほど順位が低迷して来ました。で、やはり長いということに気づいて、コードの短さも意識して再作成してみることにしました。

2回め(最終形)

最終形.rb
$><<%W@68656C6C6F2C20776F726C64@.pack(%@H*@)

だいぶ長さが縮みました。まずは$>が標準出力で、それに<<することで出力を行います。その次はまたも%記法ですが、%W@...@では、中身を文字列にした配列を生成します。この状況で変数展開は不要なのですが、wは出力文字列中にあるので回避して大文字としています。

で、お題の文字列を16進で表した文字列1つの入った配列ができますが、それをpackでデコードします(この関数自体が暗号みたいですね)。これまたしつこく%記法で引用符を回避しています。

全体にコードは短くなって、英小文字もpackの4つだけになりました。

結果発表

途中経過も追いかけていたのですが、最終結果としては11位(Rubyトップ)となりました。トップに来た戦略の「文字列のxor」は薄々思いついてはいたのですが、Rubyでできないために放置していました。

他の人が繰り出す技で気になったものが、

  • PHPの関数名は大文字小文字を問わないのを利用
  • PHPに入らず、そのままhello, worldだけ書く
  • どう考えても、この勝負に向かなさそうなJavaであえて挑戦する姿勢

などです。

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8