YAPC::FukuokaのCode GolfでJavaScript部門1位だった
11月なのでけっこう前の話だけど、なんだかんだ書くの遅れてしまった。
エンジニアイベント『YAPC::Fukuoka』のサブイベントで、Code Golfが開催されていた。
Code Golfについて
与えられた問題に対して、いかに短いbyte数でコードを書けるか競う競技。Golf同様Parのbyte数が設定されている。
今までCode Golfをやったことがなく、右も左もわからない状態だったが、面白そうなのでとりあえずやってみた。
Holeは2つあり、最初はスコアが全く振るわなかったが、のめり込んで休日もずっとやっていたらJavaScript分野でHole1もHole2も1位をとることができた。


ちなみに、今回の最終結果を見るに Perl>Ruby>Python>JS>PHP の順で短くかけるっぽく結構不利だった。
でもJSが好きなのでJSで挑んだが、全体の順位は結構低かった。
最終的なCode
Hole1 (-10)
for(s=0;h=0,l=std.in.getline();print([s+=h,h]))for(k of l)for(c of'046889ABBDOPQR')h+=k==c
Hole2 (-27)
l=std.in.getline() for(w=[],j=65;m={},l.split` `.map(s=>{for(i=h=0;s[i+1];)m[v=s[i]+s[++i]]=-~m[v]}),eval("for(e in m)m[e]>h&&(h=m[e],b=e)"),h>1;)w.push((k=String.fromCharCode(j++))+':'+b),l=l.replaceAll(b,k) print(w+` `+l)
以下、Hole1について
雑記で備忘録っぽいけど。
Hole1の問題内容
- 複数行の文字列が渡される
- 0469ADOPQRのどれかがあれば
1としてカウント - 8Bのどれかがあれば
2としてカウント 累計,その行のカウントを繰り返し出力する
途中経過
初期実装(+1000くらい) https://perlbatross.kayac.com/contest/2025fukuoka/challenge/1/sample 言語をJavaScriptにすると表示される
途中 (+70くらい)
let s=0;std.in.readAsString().trim().split('\n').map(l=>{let h=[...l].reduce((p,i)=>{let a='8B0469ADOPQR'.indexOf(i);return a<0?p:a<2?p+2:p+1},0);console.log((s+=h)+','+h)})
上にもあげたけど最終実装(-10)
for(s=0;h=0,l=std.in.getline();print([s+=h,h]))for(k of l)for(c of'046889ABBDOPQR')h+=k==c
テクニック
色々調べながら様々なテクニックを駆使した。
- 基本
- 全体的にセミコロンやカッコを減らすようにしている
- イテレータブルな場合は.mapやfor文よりfor...ofを用いると短くできる
- JavaScriptだとメソッド呼び出しするより愚直に書いたほうが短い
- std.in.getline()
- 1行ずつ標準入力から文字列取得するメソッド
- 初期実装はstd.in.readAsString()だが、QuickJSのドキュメントを読むと実は存在している
- 途中のコード見ればわかるけど、これ使ったほうが短く書ける
for文
- 2つ目のcondition書くとこに、毎ループの最初にやりたいことをカンマ区切りで書く
- 3つ目の普通i++とか書くとこに、毎ループの最後にprintしたいのでここに書くと1byte省略
- 3重forループにすることで、{}を省略
- 最終実装だとセミコロンはfor文内でしか使っていない
最終実装では使ってないが、for文内はカンマ区切りで書けるので{}は省略できる
for(;;;){a=1;f.x()} ↓ for(;;;)a=1,f.x()
for...of
- for...ofのofの右側がクォートなのでスペースを省略
- print
- 実行環境のQuickJSで動くconsole.logのようなもの
- 出力しつつ、次のループのために累計として加算している
- 配列にすることで、カンマ区切りで出力してる(これ見つけるのけっこう大変だった)
console.log((s+=h)+','+h)})とか書いてたのでだいぶ省略print([s+=h,h])でOK
- 文字列探索部分
- 他の言語では正規表現にしたほうが短いが、JSだとメソッド名とかっこのせいで今回のケースだとただの比較が一番短かかった
/04…/.test(a)みたいな感じだとなんだかんだ長くなる
- 他の言語では正規表現にしたほうが短いが、JSだとメソッド名とかっこのせいで今回のケースだとただの比較が一番短かかった
最後に
Code Golf面白すぎた。type-challengesとかも面白かったけど、やっぱりコードのパズルは結構好きかも。
Hole1, Hole2ともにこれ以上短く書けるなら教えて下さい。使えるテクニックが気になる。
type-challenges全問完走した感想
数ヶ月前からやっていたtype-challengesですが、先日全問解答できました。(2024年4月現在163問)
いくつか思い出に残っている問題を紹介します。
一番初見きつかった問題
中級 296 Permutation
最初見たときわけがわからなさすぎて流石に模範解答見てしまった…。番号順に解答してたんだけど、モンハン無印でいうとドスランポスの次にいきなりリオレウスと戦うみたいな難易度の上がり方だった。でもこの問題以降Unionの分配法則は普通に出てくるので案外イャンクックだったのかもしれない。
一番おもしろかった問題
中級 30958 Pascal's triangle
パスカルの三角形。普通にコード書くみたいな感じで型って書けるんだと思った。
一番勉強になった問題
上級 553 Deep object to unique
完全にUniqueである型を実装する問題。似たようなケースに幽霊型があるが、あれとは異なり相互に代入可能なためどう実現すればいいんだろうと頭を捻って色々調べた問題。
一番達成感があった問題
最上級 517 Multiply
bigint同士の掛け算を行う問題。普通にArrayで実装すれば1000までなら実現可能だけどbigintってこれできるのか…と悩んでいたところ、Sumを先に解けと書いてあったので実装後急にひらめいて解けた。気持ちいい。
一番苦しんだ問題
最上級 697 Tag
渡された型にTagをつけて、あとから追加したり検証したり外せたりできる問題。テストケースがめちゃくちゃあって、全部のケースに対応するのがしんどかった…。
HasTag<Tag<1, 'foo'> | {}, 'foo'>
HasTag<Tag<0, 'foo'> | Tag<1, 'foo'>, 'foo'>
HasTag<Tag<0, 'foo'> | Tag<1, 'bar'>, 'foo'>
このへんとか。2つ目だけtrueにならなくちゃいけないが、HasTagに渡される型にあまり違いがなくてむずかった。
一番解答のコード量が多かった問題
最上級 6228 JSON Parser
まさか型でJSONパーサーを書かなくちゃいけないとは…。しかも字句解析からやるようになっており、始まる前からかなりの面倒くささを感じた。実際やってみると非常に泥臭い型を書き続ける必要があり、コード量が肥大化してしまった。
完走した感想
完走した感想ですが、最初はわけがわからないことが多くて混乱したけど、慣れてきたらパズルゲーム感覚でおもしろかったです。
Permutationとかは見てしまったけど、基本的に模範解答は見ないようにして進めることができました。苦労して解けた問題の自分の解答が模範解答と似てたときは結構嬉しかったです。
TSであまり詳しくなかった機能も問題を通じて調べることで理解を深めることができたので、やってみて良かったなと思います。
正直全問解答してしまったのでtype-challengesロスなんですが、もし問題が追加されたらまたやってみようと思います。
14年前にCで作ったゲームをRustで移植した

プレイヤーキャラクターがdo7beのアイコンにもなっているInnocent HeartをRustで移植した。
下記URLにてブラウザ上で遊べる。
https://do7be.github.io/innocent_heart/
昔話と移植した背景
作成した当時は18歳で、OpenGLを用いてゲームを作るという学校の課題のものだった。
ゲームを作るのが楽しすぎてめちゃくちゃ時間かけて作った記憶がある。
実はまだオリジナルのコードは残っていて、コンパイルして遊ぶことができる。macOSで動作確認済み。
https://github.com/do7be/innocent_heart/tree/c
しかしコンパイルするためにglpngというライブラリが必要なのだが、glpngは現在リンク切れを起こしており入手が難しい。
Dockerで動かそうにも、macOSでX Window SystemでGUIを動かすソフトウェアが使えると思ったのだが、去年辺りからOSアップデートで動かなくなった模様。
そのため、面倒だが最近習得したRustに移植してみようと思った。
Rustの話
そもそも現在メンテナンスされているものがあまりなく、選択肢として2つくらいしかなかった。Bevyも1.0.0になっていないので悩みどころではあった。
ただ、色々調べていくうちにわかったが、結局フルスクラッチのような形になり大変だった。
コード量は倍くらいになった。まあ元のコードが相当圧縮された書き方だったのもあるけど。
Componentという概念がとっつきにくくて難しいが(Unityにもあるやつだと思えばそう難しくはない)、ライフタイムを意識しなくても良いのでその点ではかなり書きやすかった。
ゲームはだいたいスパゲッティになるのでゲームエンジンの書き方に則れば結構きれいに書けて助かった。まあ最後の方はもう早く終わってくれという気持ちでめちゃくちゃに書いてしまったが…。
https://github.com/do7be/innocent_heart
ちなみにWebAssemblyにコンパイルしたものをGitHub Pagesで公開しているが、普通にローカルでコンパイルして実行することもできる。クロスプラットフォーム素晴らしい。
おわりに
まあなんにせよ、「昔このアイコンのキャラが主人公のゲームがあって…まあ今は遊べないんですが」みたいなやりとりをしていたのが嫌だったので、これで「このゲームのキャラです」と言えるようになったのがうれしい。
昔のバージョンよりめちゃ早くなっていてむずいんだが、まあ遊んでみてほしい(昔はマシンパワーに比例したスピードだった。今回60FPSにしたのでバランス調整はしているものの割りと早い)
Rustでライフゲーム書いてみた
代官山の蔦屋書店で本を買ってきた
東京に来てはや数年、割りと近所にありつつもいまだに行ってなかったので代官山の蔦屋書店に行ってみた。
目当ての本は特になく、適当に背表紙を眺めて興味が出たらちょっと読んでみるスタイルで3冊の本を買ってみた。
買った本
ゼロからトースターを作ってみた結果

https://www.amazon.co.jp/dp/4102200029
どっかのブログで見たことあったので読んでみたかったやつ。Dr.STONEみたいに鉱石掘ったりじゃがいもからプラスチック作ってトースター作る話。実話らしい。
江戸釣百物語

https://www.amazon.co.jp/dp/4309030106
江戸時代と釣りが好きなので自分にぴったりだと思って買った。日本は世界の他の国々と異なり、一般人がふつうに釣りを趣味として定着させている。その発端は江戸時代に庶民が釣りをするようになったところから、という認識。この辺深掘りしたかったのでちょうどいい。当時のエギとか興味ある。
オオカミと野生のイヌ

https://www.amazon.co.jp/dp/4767825016
大判の写真集で解説付き。オオカミと犬めちゃ好き。ハスキー飼いたい。
パラパラっとめくったら柴犬が出てきて、『実はオオカミに最も近いのは柴犬』と書いてあったのでマジ!?と思って買った。
他に気になった本
魚は数をかぞえられるか?
https://www.amazon.co.jp/dp/406527981X
人間以外の動物も数を認識している、例えばライオンなどは群れで狩りを行ったりする。タイトルによらず、話としては魚に限らず虫や両生類なども語られてそうだった。興味あったが、割りと長めで難しそうだったのでやめた。長い本は読めないのだ…。
魚にも自分がわかる
https://www.amazon.co.jp/dp/4480074325
鏡に映った自分の姿を見て寄生虫を取り除くことがあるらしい。かなり気になったが、難しそうだったので途中で挫折しそうだからやめた。
復刻版 動物の親子
https://www.amazon.co.jp/4863133707
かなりよさげな写真集だったけど、本の状態が良くなかったので購入を断念。
おわりに
蔦屋書店、広くていろんな本あるしめちゃくちゃ散歩してる犬が見れるのでめちゃ良かった。また行きたい。
Unity1週間ゲームジャムに初参加した
『unityroom』というUnityで作成したゲームを公開するサービスが、3ヶ月に一度行っている1週間ハッカソンに参加してみた。
今回のお題は「つたえる」だった。
Unity 1週間ゲームジャム お題「つたえる」 | フリーゲーム投稿サイト unityroom
始まったのはちょうど前回の記事から数日くらい後のこと。
なのでUnity本写経してから2週間位。
とりあえず2Dの簡単なゲームくらいなら作れる感じになっていたので今回も2Dで行こうと思い、お題から考えたのがチューチューロケットみたいな感じでコマに指示してゴールに導く的なゲーム。
と思っていたのだが2日目(春分の日なので休み)、朝起きてカブトクワガタのアクセシビリティがすごいという記事を読んで気が変わった。
「カブトクワガタ」は日本のゲームアクセシビリティの革命である | 猫の前足
ということで今回は目の不自由な方でも遊べるようなゲームにしようと思った。
作ったゲーム
つむぎちゃんのナビリンス | フリーゲーム投稿サイト unityroom

VOICEVOXという音声合成サービスの春日部つむぎちゃんを用いて、つむぎちゃんが暗闇の迷路の様子をプレイヤーにつたえることでゴールまで辿り着くというゲーム。
反省点
- ほぼ春分の日だけで作ったが、その日頑張りすぎて燃え尽きてしまい他の日はほとんど作業できなかった
- そもそも目の不自由な方が遊んだ場合にゲームとして面白いのかわからなくなってきた
- キーボード操作を求めている時点で、アクセシビリティの文脈としてなんか違う気がする
- 音声入力も考えたが、前述の通り力尽きたので実現できなかった
- つむぎちゃんはpixivで見て知っていたが、よくよく考えたらギャルなのでゲーム中の口調がおかしいことにあとで気づいた
参加した感想
- 思ったよりコメントも評価ももらえてうれしかった。フィードバックは大事。
- 参加者のゲームのクオリティ高すぎてビビった。売ってるゲームレベルなのではと思うものも。
- 他の参加者のゲームを遊ぶとその作者に通知が飛び、自分のゲームも遊んでもらえる仕組みになっていた。良く出来てるサービスだと純粋に感心した。
次回は参加できるか怪しいが(予定的にたぶん無理)、今度は燃え尽きないようにしたい。
Unityでゲーム作ってみた
先週の半ばからUnityの本を読み始めて数日で写経が終わったので、とりあえずゲームとして最低限成り立つとこまで作ってみた。
業務ではMacでコードを書いてるんだけど、今回はWindows機で実装してみた。Win機はゲームとネサフ用なので普段コードは書かないからキーボードがJISだしVisual StudioはVSCodeに比べて使いづらいし(特に初期設定のショートカット)で苦労した。
ちなみに買った本はこれ。一通り実装して理解できるように出来てて良い本だと思った。
