samayotta.show()

好きな映画は『たまこラブストーリー』です。

【スターティングGo言語雑感】ARC83[C][D]

 

スターティングGo言語 (CodeZine BOOKS)

スターティングGo言語 (CodeZine BOOKS)

 

 GO言語を競技プログラミングに使用できないか検討している。

動機はC++の挙動や言語仕様、STLの使い勝手の悪さにイライラさせられたから。いろいろマクロを試したりしたが、根本的な言語仕様で限界を感じたし、何より理不尽なエラーメッセージには消耗させられた。もうあの赤い文字を見たくなく、それだけで競プロから離れる理由になりかねなかった。

代替言語の候補はJava / scala / GO / rustの4つ。GO以外では、インターンでお世話になった企業/部署で実戦投入されていたので是非scalaを使ってみたい気持ちがあり、GOとの間で揺れた。最終的には評判の良い入門書『スターティングGO』の存在で決めた。

 

GOの所感

  • エラーメッセージがわかりやすい

少なくとも自分が何を間違えたのか、はっきりとした英語として教えてくれる。ので、エラーメッセージにひとつひとつ対応していけば、自然に正しいプログラムが完成するようになっている。

  •  fmt.Println()の使い勝手が良い

 すなわちプリントデバッグが快適。

  • リスト/連想配列が(それなりに使い勝手の良い仕様で)実装されている

ただしリストにあたる配列/スライスはやや複雑な仕様になっていて、自分もまだ挙動を把握しきれていないところがある。基本的にはC++vectorコンテナなどよりはずっと良いが、Python / Rubyのリストよりは使い勝手で劣る。

  • 競プロ的な関数は充実していない

標準入力、max、min等の簡単な計算関数が[競プロに使いやすい仕方で]入っていない。これらは特に難しくなく自作できるが、まえもって準備をしておく必要はある。

  • ループがややだるい。

range based forの使い勝手はC++11やBoostよりはずっとマシ。とはいえ、range based for以外も使うことが多い競プロでは、Cのfor文とほぼ同等のループを書かなければいけないGOはややだるい。REPマクロは正直なところGOでも欲しいと思った。マクロが定義できるのかは知らないが。

  • 型が厳しい

これは賛否両論。例外なく一切の暗黙型変換を許さない仕様なので、たとえばfloatとintの間でも容赦なく型エラーを吐く。ライブラリ関数も厳密に引数の型を指定しており、勝手に融通を効かせてはくれない。しかしC++のようにそれでバグったりしないので筋道がはっきりしており、その意味で安心感はある。必要に応じてやはり適切な関数を自作する必要がある。

  • 学習コストが非常に小さい

よく言われていることだがこれは本当。C++Pythonを使ったことのあるプログラマにとってはGOは非常に敷居が低い。言語仕様がコンパクトなことに加え、文法や予約語に?がつくようなことがない。実際、僕は一日半程度である程度GOプログラムが書けるようになったので、興味のある人はまず使ってみるのがよい。[プログラミングに慣れていない人がGOをどう思うかはよくわからない。C++よりは確実に良いとは思うが]

 

以下は先日のARC083[C][D]のGO解答。これをみてもらえば、GOがどのような雰囲気なのかざっとつかめるはず。

 

C: Sugar Water - AtCoder Regular Contest 083 | AtCoder

ARC083C.go

一言コメント : 解法はメモ化再帰DFS。[A,B,C,D]の手を単に全部読めば良く、初手は[A,B]としておいて一般性を失わない。

GOコードはPythonからの人力トランスコンパイル。この問題に限って言えば、計算時間で困るわけではないので、計算をうまくやってくれるそちらでよかったとは思う。

D: Restoring Road Network - AtCoder Regular Contest 083 | AtCoder

ARC083D.go

一言コメント : 解法は逆ワーシャルフロイド。例の式を思い浮かべ、ありえない場合、ありえる場合、ありえたとしてそこに辺があるかどうかを調べる。当然O(n^3)のため、スクリプト言語では(普通に考えて)間に合わないのでコンパイラ言語の出番となる。この問題では使用しなかったが、グラフ理論の問題とGOの相性は良さそうで、特に構造体の扱いが上手なので活躍が期待できる。