鍋谷 武典さんからCodeIQにて出題された問題, Minority's hello, worldを解いた時の戦略をメモ.
問題の概要は次の通り.
「hello, world」と出力するプログラムを提出して下さい。
提出されたプログラムで使われている文字を、全挑戦者について集計します。
各文字には「(その文字を利用した挑戦者の人数)の2乗」というポイントが割り当てられます。
提出されたプログラムのポイントは、そのプログラムで使われている文字のポイントの合計となります。
提出コードのポイントが少ない順に順位をつけます。最小ポイントの方が優勝です。
提出したコード
<?='%#&-%bk!&#&&'^'MFJAJNKVIQJB';
戦略
比較的短く書ける言語を選択する
短く書ける, かつ, 使える言語としてRubyとPHPで迷ったのですが, 文字列出力だけであればPHPのほうが短く書けるのでPHPを選択しました.
文字同士の排他的論理和をとる
これは「hello, world」を構成する文字を使わないための回避策で, PHPならではの技になります.
PHPには文字同士の排他的論理和をとると, その文字のASCIIコード値同士の排他的論理和に対応するASCIIコード文字を返す仕様があります.
e.g. |
---|
また, 文字同士だけでなく, 文字列同士の排他的論理和をとることで, 演算を一括して行うことも可能です.
e.g. |
---|
アルファベットの大文字をなるべく使う
定数やクラス名など特定の部分でしか使われにくいアルファベットの大文字をふんだんに(しかし必要最小限に)盛り込みました.
また, 「hello, world」を大文字にした「HELLO, WORLD」を使ってくる人もいると考え, なるべくこの文字列を構成する文字の使用を避けました.
細かいところにこだわる
その他, 細かいところ
- 文字列を囲うときは「"」ではなく「'」を使う
- 標準出力に使われる文字(put, print, echo, (, ), ", '...)を避ける
→今大会1位のPINさんのコードを参考にすると最初の「'」も外せたみたい
(外していたら2位だったかも(´・ω・`)) - 末尾に「;」が必須な言語(c++, java, ...)より, 末尾に「?>」が必要だと思っている人が多そうなPHPを使ってくる人が多いと考え, 文字列の末尾を「;」にした
→結果見る限りあまり変わらない様子 - 「 (空白)」を使わない
結果
名だたる強者たちとの心理戦(?)の結果, 前回大会同様, 銅メダルでした!
おまけ
文字列同士の排他的論理和を試せる, イケてないコード(なぜかRubyで書いた)
string1 = "hello, world"
string2 = "%#&-%bk!&#&&"
each_slice1 = string1.each_char.map(&:ord)
each_slice2 = string2.each_char.map(&:ord)
puts each_slice1.zip(each_slice2).inject('') { |sum, v| sum += (v[0]^v[1]).chr }
# => MFJAJNKVIQJB