ぱらぼろあんてな

ぱらぼろはイタリア語でバレーボールです.

WSL2+VSCodeでAtCoder用のRust環境を構築しよう!

はい,巷にありふれたやつです.ただ,プロジェクト構成をどうするかなど,意外に非自明なところを書いている記事が少ないかもと思って書いてみます.昔Rustを始めたばかりの頃,A問題のためのプロジェクト,B問題のためのプロジェクト,(以下無限)を作ってた時代がありました.そういうので悩んでる人には刺さる可能性が少しあります.自環境を汚したくない人はdocker化した方がいいですがそこまでは話さないです.また,非RustユーザでもAHCのtesterがRustで提供されることが多いし,強い人にもRustが多いので,やっといて損ないかもしれないです.

  1. Rustのインストール
  2. 必要なCargoコマンドのインストール
  3. rust-analyzerのインストール
  4. プロジェクト作成の仕方

Rustのインストール

Rustの公式サイトの手順で一発です.WSL好きの皆さんはWindows TerminalからUbuntuを立ち上げて以下を打ちましょう.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

これで,cargo, rustc, rustup というコマンドがインストールされると思いますので,

cargo -V
rustc -V
rustup -V

でそれぞれ最新バージョンであることを確認しましょう.こいつら誰ですかという方はとがさんの記事等を参考にしてください.え,2023年9月現在はAtCoderのジャッジサーバはv1.70.0なのではと思った勘の良いガキの皆さん,最終章でお会いしましょう.

必要なCargoコマンドのインストール

上記でcargoコマンドが使えるようになりました.cargoはビルドツールですが,以下のサブコマンドも取り入れることでAtCoderライフが快適になります.

  • cargo compete
    • 色んな競プロプラットフォームで問題をローカルに落としてくる,テストする,提出するとかを実現するためのサブコマンドです
    • AtCoder, yukicoderなどはもちろん,AtCoder Problemsに作ったバチャとかにも対応できます
  • cargo member
    • 子プロジェクトを親プロジェクトのメンバーとして登録する
    • プロジェクト構成の仕方のところで活躍します

それぞれ,

cargo install cargo-compete

などとするとインストールできます.

他にもhatooさん謹製のcargo snippetは超便利ですが,Rust製自作ライブラリが増えてきたらどうぞです.

rust-analyzerのインストール

rust-analyzerはエディタで編集してる時に補完してくれたり文法を確認してくれたりする言語サーバープロトコル(Language Server Protocol, LSP)です.Linterみたいなものです.例えばRustでは型推論が働くので全ての変数に自明に型を指定する必要はないですが,rust-analyzerのお陰でどの変数が何型か教えてくれるようになったりならなかったり.VSCodeへのインストールは簡単で,下図のように拡張機能からrust-analyzerを探してインストールするのみです.

プロジェクト作成の仕方

ここまでで必要なアイテムはたぶん出揃いました.ではアルゴのためのRustプロジェクトを作りましょう.これが一番重要ですが,空の親プロジェクトを作り,その下にABC319, 320,...などのナンバリングごとの子プロジェクトを作っていくことになります(他にベストプラクティスあればコメントください!!!).以下のようになることを目指します.

algorithm_v1_70_0/
├── Cargo.toml
├── abc319
│   ├── Cargo.lock
│   ├── Cargo.toml
│   ├── src
│   └── testcases
├── abc320
│   ├── Cargo.lock
│   ├── Cargo.toml
│   ├── src
│   └── testcases
├── compete.toml
├── src
│   └── main.rs
└── template-cargo-lock.toml

親プロジェクト生成&Rustバージョン指定

WSLで任意のディレクトリに移動し,以下コマンドを実行して親プロジェクトを作ります.名前はなんでもいいです.自分はアルゴ用とヒューリスティック用を分けているので,例えば以下のような名前にしています.

cargo init algorithm_v1_70_0

これで普通に1つのRustプロジェクトが作られますが,こいつのsrc/main.rsなどは一生日の目を見ません.

そして,勘の良いガキの皆さんお久しぶりです.Rustはプロジェクトごとに使用するRustのバージョンを指定できます.ついでにこのプロジェクトでのバージョンを指定しましょう.以下のコマンドでv1.70.0のtoolchain(cargoやrustcをひっくるめた名称と理解しています)を入れます.そして,親プロジェクト内でrust-toolchainという名前のファイルにバージョンを書き込んでおきます.

cd algorithm_v1_70_0
rustup toolchain add 1.70.0-x86_64-unknown-linux-gnu
echo 1.70.0-x86_64-unknown-linux-gnu > rust-toolchain

そうするとあら不思議,cargo, rustcのバージョンが1.70.0になります.VSCodeでConnect to WSLし,この親プロジェクトを開いた状態で以下を進めてください.

cargo competeを使うための設定

親プロジェクトの中に移動し,以下コマンドを実行してcargo competeをAtCoderで使えるようにしましょう.

cargo compete init atcoder

以下の質問が来ると思いますが,自分は2で回答します.

Do you use crates on AtCoder?
1 No
2 Yes
3 Yes, but I submit base64-encoded programs
1..3: 2

2023年9月現在,デフォルトで作成されるcompete.tomlが,v1.42.0対応の古いものです.なので,以下に差し替えてください.使わないcrateはコメントアウトすればよいです.ビルド時間が命取りになる可能性もありますので...

子プロジェクトとしてのナンバリングごとのプロジェクト作成

ゴールが近いです.親プロジェクト内で以下を打ってみてください.

cargo compete new abc320
cargo member include abc320

そうすると,以下のような感じになるかと思います.

.
├── Cargo.toml
├── abc320
│   ├── Cargo.lock
│   ├── Cargo.toml
│   ├── src
│   │   └── bin
│   └── testcases
│       ├── a
│       ├── a.yml
│       ├── b
│       ├── b.yml
│       ├── c
│       ├── c.yml
│       ├── d
│       ├── d.yml
│       ├── e
│       ├── e.yml
│       ├── f
│       ├── f.yml
│       ├── g
│       └── g.yml
├── compete.toml
├── src
│   └── main.rs
└── template-cargo-lock.toml`

また,親プロジェクトのCargo.tomlに以下のように書き込まれるはずです.

workspace = {members = ["abc320"],exclude = []}

これによって,abc320がalgorithm_v1_70_0の子プロジェクトであることが認識されます.たぶん. VSCodeを親プロジェクトで開いた状態で,全ての子プロジェクトに対してrust-analyzerが働く状態になってるかと思います.

A問題を実際に解いてみてください.型チェックや補間は効いてますでしょうか.提出前にテストしたくなったら以下を打ってください.

cd abc320
cargo compete t a

ローカルに落として来たテストケースをよしなに実行してくれます.標準エラーも出してくれるのでこれでデバッグが事足りることも多いです.ちなみに以下のコマンドだと,普通のRustバイナリの実行になります.

cargo run --bin abc320-a

いざ提出!

cargo compete s a
or
cargo compete s a --no-test (ローカルテストなし)

ローカルテストなしは,AHCもしくはPCスペックが低くて想定解でもTLEしちゃうときに使います.ジャッジ結果がリアルタイムに返ってきて,無事ACになったでしょうか.

さいごに

もしかしたら非自明かもしれないRustでAtCoder環境を作るときのプロジェクト構成に焦点を置いて書いてみました.WSL最高!VSCode最高!cargo compete最高!です.質問・加筆修正案等あればコメントお願いします.

HEROZに入社して1年が経ちました

2022年9月にHEROZという会社に入社し,なんやかんやで約1年が経ちました.今のところ楽しくやれてます.初投稿なので自己紹介や振り返りを兼ねてHEROZに来る前や来た後について書き散らします.

  1. 来る前
    1. 修士課程
    2. 某研究所
    3. 某SIer
    4. 某web系
    5. フリーランス
  2. 来た後
  3. これから

来る前

HEROZは5社目です.ぱらぼろさんの社会人歴は現在7年目なので,モンスタージョブホッパーです.よいこのみんなはこうならないように.

修士課程

研究の傍らで部活のコーチをしていて,消費したエネルギーを週5のラーメン(うち1食は二郎系)で補う日々でした.

あまりに研究熱心だったので(?),海外大で博士課程に進学しようと思って就活をしませんでした.少ないバイト代を叩いてTOEFLを5回(当時のレートで1回約2万円です)くらい受けましたが73点しか取れず,留学は足切り(非英語圏でも90がボーダー)でした.英語の勉強のために学内の留学生たちに絡みに行き,よく飲みに行きました.夢のない自分に比べ,大きな志を持って異国の地に学びに来る彼ら彼女らを素直に尊敬しました.ビアポンも教えてもらいました.ある日,飲みに来いよ!と誘われたが明日研究室で進捗報告があるからまずいと言って断ると,"Hey! don't worry. Tomorrow is tomorrow." などと言ってくる悪友がいたり(結局飲みに行った),とあるフランス人の子が酔っ払った時に,"Why are they pissing the river?" (なんでみんな鴨川に小便するんだい?) と言っていたのが謎に印象的です.昼間の鴨川等間隔カップルは有名ですが,夜中の鴨川等間隔小便ニキはたぶんまだまだ知名度が低い概念ですね.

後から考えると,就活は絶対にした方が良かったです.身分を失わないように所属研究室の博士課程進学の権利は得ておきましたが,お金がないので気乗りしませんでした.謎にM2の年明けにペーパーを書いたり学会発表とかしていました.

某研究所

学内の研究室の先生に拾われて,その人が大学外に持っている研究所の技術員として就職しました.

ja.wikipedia.org

いわゆる関西文化学術研究都市(けいはんな学研都市)という,つくばに似たところにある研究所で,電車の最寄り駅からバスで20分揺られて着くようなだだっ広い田舎でした.技術員として1年働いたらD進しないかと言われて二つ返事ではいと言い,学振を書いて内定を頂いたのですが,1年持たず半年後に見込みがないからやっぱり来ないでと言われちゃいました.大学の事務に学振辞退の手続きに行った時の事務の方の驚いた顔が忘れられないです.何度も確認されましたが,自分の記憶でも何度確認してもクビにされているので素直に辞退しました.

人生でクビ経験のある人間が周りに自分しかいなくて,よく友人にイジられています.また,これ以来現在でも,博士号は「足の裏の米粒」の如く頭の片隅で気になっている状態です.

SIer

部活の先輩のツテで東京のSIerに来ました.グレンタウンのポケモンけんきゅうじょみたいな殺風景なところから一転,スーツを着てヒルズ族の仲間入りです.

第二新卒で入ったので新入社員研修を受けるのですが,理不尽に怒鳴り散らかすタイプの講師に盾突き続け,入社から1ヶ月半までの間に人事に8回呼び出されました.150人いた同期入社で自分ともう一人が,人格に問題があるので現場配属に不適格という烙印を押されてしまいましたが,ギリギリ裏で大きなパワーが働き,システムエンジニアとしてのキャリアがスタートです.

環境は狂っていて,コンサルとSIerの雰囲気を併せ持つ現場で,残業は美徳(残業代なし)で,毎日誰かが喧嘩して,緩やかにみんな精神を病んでいきました.そもそもスーツを着て革靴を履いて朝から晩までプログラミングなんかできるわけないです.午前3時にヒルズのブラインドが全て自動で開いて薄明かりが差し込むのが見えると虚しくなったものです.ただ,社会人・エンジニアリングの基礎を丁寧に叩き込まれたのも事実です.まだ社会人をやれてるのはこの会社のお陰なのでその点でとても感謝しています.

某web系

hbr.org

Date Scientist: The Sexiest Job of the 21st Centuryという記事をご存知でしょうか?何かと意思決定が適当であることに不満を持っていた自分はSexiest Date Scientistになりたい一心でデータサイエンスの門戸を叩きました.「社内にアプリから蓄積されてきたデータあるんやけど,これ使ってなんかできへんかな思てんねん」と言ってきた会社に,なんと未経験かつ社内初のデータサイエンティストとして就職しました.後々考えると,これは極めて危険な行動だったなと思います.

データサイエンティストは,当初抱いていたイメージよりはキラキラしておらず,泥臭いデータ集めや四則演算のみで集計して可視化をするだけなことも多かったです.当時右も左もわからず1人プロジェクトをやっており,独学だけであまり専門的な内容に踏み込めなかったため,Sexiest Date ScientistからDate Scientistの部分を抜き取った単なるセクシー人材と化していました.ただ,E資格取得の講座を受けさせてもらったり,画像認識APIAWSに構築できたのはとても学びがありました.ここでの経験をもとに,Qiitaに以下の特級呪物を落としてきました.

qiita.com

一方で電話番やオフィスの掃除など「これ本当に自分がやらないといけないの?」と思わざるを得ないことをやらされることが多かったです.あと伝説的にブラックでした.

フリーランス

技術的に色々なことをスピーディにキャッチアップしたい,仕事上の人間関係を最小化したい,一時的にでも収入を上げる必要があったりとかして,フリーランスをやってみようとなりました.あまりに転職しすぎてるため,友人にはとうとうフリーターになったかとよく言われました.

ここで初めて画像認識を本格的にやり始めました(フリーランスでそれはいいのか?).オンプレのサーバにsshしてオレオレdocker containerを作ってその中でモデル開発するみたいな感じでした.

ところがフリーランスのいいところは個人的な経験からすると収入が高いくらいで,社会的信用がない(自分はカードを作れなかったり,家を新たに借りれなかったりしました),確定申告めんどくさい(知り合いの税理士に破格で依頼しました),仕事上重要なことを任せてもらえない,首切りのリスク,孤独などのマイナス面も多いです.なってみてからわかった愚か者なのですが,技術的に確固たるものを持った人がそれを商売道具としてやるから個人事業主と呼ばれるのであって,ひよっこデータサイエンティストが適当になっていいものではなかったです.父も母も個人事業主なのにこれに気づかないのはどら息子過ぎました.

なお,フリーランスの時に可処分時間が大幅に増えたことと,自分のスキル志向にマッチしそうな気がしたのでこの頃に競技プログラミングを始めてみました

来た後

転職サイトの情報を常にアップデートするようにしていると有象無象からスカウトが来ることは有名事実ですが,ある時HEROZからのスカウトを受けて仰天しました.こんなに強い会社が自分にスカウトを送ってくる時代か,人手不足なのかな?などと思いました(実際人手不足は今もそうです,We are hiring!!).競プロをやっているとHEROZに関わりのある強い方々の雷名が轟くこともあり,ここの一員になれたら自分も何らか強くなれるかなと思い,すぐに面談しましょうとなりました.面接は緊張していて記憶はないのですが,あれよあれよと進んでオファーをいただき,特にフリーランスに未練もないのですぐ承諾しました.とても嬉しかったです.

入社して1ヶ月で右アキレス腱を断裂して2週間ほど業務を休んでしまいましたが,それ以来は元気にやれています.最適化やりたいです!と言って来たのですが,社内的には画像認識の人と思われています.あとは流行りの生成系とかも引き合いが強いので一部やっていたりします.

技術的におもしろいことをやっているだけではなく,かなりムダが排除されているのが私の推しポイントです.社員の皆さんはスマートで人間的にも尊敬できる方々です.ソフトウェアインストールの制限とか謎の社内調整とかないし,残業もあまりないです.会社のA100はプライベートユースもOKです.エンジニアファーストの風土が根付いていて,こんなに大切にされることあるんだって感じです.HEROZは控えめに言って天才な人がちらほらといて,技術への異常なキャッチアップスピードの早さに振り落とされないようにしがみつくので必死です.会社の雰囲気は,よく言われるのですが研究室みたいで,自分にも良く合っています.気になるあなたはカジュアル面談いつでもです!募集職種一覧は以下です.学生の方もおそらく通年でインターンとか柔軟にやってくれそうな雰囲気はあります.リファラルもありますのでDMお待ちしております.

heroz.co.jp

これから

仕事と競プロを両立して頑張っていきたいなあというところです.キャリア的には機械学習や最適化に関する色んな技術スタックを扱えるようになっていきたいです.競プロはアルゴ入緑,ヒュ入青が当面の目標ですね.DPをがんばります.