週記(2021/12/06-2021/12/12)

12/06(月)

先週は週記を投稿したあと比較的すぐに布団に入った、のだが、うっかりラノベを読み始めてしまった。結構終わり際で読み止しにしていたもので、そのまま読了。

「天才最弱魔物使いは帰還したい」2巻。今巻も非常に良かった。先週も書いたが、なろうでは読み落としていた伏線を探しつつ丹念に読んでいた。僕は槻影さんの書く文章やキャラクターが好きだし、中でもこの作品の前身となる「Tamer's Mythology」がハチャメチャに好きなので、他のラノベを差し置いてもこれはじっくり読みたかったのだ。と、まあいかにもわかっている風に書いたが、思い返してみればそれほどクリティカルな描写はなかったかもしれない。しかし、結末を知った状態で改めて主人公フィルの行動を眺め渡してみると、なるほどかなり初期から真相に気付いているらしき行動をしていたのだなとわかる。

あとは、登場する情報屋について。元の「Tamer's Mythology」でも《明けの戦鎚》の面々がフィルの正体を聞きに行ったのが初出だった。僕はこの部分がか!な!り!好きである。これはもともと1巻の範囲の出来事だったのだが、改稿後の1巻からはその描写が消えていて、ひどくがっかりしたのを覚えている。今、2巻にて改めて回想という形で語られ、非常に満足している。

『L等級のLは……Legend《伝説》のLなんだぜ』

https://ncode.syosetu.com/n4224gn/92/

読み終えて、さらにハーメルンを開いて読み進めようとした段階で寝落ちした。午前9時だった。

午後4時半前に起床。即座に進捗報告スライドを錬成し、定例会に臨む。結局、先週は見事に一文字もコードを書けていない。業務をやっていたつもりなのでそれで何とか「仕事してる感」を醸し出そうとしたが、冷静になると質問事項のやり取りに結構待ち時間が発生したので、その間に十分進められたのだと気づき、愕然。やる気がなさすぎるだろ。

今週も勉強会まで終えて、学食に向かう。今日はこれが一食目となる。このような場合、ミールカードの当日分をできるだけ使うためにも丼モノの小とカレーの中を頼んで腹をパンパンにして帰っているが、今日は丼が中サイズしか用意されていなかった。いけるだろうと思って購入したが……かなり辛かった。今日はまずカレーから攻めて、できるだけ噛まずに飲み込むことで満腹中枢の反応を少しでも遅らせようという戦略で戦った。多少効果があったようにも感じられる。

帰宅して業務を開始する。マニュアルや研修の模様を録画した動画を見つつ頑張っていた。それなりに頑張ると終わりそうな光明が見えてきたが、やはり初めてということがあって判断に迷うこと、通常どのように処理されるのか知らないことが多々あるので、完成はしなかった。どれもそれなりのところで留めて、また明日こそ質問を投げることにしよう。

ACL Practice ContestのSCCが、ACLを使うコードからRubyのトポロジカルソートライブラリtsortを使うものに縮められていた。メソッド名strongly_connected_componentsが長いので、TSort.methodsから配列アクセスで取り出してsendするという、Pythonのnetworkxゴルフテクみたいなことをやっていて面白い。それにしても、このライブラリの設計がよくわからなかった。頂点の子を取得するために「頂点を渡されると、その子を列挙する」というコールバック関数を作らせるのはわかるが、このライブラリはさらに1段階深く進んで「頂点を渡されると、その子を列挙して、これまた渡された関数の引数にして呼び出す」というものを要求している。つまりちょうど、コールバック関数が二段階になっているようなものだ。

と、書いていて気付いた。つまりこれは、Rubyで「列挙」を行おうとしているのではないか?ただ列挙して集めて返すだけだと、いちいち配列オブジェクトを生成することになって、パフォーマンス上の問題があるかもしれない。それで逐一生成させたいので、順当にいけばEnumeratorを返すべきかもしれないが、いちいちブロックを渡して実行するのはライブラリでは行ってくれないので自分でブロックを実行しなければならない、のような感じか?ブロックを我々が実行することになっているのも、これまたパフォーマンス上の問題かもしれない。詳しくはわからない。ちなみに頂点そのものもこのような形で列挙しなければならないので、都合2種類のラムダ式を書いている。

atcoder.jp

夜中からラノベを読み始めた。理由は定かではないが、なかなか読み進められずちょっと苦労した。

午前4時読了。「王立魔術学院の《魔王》教官I」。かなりハリー・ポッターを思い起こさせる学院の描写だったが、当然のことながら内容はそこそこ違う。中盤まではクラスの生徒たちのバックグラウンドが語られて、主人公である教官が問題を解決していく様が心地よかった。終盤にはバトルもあって、教官の強さが遺憾なく発揮されておりこれもまた良い。ラストで意味深に登場した敵キャラの正体が数ページ先で開示されており、びっくりした。それはそれで面白いのか、それとも正体不明の敵キャラが紛れ込む学院生活に耐えられない読者への配慮か。主人公が認めている上級生の一人と敵キャラの特徴が被っていたので、まさか裏切り……と冷や冷やしていた僕にとってはありがたかった。

冷蔵庫の中でぶよぶよになりかけていた梨を剥いて食べた。母が剥いてくれたものの形を思い起こして見比べてみるに、僕は芯の周りを深く切り落としすぎな気がする。どのくらいが不可食部分なのかわからず、とりあえず色が違うところを確実に除去するようにしていたが、実はそこまで神経質になる必要はないのかもしれない。

布団に入って別のラノベを開いたら、午前7時半になってしまった。就寝。

12/07(火)

午後1時起床。

とりあえず質問事項を投げておくか、としたら、そのままずるずると業務を始めてしまい、学食に行くタイミングを逃した。結局午後2時くらいから1時間休憩をとることにして、その間に購買に行って菓子パンを大量購入してきた。また戻ってきて頑張っていたが、単調なくせに細かい作業ばかりが続くフェーズで、かなりつらい。プログラマなんだから何かコード書いてサクッと効率化したい、と思うも、どこからどこまで機械に任せられるのか定かではなく、結局手でやったほうが確実で速いという話になってしまう。しばらくやって、自動チェック待ちの状態に進んだ。なかなか結果が返ってこないようだったので、ここで一息入れることにしてラノベを開いた。

そのまま2時間くらいかけて読み切った。「何と言われようとも、僕はただの宮廷司書です。」。こんなタイトルなのであらすじを読む前から無自覚チート系主人公だとわかり、実際そうだったので満足。自分のことを一般人だと言い張る丁寧語系主人公ということで、かなり「公女殿下の家庭教師」を想起させられるが、そちらより性格が幾分攻撃的になっている気がする。あとは、魔法が上手いとか、ヒロインが王女さまとかも似ている設定。まあこういう設定はいくらあってもいいので、良い。「公女殿下の家庭教師」とは違いこちらの主人公はより明確に強いので、読んでいて安心感はあった。ヒロインの挙動もより僕の好みに近い。

PCの画面を見るとまだ自動チェックの結果が返ってきていなかったが、リロードすると見れた。それを使ってさらに進めていたのだが、ほとんど終わり際になって、またわからないところが発生してしまった。実は今日が期限のタスクなので、どうしよう……という感じ。とりあえずできているところまで報告して、自分の誠実さをアピールすることにした。期限をぶっちぎっている時点で誠実さも何もないのだが。もう本当に自分がどうしようもない。見通しが甘すぎる。

KUPC2021でチームメイトに任せたっきりの問題から1問、C問題を解いた。かなりややこしい解き方をして合わせるのに苦労した。

C - Gacha

最適解は1\dots N区間に分かれ、各区間ではコインを全部拾ってからガチャを全部回すことになるだろうという予想を立て、「左からi枚のコインを拾って左からi個のガチャを回した」ときのコスト(をちょっと変えたもの)でdpをした。遷移はj\lt iからiまでのコインを一気に拾って、その後j+1のガチャに一直線に向かい、次に「コインiの位置に」帰ってくるまでの距離を足すことになる。ガチャiの位置に向かってしまうと、区間から外れるコインを拾ってしまう可能性があり、コスト計算の絶対値を外す関係上よくない。

さて、コストは行って・戻って・行っての絶対値3つで書けるが、このうち1つは絶対値記号を単純に外せる。残り2つ、|B_i-A_j|+|B_i-A_{j+1}|をどうするかが問題だが、A_jA_{j+1}B_iの大小を見るとうまくいった。A_{j+1}\le B_iのとき、A_{j+1}\le B_{i-1}\lt B_iからそのようなjの値は尺取りで求められる。よってこれに対しては、尺取りと同時に絶対値を外した後のA_jA_{j+1}寄与分を含めた累積最小値を持っておけばよい。A_j\le B_i\lt A_{j+1}のようなjは高々一つしかないので、毎回計算。B_i\lt A_jに対しては、これまた絶対値を外した後の寄与分を含めた最小値を、スライド最小値で管理すればよい。

夜は日記を書いていた。投稿して布団に入り、なろうの更新を確認すると、章の変わり目で投稿が途絶えていたシリーズに閑話っぽい感じの話が投稿されていた。それを読んで、ついでにシリーズ全体を読み返していたら、アッという間に朝になってしまった。午前9時になったので一旦今日の夜に出た質問事項を投げて、やり取りのためにまだ少し起きていようと思いつつ布団に戻ってなろうを読んでいたが、今度は寝落ちしてしまった。閲覧記録によれば午前9時半すぎのことだった。

12/08(水)

午後3時くらいに目を覚ます。Slackを見ると、僕が寝落ちしたちょっと後に質問に対する回答がついていた。やることは分かったつもりだが具体的にどうするのかわからなかったので、その旨返信すると、なんと通話で説明してくださるらしい。相手方の空き時間を提示されたので、1時間後を指定して、恐れ知らずにもまたちょうど1時間寝た。

午後4時、執念の起床。通話開始が少し遅れるらしく、その間パソコンの前に座っていていろいろ確認していたら、少し眠気も取れてきた。30分ほど指南を受けつつ操作を行い、その後も少し取り組んで、ようやくマニュアルにある工程をすべて終わらせた。タスクのステータスを最終チェック待ちにして、これでひとまず終了だろう。結局期日は1日オーバーしてしまった。社会人にあるまじき醜態。猛省。

学食に行った。今日もフードファイトで、ヒレカツカレーの中を2皿。ほぼ咀嚼せず10分で流し込んだので、辛さ(からさではなくつらさ)は月曜日ほどではなかった。しかし食べ終わってみると、まさに腹に一物(物理)があるような感じがしてちょっとまずい。無理はするものではない。

夜、いよいよゼミ準備を始める……前に、火曜日のPythonの講義で出ていた課題を終わらせた。これは今週も、講義スライドに出てきたコード片をサンプルコードと組み合わせたビジュアライズを追加するくらいで終了。

とりあえずほかの人の発表資料を読み返そうとしたが、前回の発表者が残している部分はアップロードされていなかったし、教科書を見ると分量的にもかなりあるようだったので、その部分はばっさり放置してすぐ自分の担当箇所を読み始めることにした。幸い章の変わり目にあたり、内容的にもパッと見前章の内容は関わってきていないため、何とかなりそう。途中集中を切らしつつも、とりあえず30分くらいは喋れるかなという分量の準備ができた。今日はこのくらいにしておこう。

Twitterでnullさん(競プロer的にはstoqさん)のブログが流れてきたので読んでいた。大変に面白かったのでスターをつけまくって、Twitterに戻ってみると、すでに投稿ツイートのRT数が20を超えており、他の人も面白いと思っていることが分かってうれしくなった。

null-mn.hatenablog.com

午前3時からラノベを読み始める。面白すぎて途中で切り上げることができず、しかも結構丁寧に読んでいたので、読了したのは午前8時半だった。

「時々ボソッとロシア語でデレる隣のアーリャさん」3巻。非常に良かった。1巻も2巻も良くて、このシリーズがすっかり好きになっていたので、丁寧に読んでいたというわけ。カバー折り返しにある著者コメントでは自信のない様子を見せている筆者だが、毎巻毎巻間違いなく面白いストーリーを作ってくる。そう、そもそもストーリーが面白いのである。ロシア語要素やデレ要素は僕の認識ではスパイスでしかない。

この巻は主人公政近の妹に焦点を当てた巻。2巻で登場した妹の従者も絡めて和気あいあいとしていたが、そこはやはり生徒会長を目指すうえで戦う敵ということもあり、終盤はバチバチバトルしていた。2巻のバトルとは違い、中学時代に仲間同士だったこともあってお互いの手は知れていて、搦め手もあってドキドキした。このシリーズでは主人公がロシア語を扱えることや、妹が妹であることを周囲に伏せて進んできている。ネタバレにはなるが、終盤でそのうちのほんの少しが明かされ、思わず震えが来た。

毎巻ラストの見開きイラストには訳なしのロシア語が書かれている。1巻は適当にググったのが正解で、2巻はスルーしたが、3巻ではロシア語で使われる文字の一覧からコピペして翻訳に掛けてみることにした。「с удовольствием」であった。なるほどなあ、という感じ。またネットで検索すればこれまでの巻のロシア語の訳も出てきたので、思い返してニヤニヤしていた。

午前9時前に攻めの就寝。3時間くらいで起きればゼミに間に合う。

12/09(木)

午後1時、ゼミの友人からのモーニングコールで起きて血の気が引いた。遅刻である。かなり急いで山に登ったが、30分程度遅刻した。教室に入って一息ついた段階で、途中で購買で買ったパンを食べようと思ったら、先生に止められた。僕はその時、本当にそのタイミングでパンを食べてよいと考えていたが、後から思い返してみれば普通の講義中でも食事をしてはいけなかったような気がする。長いオンライン授業生活で何もかもを忘れてしまった。

耐え切れずリプライツリーに書いたが、改めて言語化しておこう。最初は久しぶりに叱られて凹んでいただけで、あまり真剣には考えていなかった。教室の空気みたいなものも感じ取れていなかったが、どうやらそれなりに重い空気になってしまっていたらしい。そのことに全然気づけていなかった、ということにまず愕然とした。これは自分が空気を読めなかったと取れて、人間関係に関する能力の低さを暗示している。さらにそのような真剣味のなさから、ゼミ後に改めて注意された時も先生の意図をわかっていない反論を繰り出してしまった。これもまずかったらしくて追加ダメージ。

発表については、今週も前の発表者が終わらなかったのでまた来週。数週間前、筆が乗って大量に準備してしまったらしい。思う存分やってほしい。ゼミ後は今週も部屋を移動してボドゲ。今日はディクシットとスカルをプレイした。ディクシットは僕自身はいいとこナシだったが、友人の一人がありえないくらい正解してポイントをガンガン稼いでいてびっくりした。自分ひとりだけ正解して残りの人は自分の出したカードに騙される、という最も1ターンの点数が高くなる状態を何度も達成して本当にすごかった。スカルは良くもなく悪くもなく。今日はみんなイケイケでチャレンジをしていたので、ブラフはそれなりに成功していた。これまで何週間かやってきた結果、場にあるすべてのカードをめくるのが勲章みたいになっていて、みんな積極的に狙っていた。

さて、僕が叱られているのに真剣味がなかったという話を上で書いたが、これはスカルの途中で僕が言及して、周りから得られた反応から分かったことだった。特に発表中だった友人には申し訳ない。重くなった教室の空気にやりにくさを感じたことだろう。自分の空気の読めなさが原因で友人を失うことは避けたいが、人付き合いを今から鍛えるというのも難しい。とにかく慎重な行動を心掛けたいものだ。特に遅刻癖は何とかする必要がある。今日もたくさん目覚ましをかけていたが、起床の決め手になったのはモーニングコールだった気がするので、とりあえず来週もそれをお願いすることにした。そのくらいの仲の良さは、あるはず。

学食で食事して帰宅。年末にその年1年で読んだ本を振り返るような記事は、去年も書きたいと思っていたが、なんとなく怯んでいるうちに実現には至らなかった。今年ととりにゃあアドベントカレンダーを見ていて、それに便乗すれば筆も乗りそうだと感じ、勢いで参加登録をした。ととりにゃあ氏に全く関係がないことは許してほしい。Amazonのほしいものリストを貼るよりは、マシだろうか?

ととりにゃあ Advent Calendar 2021 - Adventar

少しコードゴルフをしてからラノベを手に取ったがあまり集中できず、ネットサーフィンをしているうちに眠気が強くなってきたので、日付が変わったあたりで布団に入った。

すぐにでも眠れるはずだったが、うっかりなろうの読み返しを始めてしまう。そうこうしているうちに眠気が消え、ラノベの続きを読み始めて、そのまま読了。

「ひきこもりの俺がかわいいギルドマスターに世話を焼かれまくったって別にいいだろう?」。キャラクターの設定はよかったし、最後の見せ場もかなり劇的だったが、それ以外は印象が薄い。主人公は最強という設定で、実際あまりにも強すぎてただでさえ少ないバトルシーンがどれもあっさり終わってしまっていた。ヒロインとの絡みがメインだったのだろうかテンポはよかったが、僕が求めていた描写は少なかった。

さらに1冊読了。「灰原くんの強くて青春ニューゲーム」。めちゃくちゃ面白かった。逆行転生モノで、空気が読めず手ひどい失敗をした高校生活をやり直す話。ハイスペック主人公も良いし、それに無自覚なのはさらに良い。そんな主人公が慎重に態度を取り繕ってやり直す高校生活が全部思い通りにいくかというとそうでもないようで、シリーズ全体を通して微妙な緊張感があるのは刺激的だった。ネタバレになるが、その緊張感が膨らんで弾け、ラストに繋がっていく。解決の過程で主人公の慎重さにも変化が出たようで、もし続刊すれば2巻からはまた違った一面が見られるのではないかとかなり楽しみになった。

とにかくかなり良かった。続刊することを願っている、とツイートすると、ふぁぼん氏にすでに決定していることを教えてもらった。感謝。この作者の作品は、先月も「英雄と魔女の転生ラブコメ」を読んだことを覚えている。帯を見て「灰原くんの~」を知り購入を決めた、という経緯があった。そちらも続刊が決定しているらしい。

また別のラノベを開こうとしたが、今読んだものが面白すぎて別のものに手が出ない状態にある。逆行転生モノが読みたい気がしたので、なろうで調べて1作読み始めてみた。半分くらい読み進めて、午前9時半に就寝。

12/10(金)

午後7時半起床。サークルを毎週欠席しており、申し訳なさがある。

実は昨日DMが来て、土曜日の午後に遊ぶ予定を入れたのだが、生協の弁当配達を完全に忘れていた。メールで連絡すれば配達日をずらしてもらえるようなので、月曜日の同じ時間帯をお願いしておいた。

夜はずっと日記を書いていた。本の感想をどう書いたものかわからず、そこでタイプする手が止まりがち。ちょっと読み返してみたり、集中を切らしてTLを眺めてみたりしてただただ時間ばかりが過ぎていった。多分、書評というジャンルの文章をほとんど読んだことがないのが原因ではないだろうか。

読んだ後に自分の中でその本を読んだことによる気分の変化があって、これが正の方向に大きいものを面白いと評価している。また、途中で下に振れたりしていた場合なども、終わりとのギャップがあって印象に残りやすい気がする。それを何とか書き残そうとして、気分の変化の原因を探っているつもりだが、どうしてもキャラ設定や世界観、文章力などの表面的なことにしか目がいかない。ラノベで「著者が読者に伝えたいこと」などの信念が表現されているとは思っていなかったが、そうでもないようで、しかし自分で読み取れているとは思えない。書評ブログをちょっと覗くと、1冊の本で1つの記事を作るくらい感想を書いているので、そこまでではなくとも参考にしたいが……。

今年、これまで5回開催されたCGRによるポイントの集計がCFに投稿されていた。自分は今28位にいるらしい。思ったより高くて震えている。20位以内だとパーカーがもらえるらしいが、さすがに遠いか。

Codeforces Global Rounds 2021: Current Results (GR13-GR17) - Codeforces

なろうを1作読了。「転生リベンジ芸能人ライフ~不遇だったアイドルオタクな青年、謎の死を遂げた推しアイドル少女の命を救うため、二度目の人生で芸能界へ飛び込む~」。昨日読み始めた逆行転生もので、完結済みという設定だったが、実際は章の変わり目で投稿が途切れているだけだった。

https://ncode.syosetu.com/n5160gu/

同じ作者の作品は他にも読んだことがある。そちらも逆行転生モノで、結構面白かった記憶があるのでこちらも楽しみにしていたが、あまり面白くなかった。題材の違いを除けば、どちらも逆行転生して幼少期に訓練を積んだ結果チートスペックを手にし、無双する話であるとまとめられる。よってこの読後感の違いは題材の違いによるものであると考えられる。アイドル活動はもうちょっと真面目にやってほしい、と自分が無意識的に考えていたのだろうか。サッカーものはほとんど読んだことがないが、アイドルものは結構読むので、その違いかもしれない。また、文章中にありえないくらいの誤字・脱字があるのはどちらも変わりないが、ストーリーにあまり集中できなかった結果そちらが目に付いて、さらに悪印象を強める結果となった。

素人おっさん、転生サッカーライフを満喫する 逆行転生にハマってた時に見つけた作品。 https://ncode.syosetu.com/n5399el/

おすすめのなろう小説まとめ - kotatsugameの日記

FHC Tシャツの連絡メールがまた迷惑メールに振り分けられていた。文面の「this link」にリンクが貼られていないように見えてどうしたものかと思ったが、迷惑メール扱いを解除するとリンクが見えるようになった。確かに、迷惑メールにあるリンクは問答無用で無効化するのは対処として正しい。以前Mサイズで注文したTシャツは裾が長すぎた記憶があるので、今年はSサイズで注文した。

キッチンの換気扇をつけると、エアコンからポコポコと水音がし出した。以前にも同様の現象が発生して、その時調べた限りでは、部屋の気圧が外に比べて下がった結果エアコンの排水ダクトから空気が逆流してきているという話だった。実際部屋の窓を開けて気圧を同じにすると水音が止むので、原因として正しいだろう。また、換気扇をつけて部屋の気圧が下がるということは、部屋への空気の引き込みがうまくいっていないとも推測できる。そこで、目につく換気扇のフィルターとエアコンのフィルターを掃除した。ありえない量の埃が溜まっていてほぼ完全に詰まっていたのを頑張って掃除すると、なんと部屋からの「排気」が正常化されたらしく、今度はキッチンの換気扇を止めた状態でもひどい水音が鳴るようになってしまった。仕方がないので部屋の窓を開けて眠ることにした。

外気温と等しい室温の中、布団にくるまってしばらく本を読んでいた。明日は遊ぶ予定があるので、午前7時半就寝。

12/11(土曜日)

正午、起床。あまりにも眠い。

昨日洗って干しておいたエアコンフィルターを戻しておく(換気扇のフィルターはティッシュで拭いて昨日すぐ戻した)。相変わらず窓を閉めるとポコポコ音がうるさいが、水が部屋に逆流してくるとまではさすがにならないだろうと信じ、その状態で放置して出かけることにした。

お互い待ち合わせに遅刻しているようだったので、のんきに神社に参拝などしていたら、先に集合場所にたどり着かれてしまった。今日遊ぶもう1人の家に行って家主と合流し、昼食を摂ってから家に戻って、夜までボドゲ三昧だった。今日プレイしたのはドミニオンとスプレンダー。僕がゼミ後にドミニオンなどのボドゲをやっているという話を聞いて今日誘ってくれたらしいが、実際のところはまだ1戦しかしたことがなかった。

まずドミニオン。何回やったか覚えていないが、ほぼずっと最下位だった。前回プレイ時に以下のような感想を抱いたので、今日はどのタイミングから勝利点を集めようか考えていたが、全然間に合っていなかった。慣れている人たちとプレイすると展開が速い。デッキを作るというよりデッキを削るのが上手くて、例えば序盤から「礼拝堂」という手札を4枚まで廃棄可能な(つまりデッキを削る)カードを何回も打っているなあと思っていたら、終盤になっても山札が薄くて強力なカードを何度も使っていたということがあった。

デッキを作るのに夢中になっていた結果勝利点をほとんど確保できず、最下位となってしまった。

週記(2021/10/25-2021/10/31) - kotatsugameの日記

また、そのようなデッキを削るカードがない場合には山札を回すことが必要になるが、これに関してもいろいろ参考になることがあった。前回のプレイでは「市場」なる+1ドロー+1アクション+1購入+1金という能力が多いカードが強いと思っていたのだが、これはどちらかというと中途半端になってしまいがちなもの。+1ドロー+1アクションはすなわち「手札を減らさず権利も消費しない」というだけの意味で、結局のところノーコストで+1購入+1金という意味だったとわかる。このカードを使った回で一緒に使われた「研究所」、+2ドロー+1アクションのほうがよほど自由度が高そうに見えたし、それで金貨など引き当てれば市場に勝る効果となる。+1購入を使いたいような機会は、少なくとも今日はなかった。手札の枚数といえば、「地下貯蔵庫」というカードで残りの手札を引き直しつつ+1アクションができるので、デッキを回すのに大変良いカードだと思っていたが、これも思ったより強くない。なぜなら、使った「地下貯蔵庫」の分だけ手札が減ってしまうからだ。

スプレンダー。毎ターンチップを集めてカードを購入し、そのカードとチップを合わせてさらに上のグレードのカードを購入していき、点数を集めるというゲーム。集めたカードの枚数によって貴族タイルというまた別の点数が取得できる。1戦だけプレイして、ビギナーズラックか僕が勝利した。序盤だけチップを集め、残りのターンはずっとレベルが低いカードをカードで購入するというのを繰り返していたら、最終的にレベル1が14枚、レベル2が4枚集まって、貴族タイルをすべて取得できて勝利した。聞くところによると、普通はもっと早く決着がつくゲームらしいので、この戦略とも呼べないような貪欲法は使い物にならなそう。

午後8時を過ぎ、みんなで夕食を食べに行くかという話になったが、午後9時からのABCに間に合うか不安だったし、食欲もないので、自分だけ先に帰ることにした。寝不足からかかなり頭が痛く、フラフラしつつ帰宅。

家に帰ってみると、今朝はあんなにうるさかった水音が静かになっていた。昨日掃除しなかった換気口を見つけ、フィルターを取り外してみると、こちらも目詰まりしていたので洗った。乾かすのは間に合わなかったので、換気口が開いてまた外気温と一致してしまった室温の中、寒さと眠気に耐えながらABCに出た。全完21位。

Panasonic Programming Contest 2021(AtCoder Beginner Contest 231) - AtCoder

Aはdcで6B。BはRuby。CもRubyで書こうとしたらWAで、「以上」という文言を見落としていたので、C++に切り替えて二分探索で解いた。Dは同じ情報が2度以上与えられないという条件を読み飛ばし、その辺りもケアしようと思って丁寧に書いている途中で気づいた。その名残で、ループ判定はdfsで行った。Eは桁dpをしたが1WA。このあたりが眠気のピークで、全然頭が働かず修正に10分くらいかかった。よくわからないまま式をちょっと書き直したら上手くいった。FはBIT。Gは積をcombinationの場合の数と読み替えるテクで、Cookie Distributionの解説を見ながら解いた。

atcoder.jp

Hが解けず、しばらくコードゴルフをしていた。一段落ついて戻ってくると何となくわかった。フローだという予想はついていたが、その辺の張り方について。すでに使ったことのある頂点を通るのにペナルティを与え、流量を変化させてみれば、最小値が求まりそう。ペナルティについては、最初は流量1・コスト0の辺で頂点とsource・sinkを結ぶが、以降は流量無限・コストINFの辺で結んでおけばよい。流す流量をkとしたとき、k\ge H,Wが必要で、理想的にはコストINFの辺を通るのは2k-H-W回となる。つまりその分を総コストから引いてみて、まだINFが残るようなら、ちゃんとすべての頂点を使えていないので、流量が足りないということ。またそれを気にせずとも、INFより大きな値が答えとなることはない。流量を変化させるのにはACLのslopeを使った。

コンテスト後に換気口から外していたフィルターを戻し、エアコンを付けたところ、一気に部屋が温まった。どうやら昨日エアコンのフィルターも掃除したのがかなり効いたらしい。最近エアコンをつけても部屋が温まらなくて、寒さに耐えられず設定温度を23度に上げていたが、今はあまりに暑いのでいくらか下げることにした。これまでどれだけ無駄な電気を使ってきたのだろうと後悔。

コードゴルフ。Aはbcに4Bがあった。bcを使うという発想を自分から出せたためしがなく、コンテスト直後に最短コードを確認して口から魂が抜けるような思いをした。Bは同様の問題が既出なのでそこから最短コードをコピペしたが、そちらごと更新された。この問題はAWKの解が28Bであったことだけ覚えていたので、手元にあるAWKの最短コードリストから28Bのもの18件を抜き出し、コードを読んでどの問題か探していた。

atcoder.jp

CはOctaveのlookup関数が超強力である。DはUFで、PerlのUFには最近手も足も出ない。大敗。Eは解説を読んでRuby再帰関数を書き、Vimに直していたが、直接N\times 2次元のdpをするコードに負けた。Fはコードゴルフの途中経過では全然勝てなかったが、最後の最後に隙をついた自明な更新で掠め取った。GはRubyで書いていたら式変形で縮められたので、Vimに直して縮め返した。HはPythonとnetworkx。公式解説でもslopeで流量を全探索していたが、僕の解法の強化版が最短コードになっていて、そちらはsourceとsinkをコスト2×INFで結ぶことで、その辺を使うのが実質流量を1減らしていることになり、流量maxの場合が即座に解となるようにされていた。

朝方までコードゴルフをしていて、眠気も微妙な具合になってきた。布団に入るちょっと前にFHC finalのYesNoが行われていて、見ているとへのk氏が4位になっていた。すごすぎる。

布団に入って読書。1冊読了。「江戸の花魁と入れ替わったので、花街の頂点を目指してみる」2巻。そこそこ面白かった。1巻を読んだときにも書いたが、現代の医療知識のまま江戸時代に転移した(憑依ではない!僕ももはや覚えていなかったが、1巻で体ごと持ってきたという描写があったようだ)ので、有り合わせのもので医療行為を行う描写がある。1巻では種痘を行っていたが、2巻では梅毒を治していた。真似しないでください、の注意書きが1巻よりも強い表現になっていた。とまあ、知識は現代のものだが、登場人物のセリフはすべて時代がかった口調になっている。物の名前や慣用句等も合わせられていて、注釈が結構多い。そのあたりしっかりしているなあと読んでいたのだが、一方江戸時代に西洋の料理や現代の髪型を持ち込んで高く評価されるという描写があって、そんなに容易く受け入れられるものか?と疑問に思った。

午前8時就寝。

12/12(日)

目覚ましを何度もスヌーズしつつ、午後4時ちょっと前に起床。すぐさまAHC007。登録時の質問で、インターン生が役職員に含まれるのかよくわからなかったが、TLでの助言を受けて含まれることにしておいた。今日は手も足も出なかったので、ちょうど1時間で切り上げてOpenCupに移動した。

THIRD PROGRAMMING CONTEST 2021 (AtCoder Heuristic Contest 007) - AtCoder

まず通常のMSTを求め、その辺のみを使うので12599577888点。入力の1行目にN Mがあると思い込んで、その部分を読み飛ばす実装をしていたため、なぜかずっと答えが合わずに苦労していた。もう何も思いつかなかったのでシャワーを浴びていると、毎回明らかになった辺の情報と残りの辺の長さの期待値(距離の2倍)でMSTを再計算し、そのMSTに採用されていたら採用という手法を思いついた。これで13885749353点となり、最終結果は245位だった。パフォーマンス1630でレートは2026→2034(+8)。

OpenCup後にいくつか解法を探してみた感じ、長さの期待値を正確な値である距離の2倍ではなくもう少し小さくしてみるとか、そもそも実際にランダムに長さを生成して何回か試してみるとか、そういう方法があったらしい。ランダムに生成するときも、ピッタリ1倍から3倍にするのではなく、もう少し区間を縮めたほうがスコアが良くなったようだ。また、「MSTを作って採用されたら採用」ではなく、「採用したMSTのほうが採用しなかったMSTより安い場合採用」とすると、ほんの少しだけスコアが伸びたようでびっくり。実際に書いてみると再現し、13917323561点になった。同値だと思っていたが、おそらく辺のソート順で前者のほうが採用されやすく、このような違いが生じたのだろう。

コードゴルフ的には、1を1995個以上出力してもよいことには気づいていたが、AWKsedでもインタラクティブが動くというのが想定外で大敗。

OpenCup。今日は5時間フルで参加できた。チームメイトの1人はAHCに参加していたため、最初は2人だった。チームとしてはAMCDJHIGEをこの順に解いて9完13位と、過去最高の順位を記録した。ほぼすべての問題に原神?というゲームが絡められていて、Paimonなるキャラクター等が登場するのはいいのだが、問題ページに特に関係ない画像(しかも一部は公式ではなくPixivから)が貼り付けられており、それのせいで問題文の読み込みが遅くてイライラした。

Aは地域のコンテストで出た問題の変形らしく、注意して読んでいたが、実際はほとんど関りがなくてただ問題文が長いだけだった。正方形を4つに区切り、どの領域に目的の点があるかで寄せる角を変えればよいとすぐにわかり、4通りのコードをコピペを駆使して生成しAC。いくつか問題を読んでいるとMが通されだしたので、読む。整理すると符号を割り振るだけになる、よく見る問題。n=1のコーナーケースにハマって1WA。次にCが通されていて、読んでもよくわからなかったのでチームメイトに投げるとシュッと通してくれた。

D問題を読んでみると、つい最近見たことのあるソート関数が取り上げられていた。ビジュアライズ結果も見た記憶があるので、しばらくTwitter検索でツイートを掘り出していた。

改めてアルゴリズムを把握すると、i=1の場合の交換とそれ以降の交換に分ければ求められそう。前者はシミュレートで、後者はほぼ転倒数になるため、インクリメンタルに更新できる。勢い勇んで書くもサンプルが合わない。もう少し考えると、値が重複する場合に困っていることが分かった。重複を部分的に取り除く必要があるが、これは後々削除される要素の寄与分を持って一緒に更新していけば後から無理して求めなくてもよい。チョイチョイ直してサンプルが合った。怖いのでランダムケース生成してチェッカーに掛けると、ボロボロ落ちるケースが見つかったが、幸い修正は容易で、値の分布を変えたランダムケースでも落ちなくなったので、満を持して提出しAC。これが全体で2番目のACで、かなり興奮した。

Dが通るのとほぼ同じくらいにJが解けたらしいので、実装に入ってもらって次に通されているHを考えていた。これは木dpをするだけに見える。しっかり遷移を詰めて、Jが通ったのを確認して実装に入る。1度WAするもtypoが見つかったので修正し、もう一度投げると通った。アルゴリズムの間違いではなくて一安心。その後Iもできたらしくて、通っていた。

Eを考えてわかった気になり、実装に突入。しかし2次元セグメント木が必要になって暗雲が漂う。このあたりでAHCからチームメイトが帰ってきて、1点加算矩形取得のデータ構造を持っていないか聞くと、シュッと投げてくれる。それをコピペしていざ具体的な値を求める段になり、ようやく解法の破綻に気づいた。しばらく考えても修正不可能で、そうしているうちにGが解けたらしいので、いったんパソコンを空ける。頭を抱えていると、先ほどデータ構造を恵んでくれたチームメイトがまったく別の解法を生やしてくれた。Gが通るのを待って実装してもらい、提出するもTLE。行列積が重いところ、三角行列であることや成分のいくつかが常に1であることを利用して展開すると、演算回数がかなり減ったらしく、それで通った。後から公式解説をチラ見したところ、行列の形に注目して行列積を軽量化するところまで含めて想定解だったらしい。

OpenCupから戻ってくると、今日の昼間に行われていたJOIの二次予選の問題がAtCoderに上がっていたので、急いで解いた。

JOI 2021/2022 二次予選 過去問 - AtCoder

Aは簡単。AWKの25Bを投げると、時間差ですでに投げられていた。その後Vimsedで頑張ってみたが、どれもTLEしてしまった。特にsedのホールドスペースをスタックのように使うやり方は、かなり上手いと思ったのに、小さいケースでも思いっきりTLEしてしまった。以降はコードゴルフなし。BはBFS。Cは難しかったが、縦の和・横の和が一致するというだけでもパターンは相当絞られるので、約数全列挙などした後全探索する。Dは直前に食べた飴の位置を覚えておいて、2個連続で食べたようなら遷移先を十分遠くに飛ばしておけばよい。EはTLで少し言及を見てしまって、Undo可能UFで殴り倒した。1250msくらいかかった。

CF #759 div.2があるようだったので出た。5分こどふぉるのが2連続で行われた。

Dashboard - Codeforces Round #759 (Div. 2, based on Technocup 2022 Elimination Round 3) - Codeforces

Aは丁寧にやる。Bはちょっと考えると、後ろからの累積maxが更新される回数だとわかる。Cは正負に分けて考えてよい。Dはしばらく1,2,4,3をソートできると思って手で実験していたが、ふと転倒数のパリティが変わらないことに気づいた。かなり見覚えがある考察だ。同じ値が2つ以上存在するなら、そこを入れ替えることでパリティを変化させられるため、必ず達成可能。Eはdfsして親へのパスに含まれる値の頻度テーブルを作り、その上で二分探索して、値の取得はsetで行った。頻度テーブルは数値のインクリメントとデクリメントで行えたが、最初の提出ではここにもsetを用いていたので、1TLE。Fはdpを考えると区間ごとに値が一定で、座圧した後遅延セグメント木に一次関数の作用をさせた。

システスも通って全完10位。上位10人中8人が日本人だった。Eは106にlogを付けたので心配していたが、TL 4000msのところを3200msくらいで通った。結局、削除のためにsetを使っていたので、そこをうまくやると線形時間の解法が作れるらしい。解法の一部に見覚えがあるなと思って日記を検索したところ、半年ほど前に見たことがあったらしいと発覚。

vectorの途中の要素が、一番後ろの要素とswapしてからpop_backすることで削除できるという話を聞いた。言われてみれば当たり前だが、かなり盲点。

週記(2021/05/03-2021/05/09) - kotatsugameの日記

FはARCで既出だったらしい。当時の自分はちゃんとstackを使って線形時間で解いていた。

atcoder.jp

終わってからずっと日記を書いていた。火曜日にはととりにゃあアドベントカレンダーの記事を錬成しなければならない。実は、今年読んだ本ではなく去年読んだ本を書こうかと迷っている。去年同様の記事を書けなかった理由を思い出したからだ。12月にそのような記事を書くと、当然12月に読んだ本が記憶に新しすぎるため、正しく判定できないのではないかという恐れがある。しかし読んだ本の統計を取ろうとも考えていて、その場合今年の本を対象にするのが望ましい。どちらにするのか、書き始めてみなければなんとも言えないだろう。