CodeIQにMinority's hello, worldという問題が出ていました。
問題が見れなくなっているので引用すると、こういうもの。
■問題の概要
「hello, world」と出力するプログラムを提出して下さい。 提出されたプログラムで使われている文字を、全挑戦者について集計します。 各文字には「(その文字を利用した挑戦者の人数)の2乗」というポイントが割り当てられます。 提出されたプログラムのポイントは、そのプログラムで使われている文字のポイントの合計となります。 提出コードのポイントが少ない順に順位をつけます。最小ポイントの方が優勝です。
出題者の鍋谷さんによる結果発表と解説がこちら。
http://nabetani.sakura.ne.jp/codeiq/hwbattle2/
で、私はF#で適当に(あまり考えずに)下のようなコードをぶっこんで
System.Console.Write("hello, world")
結果、スコアは29,198点、順位は58位となり、当然上位には入れませんでした。
で、ここからがコードゴルフ。
じゃあ、どういうコードだったらもっとスコアが良かった(低くなった)か?ということで再考したのがこちら。
printf<|"%s"<|"hello,\u0020world"
これだと何点取れてたかを計算し直したコードがこちら。
let addCount (xs: (char*int) seq) (ys: (char*int) seq) = Seq.append xs ys |> Seq.groupBy fst |> Seq.map (fun (c,zs) -> c,(Seq.sumBy snd zs)) let calc (xs: (char*int) seq) (ys: char seq) = ys |> Seq.map (fun c -> Seq.find (fun (c',_) -> c=c') xs) |> Seq.sumBy (fun (_,v) -> v*v) [<EntryPoint>] let main argv = let othersCount = [(' ', 42); ('!', 9); ('"', 24); ('#', 10); ('$', 12); ('%', 10); ('&', 10); ('\'', 19); ('(', 28); (')', 26); ('*', 6); ('+', 8); (',', 36); ('-', 17); ('.', 24); ('/', 7); ('0', 17); ('1', 11); ('2', 15); ('3', 9); ('4', 18); ('5', 14); ('6', 11); ('7', 8); ('8', 12); ('9', 8); (':', 11); (';', 19); ('<', 20); ('=', 16); ('>', 15); ('?', 11); ('@', 4); ('A', 5); ('B', 4); ('C', 11); ('D', 13); ('E', 16); ('F', 9); ('G', 4); ('H', 16); ('I', 5); ('J', 5); ('K', 5); ('L', 16); ('M', 6); ('N', 5); ('O', 16); ('P', 4); ('Q', 7); ('R', 14); ('S', 5); ('T', 8); ('U', 4); ('V', 5); ('W', 13); ('X', 3); ('Y', 2); ('Z', 4); ('[', 11); ('\\', 14); (']', 13); ('^', 10); ('_', 8); ('`', 4); ('a', 20); ('b', 9); ('c', 26); ('d', 30); ('e', 33); ('f', 9); ('g', 6); ('h', 31); ('i', 21); ('j', 9); ('k', 9); ('l', 26); ('m', 8); ('n', 19); ('o', 33); ('p', 26); ('q', 8); ('r', 37); ('s', 23); ('t', 28); ('u', 17); ('v', 8); ('w', 22); ('x', 9); ('y', 12); ('z', 4); ('{', 10); ('|', 7); ('}', 12); ('~', 9)] //let myCode = "System.Console.Write(\"hello, world\")" let myCode = "printf<|\"%s\"<|\"hello,\\u0020world\"" let myCount = myCode |> Seq.distinct |> Seq.countBy id let count = addCount othersCount myCount printfn "%s" myCode printfn "%d" (calc count myCode) 0
実行結果は、20,964点。もしかしたら50位以内には入れたかもしれないけど、他の人のスコアも変動するので、実際はどうでしょうね。(計算すれば出ると思いますが、面倒なのでコードに落としていません)