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

Codeへの愛とCuriosity

CodeIQ への出題・解説解題・その周辺について、思いつくままに。

対戦型 hello, world! の解説・解題

CodeIQ に「対戦型 hello, world! 」という問題
https://codeiq.jp/q/1356
を出した。

問題について

ideone にある言語で hello, world! を書いて、対戦させようという問題。

提出コードに課された条件は

  • ideone にある言語のどれかで書くこと。
  • 過不足なく「hello, world!」を出力すること。
  • ソースコードに使える文字は、アスキーコード 0x20〜0x7e の文字のみ。
  • ソースコードに使える文字は、100文字まで。

という具合。

戦いのルールはちょっと長くなるど

1文字目から順に対戦する。文字と文字の戦いのことを「マッチ」と呼ぶ。
マッチの勝敗は

  • 数字, 大文字, 小文字 が グー, チョキ, パー の関係。
  • 空白以外の記号は、数字・大文字・小文字 のいずれにも負ける。
  • 空白は 9, Z, z にだけは勝つが、それ以外のすべての文字に負ける。
  • 文字の種類が同じ場合は文字コードが大きいほうが勝ち。

というルールで決まる。

  • マッチで勝敗がついた場合は、負けた文字が退場する。
  • 引き分けの場合は両者が退場する。
  • これを、一方の文字がなくなるまで繰り返す。
  • 先に文字がなくなったほうが負け。

という感じ。

これで総当り戦を行い、勝ち点が多い人が優勝。という遊び。

実際に戦っている様子を

で見ることが出来る。

勝つために

ゲームのルールを理解し、どうすれば勝てるのかを正しく考察し、考察の結果を実現するということが求められている内容になっている。

問題の設定はやや馬鹿げているけど、挑戦した人が勝つためにすべきことは普通の課題解決の体裁になっているので、なんなら入社試験に使ってもいいぐらいに思っている。どうでしょうか。

ルールをきちんと理解すると、

  • ある文字が対戦する相手は、自分の前の文字を倒した相手になる(直前が引き分けた場合は例外となる)

ということがわかる。

引き分けを度外視すると「ZyZyZyZyZ」のような

  • あるカテゴリの最高位の文字(上記のZ)
  • 直前のカテゴリに勝つカテゴリに勝つカテゴリの、最高位のひとつ前の文字(上記のy)

を並べると連敗はしないということがわかる。
「z8z8z8」でも「9Y9Y9Y」でも良い。このようなパターンをできるだけ長く仕込みつつ、どう「hello, world!」を出すかが勝負になる。

あと。

  • 同じ文字を繰り返しても連敗する可能性が高く、得策とはいえない。
  • 同じカテゴリも避けたい。

という辺りも気にするといいと思う。

とはいえ。

全勝がいないことからもわかる通り、最後は運。予測できない他人に勝つことが必要で、同しようもない部分が多い。
あと。
「hello, world」という、「y」や「A」で薙ぎ払われる文字列を回避するために文字を費やすのか、ここを諦めるのかが難しいところ。
優勝コードは回避するために工夫をし、2位のコードは諦めてシンプルにまとめている。

言語の選択も難しい。

  • 引用符が不要な Bash
  • 文字列の xor が使える Perl
  • say が3文字だし「y」を含んでいて強そうな Perl6
  • 大文字小文字が混ぜ放題の SQL

辺りが強そうかと思っていたんだが、SQL の方はいなかった。残念。

総評的な何か

勝ち負けはまあいいんだけど、要求仕様である

  • 100文字以内
  • 改行不可
  • 「"hello, world!"」や「hello world!」ではなく「hello, world!」を出力する

を守れていない方が10名以上いたのが残念だった。

出題文面の工夫がもう少し必要だったかもしれないとも思う。

宣伝

オフラインリアルタイムどう書くやります。
4/18 土 です。
詳しくは https://yhpg.doorkeeper.jp/events/22168 を御覧下さい。