bowwowforeachの日記

競技プログラミングをします。主にヒューリスティック/マラソン/ゲームAI。

CodinGameでバイナリデータを扱う

CodinGameでバイナリデータを扱いたい時ありますよね。ニューラルネットワークとか。

ソースコードで提出しないといけないので、バイナリデータを何らかの方法でテキスト形式に変換して埋め込んでおき、実行時にバイナリデータに戻すといった手順が必要になります。

バイナリデータをテキスト形式に変換する方法で有名なものにBase64がありますが、CodinGameにおいてはもっと良い方法があります。

 

Base64

まずBase64とは、バイナリデータを64種類の文字で表現する方法です。

手順

  1. バイナリデータを先頭から6bit読み取る
  2. この6bitを整数とみなすと0~63の値になる
  3. 値に対応する1文字を出力(変換テーブルを用意しておく)
  4. 1~3をバイナリデータなくなるまで繰り返す
    ※最後の6bitに満たないとこだけ特殊処理必要

という感じ(64進数に変換してるようなもの)

 

Base32768

CodinGameのコード長制限は恐らくUTF16で10万文字(2022/7/5 bowwowforeach調べ)

つまり'a'も1文字だし、''も1文字だし、''も1文字としてカウントされます。

使える文字を調べた結果55000文字ほどありました(サロゲートペアは良く分からんので除外)

このことからBase32768というのがデータ量効率、実装の手軽さで良さそうです。

 

手順

  1. バイナリデータを先頭から15bit読み取る
  2. この15bitを整数とみなすと0~32767の値になる
  3. 値に対応する1文字を出力(変換テーブルを用意しておく)
  4. 1~3をバイナリデータなくなるまで繰り返す
    ※最後の15bitに満たないとこだけ特殊処理必要

 

☆使える文字が55000あるので、55000進数変換すればもう少しデータ量効率は良くなるはず。処理時間や実装の手間と相談。

 

使える文字が連続している場所(文字コード)はこちら。(間違ってたらごめんなさい)

  • 0x3220 ~ 0x4DB4
  • 0x4DC0 ~ 0x9FEE
  • 0xAC00 ~ 0xD7A2

これで39274文字あるので十分足ります。

 

UltimateTicTacToeでニューラルネットワークを埋め込んだらこんな感じ。

 

以上です。