Toyama.rb #30 オフラインリアルタイムどう書く に参加しました

toyamarb.connpass.com

毎月恒例Toyama.rbに参加してきましたが、今回はいつもの「もくもく会」ではなく、「オフラインリアルタイムどう書く」でした。

やる前は、「制限時間付きの実装、何かのプロダクトになるわけじゃない実装、とかってあんまり好きじゃないんだよなー」とか実は思ってましたが、やってみたら想像以上に良かったです。

前日

Toyama.rbというRubyのコミュニティですが、利用する言語はRubyに限らないということだったので、直近で仕事で必要そうだけど実力が追いついてないSwiftでやろうと思いました。 また、ググって出てきたどう書くの問題を眺めて、「文字列を受け取って、文字列を出力、それが提示されている値と一致しているか」というフォーマットっぽかったので、assertのやり方を調べたり、いくつかのループのやりかた(Rangeを使ったり、forEachを使ったり)を調べておきました。

1問目

1問目は「フォークじゃない」 http://nabetani.sakura.ne.jp/hena/ord18notfork/ でした。 並んでいる状態をどうやって保持するか、"x"のお客をどうやって管理するか、といった部分で実装方法が別れていた印象です。

私は、実装速度・コードの簡潔さよりコードの読みやすさを優先して、ある程度オブジェクト指向的に書いていきました。 StoreクラスにRegiStateが5個あり、RegiStateにCustomer enumの配列を持ち、Customer enumでは normal | stop("x"の人)を表現しました。

1時間の制限時間だったのですが、「どのレジに並ばせるのか」の部分がうまく行かず、すべての人が最初のレジに並んでしまったまま制限時間を迎えてしまいました。 その当時の実装状況としては、 https://github.com/noboru-i/toyamarb30/blob/687815b5784bea04bb1fe0a41b7bcc3b67700500/ord18notfork.playground/Contents.swift です。

次の日、ちょっと修正したら、すべてのテストがパスしました。やっぱり、落ち着いて考えることは必要ですねー。。。

時間内に解けたのはkunitooさん1人だけで、Rubyで実装していました。 https://gist.github.com/kunitoo/624fcc785385c76168f6f1005183b954 min_by などを利用して、かなりスッキリしたコードで実装されている印象です。

みなさん、RubyJavaScriptC++Pythonなど、いろいろな言語で解いていました。 解く順番も、私みたいにオブジェクトの状態・操作を考えて一気に実装した人もいれば、TDD的に各メソッドの入出力をテスト書きながら進めた人、たくさんあるテストデータの中から簡単そうなものが通る実装を書きそれを育てていく、などいろんな人がいました。

2問目

2問目は「積み木の水槽」 http://nabetani.sakura.ne.jp/hena/ord13blocktup/ でした。 これもいくつかやり方があったようで、「下の段から走査していって、水が入る可能性のあるブロックを特定する」というものや、「列単位に、その左右の堰となるブロックの高さを求める」などがありました。

私は前者で、マス目を2次元配列と考え、マス目の状態を block | water | fall(0の列+そこに水が流れていってしまうマス) | undefined(まだ確定できていないマス) に分類し、undefinedで埋まっている状態から順に確定していくイメージで進めました。 手順としては、 ・入力文字列から block の位置を確定していく ・0の列を fall として、そこに水が落ちていくマス目も fall としていく ・まだ undefined の箇所について、隣接するマス目を確認しながら water を確定していく と考えました。 実装状況としては、 https://github.com/noboru-i/toyamarb30/blob/928b2f6fd4ee1d417350c0860d4b758e128a0c5f/ord13blocktup.playground/Contents.swift です。 問題の理解と考え方をまとめるのに時間がかかり、実装面でも2次元配列の扱い(どっちがx座標?など)に戸惑ってしまい、やはり1時間では解けませんでした。。。

ただ、mugi_unoさんの説明を聞いていると、3つ目の手順で undefined になっている部分は、すでに waterで確定っぽいですね。

これも制限時間内に1人だけ解け、しかも解いたのは学生、社会人は誰も解けずというちょっと不甲斐ない結果となりました。

これも次の日に修正しようと思ったのですが、列単位で水の量を計算できるというのを知ってしまったあとだと、今のやり方を進める気が起きず、とはいっても別のやり方を新規にやる気にもなれず。。。 やっぱり、オフラインで集まってやるからやる気になるんだなーと思いました。

感想など

実装・確認はXcodeのPlaygroundで実装を進めました。 リアルタイムで実行してくれるのは便利だったのですが、書きかけの状態でも動作してしまうためコンパイルエラーがじゃんじゃん表示されたり、Xcodeが急にクラッシュしたり、書き換えても実行結果が更新されなかったり、まだうまく使いこなすことができませんでした。。

個人的には、もうちょっと時間を使って、読みやすいコードにするとか、言語機能やライブラリをフルに使って短いコードで書くとかをやるのも面白いかなーと思いました。 (個人的に、時間に追われるのが苦手、というのが大きいですが。。。)

1時間やって、全員分の説明・レビューする流れは良かったです。 今までもくもく会で何をやっているかは知っていましたが、みんなが同じ時間に同じ問題を解くことで、それぞれがどういった考え方で実装を進めていくか、どんな言語をどの程度かけるのか、といったことがなんとなーく知れたのはよかったです。(特殊なケースではあるので、実際の仕事能力とは別の次元だとは思いますが)

個人的には「もくもく会」が好きなので、Toyama.rbはそれがベースだとうれしいなーと思いますが、定期的にこういったイベントがあるのはやっぱり楽しいですね。