週記(2020/10/05-2020/10/11)

10/05(月)

起きたら午後3時だった。昼前に一瞬意識を取り戻してツイッターを確認した覚えがあるが、二度寝に成功したらしい。

昨日のこどふぉのEのhackケースがTLに流れてきた。昨日のツイートだが、誰かのいいねで再度表示されていた。

同じ文字のペアを消すか消さないかは、以前の文字列によって決まる。消すことで後ろからより文字コードの大きい文字が出てくるなら消すべきでないし、逆にそうでないなら消すべきだ。では、後ろにある文字が同じであった場合はどうなるだろうか?

コンテスト中の僕は、この場合一律で消さないべきだと考えていた。消すべきだったら、そもそも後ろに同じ文字があるので、今見ているペアの片方とくっついて消えているはずだという理屈。これは嘘で、実際には"bbzzb"みたいに「消えた結果後ろに同じ文字が現れる」場合が存在する。さらに"bbzzba"だと消したほうが'a'が前に出てきてお得。

これは、後ろから見て「最後に隣り合う文字が異なった個所の文字コードの大小」を持って、それに応じて後ろにある文字が同じ時の処置を決定するようにすれば対応できる。

昨日は放置すると言っていたくせに、ちゃんと解きなおししてしまった。

学食に行って550円の弁当を買うと、レジの人が500円の弁当として会計してしまった。これはレジの人の責任なので500円分の支払いでよいらしい。ちょっとモヤっとするが、プリペイドカードなのでそうやすやすと巻き戻せるわけではなさそうでどうしようもない。

帰ってきてmodintを完成させた。invをどう計算するのか悩んだ。拡張ユークリッドの互除法が速いと思っていたのだが、ACLの実装ではmod素数の場合はpow(mod-2)している。これはどうしたことだろうか。

実際に試してみると、拡張ユークリッドの互除法int型で計算するのはpow(mod-2)よりほんの少し速いが、long long型で計算すると大幅に遅くなった。まあ試すといっても、簡単なコンビネーションの計算をする問題に提出しただけなので、詳しいことはわからない。

pow関数の引数に負の数を与えたときはpow(-n).inv()を返すようにした。素数modならpow(n%(mod-1)*(mod-2)%(mod-1))でもいいのかもしれない。大体非素数modで変なことをするなよ、という話だ。まあ使う機会があるとはあんまり思えないし、こればっかりは慣らしてから考えるべき問題だと思う。途中invpow(mod-2)で実装しているときにpow(-1)を呼んだら無限再帰になってびっくりした。

modintを作ったので、ほかのデータ構造のverifyコードを手直しした。返すmodintを新たに作っていると遅いが、そもそも引数が値渡しなのでそれを書き換える形にしたら速くなった。

次に行列ライブラリを作ろうと思ったのだが、設計に悩んでいる。次元をテンプレート引数で与えるものと、コンストラクタで動的に定めるもの、どちらが良いだろうか。少なくとも正方行列のライブラリについては、例えば2行2列行列をvector<vector<int> >で持つのはぞっとしない話だから、テンプレート引数で与えたい。一方で動的に定めたい問題もいくつか思い浮かぶ。

beetさんやei1333さんのライブラリを参考にすれば、正方行列はテンプレート引数で、普通の行列は動的に定めているらしい。動的な正方行列が欲しくなったら普通の行列のライブラリを使うのだろうか?N行M列行列の構造体にしれっとpow関数が実装されていても、使う側が気を付ければ問題ないか。

明日は講義とその演習がある。演習のほうは直前まで情報が出ていないように見えたのだが、日付が変わったあたりで再度ポータルサイトを確認すると出ていた。ISTUらしい。

ほかの講義はみーんなGoogle classroomで資料を掲載するのに、1つだけISTUでやられると煩雑で困る……と思いながらしぶしぶISTUを確認したら、classroomの授業コードが貼ってあった。OK!

しかし全てclassroomで完結させるのではなく、資料を掲載するのはclassroomだが、レポート提出はISTUで行うという使い分けをするらしい。まあ許せないこともないが、先の学期を思い出してみると、classroomで課題を出すとISTUで提出するので期限までToDoリストに残り続けることになるし、出さなければ気づけないしで困ったものだ。

10/06(火)

起きたら午後4時だった。今日は2限に対面の授業があったけれど、消し飛ばした。

学食に行く。夕方は大学近くの道が死ぬほど混むので、自転車で行く。チェーンがミシミシ言っていて非常に怖い。坂を上るときに強い負荷がかかっていて壊れそう。

帰ってきてから夜までずっとハーメルンを読んでいた。先週月曜日から読んでいた作品が読み終わった。

syosetu.org

532話、3,766,229文字。ここ1週間はこれにかかりきりになって全ての予定が崩壊していたが、それだけの価値がある作品。かなり長いが、マジで面白い。ヴォルデモートの最期の場面までは必見。逆にそこのクライマックスが本当に良すぎて(僕は泣いた)、原作終わりからの新しい話の印象がちょっと薄い。

本当はもっといろいろ書くつもりだったんだけど、書きたいことが多すぎてなんともならなかった。

しばらくAtCoderをしていた。ACLが過去問でも使用可能になったらしい。

布団に寝転んで、別のハーメルンをしばらく読んでいたら、急に耐え難い眠気が来た。まだシャワーを浴びていないし、洗濯物もたまっているし、何ならこの日記も書いていなかったが、気にせず寝てしまうことにする。とりあえず歯磨きして顔を洗ったら少し目が覚めたので、またしばらくハーメルンを読んで、今度こそ寝た。この日の日記は水曜日に書いた。

10/07(水)

昼頃起きて、しばらくハーメルンを読んでいた。

syosetu.org

昨日の夜中から読み始めた作品は24話なのですぐに読み終わる。とはいえ文字数を見ると204,065文字、これは文庫本1.5~2冊に相当するはずだ。かかった時間はそれに比べれば短いはずだし、やっぱりネット小説は適当に読みがちなんだな。内容は……正直合わなかった。

昨日消し飛ばした対面授業は、資料がclassroomにアップロードされていた。「出席できない人はこれを見て勉強してください」とも書かれていた。最高。もう一生出席しません。

1週間ずっとGame of Vampireを読んでいたわけだが、その間にいくつか新しい作品を見聞きして、タブに保存していた。余裕ができたので読もうと思ったのだが、どうにもそれほど面白くない。上で挙げた作品はジャンルが僕の好みに合っていたから読了できたが、それ以外は非常に厳しい。実際に3つくらい、最初の数話を読んで辞めてしまった。どうやら無意識的にGame of Vampireと比較しているらしい。

この機会に「本好きの下剋上」に手を出すことにした。とりあえず学食に行き、帰ってきてから読み始める。

序盤、まだ成り上がりのきっかけをつかんでいないあたりは非常に辛い。周囲の人からオススメされたことと、高い評価を得ていることを頼りに読み進める。

真夜中からTCOのwildcard roundがあったので、出た。finalに行けるとは全く思っていないが、まあRatedなので出ておくか、といった気持ち。

Easyのみの1完、しかも遅解きだった。どうしようもない。Easyの解法は見た瞬間わかってしかるべきだったのに、しばらく全く別のところをウロウロしていた。Medもよくわからずに立式したらサンプルが一生合わなくて終わってしまった。

まあEasy落ちが結構いたので、僕のコードが落ちなかったことだけはよかった。2246->2222(-24)。ゾロ目である。Rubikunさんが三桁マイナスで一瞬で黄色落ちしていてビビった。

yukicoderをする。ちょっとサボっていた間に有志のコンテストの問題がドバーッと追加されていたので、チマチマ埋める。星2.5以下の問題を再度埋め終わって、現在990AC。あとちょっとで大台に乗りそう。AOJも確かあと30問くらいで1000ACだったはず。Codeforcesは……ナオキです

10/08(木)

起きたら午後3時だった。夜の部が始まる午後4時をめがけて学食に行く。早めに行くと、食べ終わった後も余裕をもって購買で買い物ができる。

サークルからICPCに参加するメンバー全員が、ICPCのアカウント登録まで済ませてくれた。チーム名も決まっているので、メアドと一緒にファイルにまとめてコーチに送る。チームが登録されるのを待って、サークルの人々に情報の追加をしてもらう必要がある。英語のUIなので非常に分かりにくく、一番の難所だと思っている。例年通りならば活動の日に集まってみんなで確認しつつ登録していたが、今年は集まれないので、スクショを共有して参考にしてもらいながらやっていこうと思う。

明日の2限はclassroomに講義資料と動画が数本アップロードされるタイプだが、小テストがあって、授業終了30分後までに提出する必要があるらしい。その時間制限は何?

前日、つまり今日の夜に講義資料がアップロードされたので、とりあえず解いておいた。「授業時間内に動画を視聴し云々」と書いてあるが、本当に意味不明な制約なので、無視して提出した。一応コメントでこれが許されるか確認を取っているが、返信はまだ返ってきていない。

先日作ったmodintについて。2*modintが動かなかった。operatorの定義が問題のようだ。operator+=の実装を用いてoperator+を実装している。

(1) modint operator+(const modint&a){return modint(*this)+=a;}
(2) friend modint operator+(const modint&a,const modint&b){return modint(a)+=b;}
(3) friend modint operator+(modint a,const modint&b){return a+=b;}

(1)は、左オペランドintなどで右オペランドmodintのときに動かない。よって(2)や(3)みたいにfriendで書いておいて、intからコンストラクタ経由で呼び出せるようにしておけばよい。

operator+=を使用する都合上、左オペランドはコピーを取る必要がある。ACLの実装は(2)だが、(3)のほうがシンプルではないか?速度面で違いはあるのだろうか。(2)についている参照渡しのconstは、(3)では値渡しなのだから同様に満たされるはずだと思っている。しかし実測をしていないため確たることは何も言えない。

ライブラリのフォルダ構成を変えることにした。ライブラリをジャンルで大まかに分けた結果、oj-bundleで展開するときにいちいち#include"math/modint.cpp"と書かなければならなくなっていた。これを解消する。

includeフォルダを作って、ここに.hppファイルをずらっと並べることにした。ただしそれぞれのファイルは別のところにあるファイルをincludeするだけにしておく。例えば、include/modint.hppの中身は../math/modint.cppincludeするだけ、のように。

oj-bundleがファイルを探すパスをincludeフォルダ内にしておけば、modint.hppincludeするだけでmath/modint.cppが展開される一方、ライブラリ本体はちゃんとフォルダでジャンル分けされたままになるという寸法だ。

同時にverify用のコードも書き換える。これまではverify用のコードがあるフォルダから../math/modint.cppみたいにしてincludeしていた。これはいかにも融通が利かない。ちょっと場所を移しただけですぐにCEになること請け合いだ。

こちらもmodint.hppincludeするだけにしたい。oj-verifyconfigファイルをいじって、コンパイルオプションに-I library/includeを渡すようにした。結構紆余曲折あったのだが、最終的にはうまくいってよかった。

デフォルトでは-Wallをつけてコンパイルされたり、clang++も同時にテストされたりする。大体Github Actionsで動かしているのに警告出してもどうしようもないし、clang++は使わないのでテストする必要がない。この2点は前から気になっていたが、configファイルを設定することで両方解決した。最高。

フォルダ構成を大幅にいじって満足したが、実際のところライブラリは1Byteも増えていないのである。

10/09(金)

昨日のmodintoperator+の話について、日記を書いた後に適当に計測した。modint+intの場合は(2)より(3)のほうがほんの少しだけ速く、modint+modintの場合は(2)と(3)はほとんど同じくらいの速さだった。ここまではよい。

int+modintの場合は、(3)よりも(2)のほうが結構速かった。理由が全然わからない。intのほうはmodintのコンストラクタに渡されるが、(3)ではそこで作成したmodintの、さらにコピーを取っている。これは確かに遅そうだ。const modint&を引数に取っておくと、最適化がかかってくれるのだろうか?

理由はよくわからないが、実際速いのだから(3)に戻して、寝たのだった。

午後3時くらいに起きる。学食に行ったのだが、スマホを忘れてしまい、食事の写真が撮れなかった。同じことをずっと繰り返すことにこだわりがあるので、失敗したのは痛い。

yukicoderをチマチマ埋める。今日もコンテストがあるが、その前に1000ACしようとしていた。999ACなのを確認して1問解いたところなぜか1001ACになっていてよくわからないが、ともかく1000ACは達成できた。やっぱり星の数ではなくsolvedの降順に解くと楽。

サークルのメンバーの1人から、ICPCに関するアレコレについて質問があった。練習についてはAOJ-ICPCのオススメの使い方を紹介した。解答の提出についても、かなりややこしいことを強調して、模擬国内予選で試してくださいと言っておいた。問題は予選で使用する環境だ。毎年碧黴さんに任せっきりでよく理解していなかった。

ライブラリがコンピュータ内のファイルに保存されているのは、これは(あまりよくないが)許容範囲内ではないかと思う。当然コンテスト中に使うのはアウトだが、パソコン内のコード断片を全部探して削除するのは難しいだろう。.vimrcコードスニペットは削除する必要がある。これを咄嗟に断言できなかったのだが、チームメイトに聞いたところ削除するとのこと。

リクルートの冬のアルバイトについて、オンライン説明会の案内が来た。自分が何をしたいかなど全然考えていないのだが、そうして尻込みし続けているのはよくないだろうということで、試しに参加することにした。今年の夏も、親にインターンに行ってもいいか聞いておきながら何も具体的な行動をしなかったので、ちょっぴり後悔している。

yukicoderに参加する。数学回とのことでちょっと身構えていたが、ふたを開けてみると全然そんなことはなかった。

F問題は橋を検出すれば解けるが、グラフがなもりグラフなので、単純なdfsでもよいらしい。LowLinkは単純なdfsではない。

僕の橋検出ライブラリはグラフが非連結のときにバグる(というか1つの連結成分しか見てくれない)というのは以前にも書いたかもしれない。今回はなもりグラフなのでOKだった。

「N頂点N辺の無向連結グラフ」をなもりグラフと呼ぶの、かなり好き。

しばらくAtCoderをしていた。AOJも1000ACを目指して解き始める。何を埋めようか迷った結果、PCKの過去問を埋めることにした。去年古いものから順番にいくらか埋めていたのの続きで、微妙に穴が開いていたのをふさいでいくことにする。去年飛ばしただけあって難読・面倒のオンパレード。3つ解いたところで寝ることにした。

10/10(土)

起きたら午後1時だった。ちょうどKUPCが始まる時間に目覚ましをかけていた。12時と12時半の目覚ましは黙殺してしまったようだ。

慌てて起きて眼鏡を掛け、パソコンのスリープを解除してA問題を開き、ACするまで2分半だった。

コンテストの結果は5完だった。これはひどい。F問題は制約を読み落としていた。G問題は、かなりいいところまでわかっていたが、末尾に同じ数をくっつける場合の数を最後に計算する方法がわからなかった。それ以外の操作i回と混ぜて並べたときに、どの時点で同じ数をくっつける操作をしてもその場合の数は1通りに定まるので、comb(N,i)みたいな係数でよかった。

次にHHKBコンテストに出た。全完7位。誰が学生か詳しくはわからないが、たぶん学生3位か4位だと思う。3位だったらキーボードがもらえる。4位は虚無がもらえる。

F問題はかなり難しかった。連続的なやつの期待値は積分で求めるのが常道で、それをする。各[L,R]について、x/(R-L)*(min(R',x)-min(L',x))/(R'-L')*...みたいな式をLからRまで積分すると、寄与する期待値が出てくる。

出力する数値の要請から、分母は計算しなくてよい。

minが出てきてかなり困るので、全てのLRを混ぜて降順に見て計算することにする。L'>=xのときR'>xなのでmin(R',x)-min(L',x)=0。よってLが出現したら計算を打ち切ってよい。そうでない場合、R'<xならばR'-L'になるので別に係数を持っておけば考えなくてよく、R'>=xならばx-L'被積分関数にかかる。

[L_1,R_1]から[L_N,R_N]まで全部同時に計算することにする。被積分関数が対応する多項式の和になっていればよい。これまで出現した(x-L')*...を別に(other(x)とする)持っておいて、新しく[L,R]を考えるときには、now(x) <- now(x)*(x-L)+other(x)*xとする。これで自分([L,R])以外の(x-L')の積×xの総和が得られる。そのあと、other(x) <- other(x)*(x-L)とする。

多項式積分は簡単。毎回powするのではなく、累積積を持っておくのが速いだろう。まだ出現していない[L,R]に対応する係数を掛けるのを忘れずに。

この事実を利用する方法もあるらしいが、全くわかっていない。

最大値と最小値の分布(一般論と例) | 高校数学の美しい物語

次はこどふぉ。CGR11があるが、その前にtesting roundがあったので、なんとなく出る。10分のテストコンテストで、問題数は2問。1位の人は10分で2問解いたうえで2Hackしていてかなりビビった。A問題で結構落ちているようだ。場合分けでごり押した結果落ちているコードを見つけたが、あんまり読む気にならなかった。

今度こそCGR11。1時間で4完したあと、Eに2時間ぶち込んで解けなかった。椅子に突き刺さって寝たりシャワーを浴びたりしていたのだが、最後の最後でそれっぽい解法が思い浮かんだので実装していた。結局3分くらい間に合わなかったのだが、後から提出したら通った。本来なら悔しがるべきところだが、あんまり現実感がないので特になんとも思っていない。

Nに対して(N^2N)+N^3N^Nはだいたい2になる。2進表現で2つ以上の0が連続する部分があると2にならないようだ。これは実験結果からエスパーしたもの。

この連続する部分をどうにかしてつぶせば2が手に入り、シフトしながら消していくと1を作れる。つぶす方法についてだが、奇数を1から順にかけて((N^2N)+N^3N^N)==2になるのを待つ方法で通った。正当性が全然わからない。

レートは2493->2487(-6)

AtCoderbcのAC数が500問になった。bcは文字列が読めないので、入力が数値と文字だけの問題を選んで解いている。あとめちゃくちゃ遅い。総じて、どう考えても競プロ向きの言語ではない。

ライブラリを書く。modintのコンストラクタは、これまで問答無用でlong longにキャストしていたが、テンプレートにした。毎回long longで剰余の計算をするのは遅そう。

行列ライブラリを書く。固定長の正方行列と、動的にサイズを決められる行列の2つ。固定長の正方行列は、例えば2 x 2行列を遅延セグメント木に乗せたり、数列を漸化式で計算したりすることを想定しているので、あまり機能は持たせない。足し算と掛け算とpowのみ。

そういえば単位行列を得るための関数はいろいろあるみたいだけど、僕はOctave由来のeyeにした。別にOctaveだけがeyeというキーワードを使っているわけではないが、僕にとってなじみ深いのはOctave

普通の行列の方はいろいろ作る。powも作っておいた。縦と横のサイズが違うときにpowするのは意味不明なので、assertも入れておく。これに限らず、行列の計算はサイズが重要なので、いろんなところにassertを入れておいた。昔は自分が書いて自分で使うライブラリにおいてassertなど無駄だと考えていたけど、改宗。

行列式の計算と、ガウスの消去法も実装した。ガウスの消去法について、対角行列ではなく上三角行列で計算を止めると定数倍に結構効くという話もあるが、ライブラリでは対角行列(というか単位行列)まで計算することにした。定数倍高速化がしたければ、その場で書き直す。あとはmodintだったら割り算のかわりにinvを求めておいて掛ける形にするだけでもかなり変わるだろう。それはそうで、log(mod)を落としているから。

ガウスの消去法のverifyとしてyosupo judgeの連立方程式を解く問題に提出したが、ライブラリ以外のところでハマった。拡大係数行列にガウスの消去法を適用して、まずランクを求め、下のほうに非零の数が残っていないか判定するのだが、そもそもこのランクにAx=bbの部分のみからなる行が含まれている場合があるのに気づかなかった。

10/11(日)

起きたら午後6時だった。えでゅふぉがあるが、確か今日が期限の課題があったはずなので見送る。

レポートを書こうと課題を確認すると、明日までだった。もうえでゅふぉが始まってからしばらく経っているので、今更出る気もないため、この課題を終わらせる。

えでゅふぉが終わったのと同じくらいの時間に書き上げた。提出して布団に入る。まだARCまで数時間あって、少し眠いが、今寝るとどう考えても起きられないので、寝ないように注意してなろうを読む。

午後9時あたりにTLを見たらARCの幻覚を見ている人たちがたくさん「ぞい」ツイートをしていて、ビビる。冷静になってなろうに戻る。

コンテスト10分前に布団を脱出し、ラムネを食べてコンテストに備える。

ARC105が始まる。結果から書くと、5完43位だった。

A問題は何も考えずにbit全探索した。結構いろいろな分け方があると思っていたけど、解説を読むと2通りしかないらしい。確かに。

B問題は実質あまりを取る操作なので操作をするたび最大値が小さくなるからシミュレーションしてもOK、と思っていたらTLEした。バカだから1度目のTLEで懲りず、ほとんど同じコードをもう一回出してもう一回TLEを食らっている。冷静になってとりあえず数列全体のgcdを取るとサンプルが合うので、未証明で投げる。AC。

C問題はNが小さいのでN!全探索を考える。N!の中で牛ゲーをしようと思ったが、今回求めたいのは最も短いときの値だから、逆。(これは符号を反転すればよかった。)

前からdpしてよさそう。今考えると、これはDAG上で牛ゲーをしているだけ。毎回M個の条件をチェックする必要があって、このままだとO(N! N^2 M)。到底間に合わない。

dfsして順に計算していけばNが一つ落ちるんじゃないの!?となって実装。O(N! N M)くらいのコードを投げるとTLEした。アホ。

尺取りみたいにしたらさらにNが消えるんじゃないの!?とO(N! M)くらいのコードを投げると、またTLEした。本当は最初に8!*10^5=~=4e9であることを計算していたので、今投げた2つのコードがTLEすることはわかりきっていたはずだ。なぜ投げてしまったのか。

冷静になると、事前にソートすると毎回判定するべき範囲が2分探索で求まり、累積maxを取っておくと範囲に対する判定が1回で完了するため、オーダーにはMではなくlog Mが出現するようになる。

CでTLEを食らっている間に順位表を確認したら、なんと4桁順位だった。ヤバい。

Dを読む。ゲーム。丹念に場合分けを行う。まずNの偶奇で先手後手両方の戦略が入れ替わる。ここで場合分け。総xorを非ゼロにするのはかなり簡単に見えるので、そちらを考える。なるべく大きな山を作るように操作すれば、めったに総xorは0にならないのでは?となる。具体的に計算すると、だいたい過半数が取れるのでよさそう。コンテスト中は適当に流したが、石全体の過半数が1つの山に集中していれば総xorが0にならないというのは微妙に非自明。

Nが奇数のとき、後手はうまくすれば必ず過半数の山を作れるので、先手が最後に石を山に追加したとき、総xorは非ゼロである。よって後手勝ち。

Nが偶数のときも同じように計算してみたところ、ぴったり半分にしかならない場合があることに気づく。さらに詳しく見ると、同じ個数の石が入った袋が偶数個ずつある場合にこのことが起き、後手勝ち。それ以外は先手勝ち。

これを実装してAC。16分で解いたらしい。

Eを読む。またゲーム。1Nが非連結の状態でどれだけ辺を増やせるか、という問題。その値の偶奇で決まる。

1を含む連結成分のサイズがLNを含む連結成分のサイズがRのとき、辺は最大でN(N-1)/2-LR個。最初からM本張られているので、N(N-1)/2-M-LRが奇数<=>先手勝ちだ。

場合分けをしていく。まずL+R==Nなので、Nが奇数のときLRは必ず偶数。よってこの場合は決まり。Nが偶数の場合を考える。

連結成分のサイズの偶奇を変更するためには、1ともNともつながっていないサイズが奇数の連結成分を加えればよい。そのような連結成分を「浮島」と呼称することにする。(僕のコンテスト中のイメージがそれだった。解法を説明するときに頻出するため、名前を付けておく。)浮島が存在しない場合は、現在のLRの偶奇が保たれるので、これも決まる。

浮島が1つしかない場合は、先手がLRのどちらか好きなほうにくっつけることで浮島がない状態に帰着できるため、先手勝ち。

では、2つ以上は?例えば浮島が2以上の偶数個あった場合、後手は先手の行動に応じてそれを打ち消すように行動できるため、最初のLRによって後手勝ちならばそれが保たれる。具体的には、先手が浮島をLまたはRにくっつけたら、必ず浮島は1つ以上残っているはずなので、それを同じところにくっつける。ほかの行動に対しては浮島どうしをくっつけて「パス」したりすればよい。

先手勝ちならば、先手は最初に浮島どうしをくっつけたあと、上の後手勝ちと同様の戦略をとればよい。以上より、浮島が2以上の偶数個あった場合は、存在しない場合と同様に最初の先手勝ち・後手勝ちが保たれる。

浮島が奇数個の場合が残っている。これは先手が最初に浮島をLRにくっつけることで、浮島が偶数個の場合に帰着できる。浮島が偶数個の場合は先手勝ち・後手勝ちが保たれるのだったから、この場合の勝ち負けは先手の最初の行動で決まる。先手はLRどちらにくっつけるかを選ぶことで、必ず先手勝ちの状態に持っていけるため、浮島が奇数個のときは先手勝ち。

以上の場合分けをコードに起こせばよい。26分でAC。

BとCで2個ずつペナを付けたときは心臓が弾け飛んだが、終わってみればパフォーマンスは2774だった。+9というしょっぱい結果だけど、冷えるよりはマシ。でもちゃんと冷静にやっていれば赤パフォが出たということで、やはり悔しくもある。

A問題のコードゴルフについて。条件はA<=B<=C<=DとしてD-C-B==(A or -A)だが、Rakuで(A,-A)X+(B,-B)X+(C,-C)X+(D,-D)を計算して0が含まれるか見てもよい。

このメタ演算子Xは、左右のリストから1つずつ選ぶ全ての場合について演算して、結果をリストで返してくれる偉いヤツ。まあそこそこ短そう。

ところで、Junctionという機能を使っても同じことができる。文にして説明しようとするとかなり厳しいことに気づいたので、リファレンスへのリンクを貼ってお茶を濁しておく。

class Junction

ともかく、Junctionに対して演算をすると、中の値それぞれに対して計算が行われる。これはXと似たようなことをやっていないか?

ということで、(A&-A)+(B&-B)+(C&-C)+(D&-D)を計算すると、A+B+C+Dから-A-B-C-Dまで16通りの計算結果がallでつながった状態のものが得られた。正確にはallがネストしているのだが、別にanyが混ざっているわけでもないので特に違いはない。

これをbool値として解釈するときは、A+B+C+D&& ... &&-A-B-C-Dが計算される。どこかの項が0になると全体がFalseになるので、これでAからDを足し引きして0が作れるかどうか判定できる。

リスト(A,B,C,D)から((A,-A),(B,-B),(C,-C),(D,-D))というリストのリストを作るのと(A&-A,B&-B,C&-C,D&-D)というJunctionのリストを作るのでは、後者のほうが短くかける。具体的には(1&-1)*AA&-Aになること、1&-1が1つの要素として解釈されることを利用して1&-1 X*(A,B,C,D)になる。(1,-1)X*(A,B,C,D)flatされてしまうので、リストのリストにはなれない。

ということで次のようなコードが書けた。

atcoder.jp

信じられないくらい美しい。

週記(2020/09/28-2020/10/04)

09/28(月)

結構早くに目が覚めて、ハーメルンを読んでいた。面白すぎて二度寝できない。結局10時頃に起床報告をした。

昼前、空腹に耐えきれなくなったので学食に行く。夏休み期間中の学食は、弁当のサイズが中しかなくて、かなり空腹の今は1個食べると足りないくせに2個だとちょっと多い、みたいな感じで辛かった。 しかしちょうどこの日から他の店舗の営業も再開して、そちらは大中小が選べるらしい。今日は知らなかったので今度から行こうと決意する。

食事をして、床屋に行って、帰ってきた。即座に布団にダイブしてハーメルンを読み続ける。

午後4時頃、読み終わった。

syosetu.org

信じられないくらい面白い。以前からずっと、上位存在・長命種が人間の発展を見守ったり導いたりする話が好きだと言っているが、これもそういった作品の1つ。しかしこの作品は現在540話あり、歴史のイベントをいくつも丁寧に描いているため、なんというか没入感がすごい。

あまりにも丁寧に描きすぎて、最初100話くらいは話が全然進んでいないように見えて「思ってたのと違う……」と感じていたが、このあたりの出来事も後々重要な役割を持つ、というかほとんど神話みたいな扱いをされるので、我慢して読んでよかった。

数日かけて一気読みしたせいで作品世界に深くとらわれてしまい、しばらく身動きが取れなかった。頻繁に身動きが取れなくなってないか?ハーメルンが面白すぎるのが悪い。

ようやっと身を起こして、サークルの事務作業をする。ICPCの関係でコーチを引き受けてくださる方とメールのやり取りをしていたが、4日くらい止めてしまっていた。サークルメンバーへのアンケートの回答待ち、という言い訳をしていたが、別に回答が出揃っていなくてもメールのやり取りはできるんだよなあ。急いでメールの返信をする。

自分が一方的にフォローしている(相手からフォローされていない)ことを片思いという。フォロバ100%という方針でアカウントを運営していると、これが結構重要になってくる。

向こうからフォローしてきたので返すと、頃合いを見計らって外されて、片思い状態にさせられてしまうことがよくある。これはフォローチャーンといって大規模アカウントを育てる常套手段だが、かなり気に食わないので見つけ次第こちらからも外す。が、そもそも見つけるのが大変。僕は専用のサービスを利用している。

twitter 片思いチェッカー|アプリ認証不要の相互フォローチェック!

ここ数か月全然やっていなかった。海外の大規模アカウントが100個くらい片思い状態になっていたので、片っ端から外す。あとはまあ、普通に僕のツイートが合わなくてリムられたアカウントをリムり返したりして、片思いの数を減らす。絵師とか有名人とか、そういったアカウントに対して片思い状態になっているのは普通なので、たいていフォロー数<フォロワー数+150くらいの状態を維持している。

フォロバ100%だからと言って「片思われ」が一切存在しないかというとそんなことはない。監視アカウントと言って、鍵アカウントでフォローするけどフォローリクエストは通さないというアカウントが数十個くらいある。あとは、そんな極端なFF比ではないのにフォローリクエストが数年保留されているアカウントもいくつかあるのだが、これはたぶん別アカに転生したんだと思う。

いろんな理由でフォローリクエストを通してくれないアカウントが存在するが、これの扱いは人によって対処が分かれがち。ブロック・ブロック解除で被フォローを外す人もいれば、放置する人もいる。僕は放置している。理由は単純で、フォロワー数が増えるとうれしいから。

ハーメルンで別の作品を読み始める。エカスドクィナさんがハリー・ポッターの二次創作おすすめをまとめていて、それから1つ。

syosetu.org

就寝報告できずに寝落ち。

09/29(火)

午前5時くらいに起きる。昨日は寝落ちしてしまったが、日付は変わっていたはずなので、5時間も寝ていないことになる。かなり眠いし二度寝するべきなのだが、いかんせんハーメルンが面白すぎる。スマホに手を伸ばし、読み始めてしまう。こうなるともう寝られない。

そのまま8時間くらい布団で読み続けていた。そろそろ学食が閉まってしまう。特に、昨日言っていた店舗は13時半に閉店である。急いで大学に向かい、食事をした。今日は味噌ラーメン大。

帰ってきて、また布団に寝っ転がってハーメルンを読み続ける。午後9時頃になって、今日絶対にしなければいけないことを済ませるために起き上がる。

まずはメールの返信。サークルでアンケートの回答を催促したところ、ちゃんと全部集まってくれた。昨日送ったメールへの返信が来ていたので、それにまた返信。1日1往復の気の長いやり取り。

あとは少しAtCoderをし、おすすめのなろう小説をまとめていた。日付が変わったあたりで、なろうの更新確認をする。

第2部が完結した。同時に作品も完結らしい。長かった……最近は頻繁に更新があったが、途中3年で3話という意味不明な更新ペースになっていて、正直完結は絶望的だと思っていた。この作者さんは結構多作かつ書籍化されたものもいくつか抱えているので、古い作品は忙しいし顧みる暇がないだろうな……と想像していた。

しかし終わり方はあんまり納得できない……戦闘シーンに突入する瞬間がラストシーンって典型的な打ち切りのイメージがあるぞ。と不満に思いつつ、あとがきのお知らせを読むと、書籍化されるらしい。

書籍化!?

これ6年前の作品だぜ?信じられない!僕が一番好きな作品だと思っているので、書籍化される妄想をしたことは何度もあったが、さすがに古い作品だし、そんな話の影も形もないということは書籍化はあり得ないだろうと思っていたのに。

で、それに伴って全面改稿するのだが、新しい作品としてなろうに投稿していくらしい。それ商売になるのか?ありがたく読ませていただきます。

書籍化の衝撃から回復したので、おすすめのなろう小説まとめを投稿した。

kotatsugame.hatenablog.com

これのジャンル分けは、自分がその作品のどんな要素を求めて読んでいるかを表している。まあでも2つ以上の要素があると感じる作品もかなり多いので、ジャンル分けはあまりよくなかったかも。あとコメントもちゃんと書きたかったのだが、熱意が足りずかなり適当になってしまった。そもそもコメントを付けられなかった作品も多い。

コメントがついていない作品は、別に筆舌に尽くしがたく面白かったわけではなく、逆にあんまり印象が残っていないだけ。そんなのおすすめするなよ……と自分でも思うのだが、このまとめ記事はとにかく数を重視した。掲載分を全部読んだ記録が残っている作品のうち半分くらいは載せたんじゃないか?

好みが似通っている人であっても、刺さるなろうは人それぞれ微妙に異なるはず。だからおすすめ記事といっても自分に本当に刺さった作品を少しだけ載せるのではあんまり他人の参考にならない。数を用意して、まとめ記事を見た人がリンクをたどって個人で判断してもらうのが良い。というか僕がそういうまとめを好み、新しい作品を探している。

布団に入ってハーメルンを読んでいたらまた寝落ちしてしまった。

09/30(水)

朝、起きる。眠いけどハーメルンを読み始めてしまい、二度寝に失敗する。昼頃、ようやく起床報告をして、学食に行く。

本当は学食に行った後そのままゲームセンターでアップデート前に駆け込みでイベントマップを終わらせる予定だったのだが、ハーメルンが面白すぎるため家に帰ってまた読む。

ハーメルンはいつでも読めるのに対して、イベントマップは今日を逃すと次復刻するのはいつかわからない。そんなことは百も承知だが、理性ではなく感情が、ハーメルンを求めているんだッッッ!

今日も今日中にしなければならないことがあるので、午後9時くらいにいったん切り上げるか……と思っていたのだが、ちょうどそのころ物語の山場を迎える。読むのが止められない!そのまま2時間くらいまんじりともせず読み続けて、一区切りついたところでしぶしぶ身を起こしてパソコンに向かう。

メールを送り、少しAtCoderをする。今日はこどふぉのdiv.1があるらしいが、眠いしハーメルンを読みたいしなのでサボる。こどふぉに真面目に向き合っていないので、結構簡単にratedをサボってしまいがち。

実は今日は夏休み最終日なので、2020年後期の履修を組まなければならない。取得単位を丁寧丁寧丁寧に確認する。今期の専門科目は再履修と結構かぶっていてあんまり取れないが、所詮選択必修なので全部取ってもあんまり意味がないどころかキャパるだけ。被っていないものを取るだけでちょうどいい。

結局、今期の再履修は1年生の時に落とした線形代数学と、2年生の時に落とした群論幾何学。1年生の時に落としたやつは、2年生のときは必修と被っていて取れなかったのだったか?まだ負債が残っているとは、嫌になってしまうな。

履修登録は明日からなので、時間割だけ考えておいて、今日は終わり。布団に入ってハーメルンを読んでいたらまた寝落ちしてしまった。最近就寝報告できてないな。

10/01(木)

朝起きて、ハーメルンを読み続ける。

このシーンで読むのに耐えられなくなる。感情がデカすぎて読み進められない。わかるか?これすき。途中から薄々感づいてはいて、お互い名字で呼び合っているのを逐一確認していた。とはいえ、予測可能回避不可能の一撃。

今日から後期なので学食の営業時間も伸びる。それで、無理して昼の学食に行く必要もないこともあり、昼はずっと布団でハーメルンを読み続けていた。午後5時、シャワーを浴びて家を出る。

学食で数学科の友人2人と会った。今日の講義の話題が出るが、まだ資料を参照していないのでよくわからない。あとは履修の話や夏休みの話。

帰宅して、またしばらく布団でハーメルンを読んだあと、履修登録をすることにした。

昨日決めた時間割の科目を登録していく。線形代数学は人数が多いので講義が5個あり、再履修の人は先生を選ぶことができる。これは後回しにして、他のものを登録した後空きコマで何が取れるのか確認する。

探すと結構プログラミング関連の講義って多いんだな。Pythonを使う講義が2つと、R言語を使う講義が1つあった。かなり興味を惹かれるが、Pythonは好きではないしR言語AtCoderで使用できないので、別にいいかな……という気持ちになる。履修登録期間中は意識が高くなりやすいので、注意する必要がある。

コンピュータグラフィックスという講義を発見した。別にプログラミングをする講義ではなさそうだが、かなり興味深い。これは耐え切れず登録してしまった。意識を低くする必要がある。

工学部の科目なので、工学部のサイトで詳細を調べる必要があるが、TLに話題を流すと運よく同じ講義を取ろうとしている人に引っかかった。classroomの講義コードを教えてもらってニコニコ。

線形代数学の先生を、シラバスを確認しつつ選ぶ。期末一発という先生は、実はあんまりうれしくないことを実感してしまったので、無難にレポートとテストで決める先生を選ぶ。

布団に入って数時間ハーメルンを読み、眠気に耐え切れなくなった段階で就寝報告をする。今日は寝落ちじゃないぞ!

10/02(金)

昼頃起きる。生活リズムがだんだんずれてきていい感じ。土曜日はARCなので、夜眠くなるわけにはいかない。ハーメルンが面白すぎて二度寝は不可能なので、最初に起きる時間自体を遅くする必要がある。

ICPCのチーム決めに関して、サークルと顧問の先生の研究室で合同チームを組むことになっているが、これに関するやり取りが佳境に入る。最近メールをやり取りしていたのは、ただこれだけのため。一昨日はこちらでまだチームを組んでいない人たちのレートを渡し、昨日はそれに対する研究室の希望を聞いた。関係する人に確認が取れたので、本決まりの連絡をする。

向こうが了承してくれれば終わりだが、一応それを待つ必要があるので、先にICPCのアカウントを作ってもらうことにする。メールアドレス収集のためのGoogleフォームも用意する。最初はサークルSlackのDMで教えてもらおうかとも思っていたが、それはあまりに原始的だろう。

学食に行く。結構時間ギリギリになっちゃったな。13時半を過ぎているので、大中小を選べる店舗は閉まっている。仕方なく普通に弁当を食べる。

帰ってきて、また布団でハーメルンを読み続ける。夕方、合同チームの了承が取れたので、残りの人たちでチームを組み、発表した。まだチームを組んでいなかった人たちを、僕がレートを見て勝手に組み分けた。圧政。この人と一緒になりたいとかの希望は聞いていたので、それ以外の人たちを何も相談せずに組み分けたのは許してもらえるものと信じている。チーム名を決めてもらうが、これまた出そろうまでにはかなり時間がかかるだろう。

しばらくAtCoderをした後、yukicoderのコンテストに参加する。5完。A問題は最も難易度が低いはずだったが、結構考察する必要があり、時間を取られた。Eは実験すると、ありうる状態の数がそんなに大きくならないことがわかるので、mapでDP。

Fは全然わからなかったのだが、区間DPらしい。うーん、まだよくわからない。こまごまとした等差数列の計算が面倒そう。

ハーメルンは全然読み終わらない。今400話まで来たが、現在投稿されているのは530話。しかもいまだに2日に1話ペースを守り続けている。これは本当にすごいことだ。

最近読んだ「東方遺骸王」も500話越えだったが、あちらは1話あたりの文字数が少ないらしい。実際、合計文字数を見れば1,487,449文字に対して3,745,967文字である。どちらも大長編であることに違いはないが、それでも差は大きい。

10/03(土)

今日はratedなのでちゃんと寝ておくことにする。相変わらず5時間くらいで一度目を覚ましてしまい、ハーメルンに手が伸びそうになるが、それを必死の思いで抑え込んで二度寝した。結局10時間くらい寝られたのでよし。

寝っ転がったままハーメルンを読んでいると、大学生協の弁当の配達と宅配便があった。対応していると、ちょうど隣人が帰宅したので、挨拶でも……と声をかけた。

ちょっとした立ち話になって、「もしかしてこたつがめって名前のアカウントでTwitterやってますか?」と聞かれた。大正解である。FFの方だった。

同じ共同住宅内にTwitterをやっている人が他にいる、というのは別の住人から聞いていたらしく、垣間見える僕の生活リズムがツイッターでの言動と一致していることで疑いを持ち、過去のツイートから確信に至ったらしい。すごいな……僕はいっつもカーテンを閉めっぱなしなので、隣人の部屋に明かりがついているかどうかさえ知らない。

過去のツイートから確信に至ったとは言っても、同じ共同住宅に住んでいればわかる程度の話で、僕の住んでいる場所がツイートから特定できたというわけではないらしいので、ちょっと安心。実際のところ、丁寧に分析すれば住所はかなり絞られると思う。インターネットって怖いね。

僕は大学でもこたつがめと名乗っているし、ツイッターアカウントとリアルが紐づけられることについては全く気にしていないのだが、普段のツイートを見てリアルの僕を想像するとちょっとウッとなるのは確かだと思う。致したとかつぶやきまくってるしね。これについては、僕がどうこうする問題ではないので、諦めてくださいと言うほかない。

あとは、せっかく隣人と話す機会なので、普段夜中にYouTubeを垂れ流しているのが音漏れしていないかを聞いてみた。特に聞こえていないらしいので安心。机があるのは会話している隣人の部屋とは逆側の壁なのだが、スピーカーが向いている方向的に考えると、音が響くとしたらこっちだよなあと考えていた。(この「こっち」というのは不正確な言葉だが、正確に書くと冗長なのでこうしている。)

水曜日に再履修で全学教育の線形代数学を取っている。専門教育が対面かそうでないかはチェックしていたが、そういえばこれが対面かどうか確認していなかった。どこで情報を得るのだろう、とツイートしたら、ホスフィンから教えてもらった。

東北大学 全学教育ホームページ Tohoku University General Education

オンラインらしい。やったぜ!

夜になって、ARCに参加した。4完74位でパフォーマンス2641、レートは5下がって2687。順位から予想していたほどひどい結果にはならず、安心している。人が増えたのと全体のレベルが上がった影響なのかな?2年前にこの順位を取っていたら、橙ギリギリのパフォーマンスが出ていたと思う。D問題にかなり手間取って、通したときはかなり遅いと感じていたが、その後4完の人がかなり増えたので、危ないところだった……という感想。いやレートが下がったのでアウトなんですが。

Cはパッと見よくわからなかったけど、N=100なのでいろいろできて、考察した条件1つだけでDPしてOK。

DもDPだけど、ついうっかりべき級数にしてしまう。べき級数にしていいことは何もない。

多項式の列があって、それの区間の積を求める。セグ木は明らかにダメなのでDisjoint Sparse Tableを使って書き上げたが、これも全然間に合わない。

もう少し観察すると、積を求めたい区間は常に正と負(DSTのときはオフセットを足して正にしていた)にまたがっているので、ここで2つに分けて0からの累積積だけ持っておけばよい。まだ少し間に合わない。

負に対応する多項式は、それぞれ正のものを流用できることに気づく。まだ微妙に間に合わない。

あとは最大ケースの答えを変えない範囲で多項式の次数を削ったり、答えが対称的であることを利用して後ろ半分は以前の結果を参照したり、そういう高速化をしたら最大ケースでもTLの4secにギリギリ収まるようになった。提出すると3820msでAC。

実際には、掛ける多項式の非ゼロな係数はK個しかないので、毎回愚直にDP遷移をしたほうが良い。他の考察はすべてよかったが、このDP遷移でべき級数を持ち出したのが本当にアホ。ギリギリ通ったからよかったものの……。ちなみに愚直にDP遷移をすると1300msだった。多項式の次数を削ることはしていない。

E問題に取り掛かったころには残り30分だった。N<=6に気づいて、座圧後の数列を固定することまで書いたら残り15分。ここで焦って考察ミスをし、場合の数を求められなかった。実際にはDPを座圧して高速化する必要があるらしく、もとより15分では望み薄だったか。

ハーメルンを読み進める。クディッチのシーンを読んでかなり興奮した。ルール的にゲームとして成立しているとは思えないのだが、フィクションの世界でバトルを演出するのには向いてそう。

そういえば、D問題で1300msを出したコードは、手元で最適化オプションをつけずにコンパイルして実行すると最大ケースで1分くらいかかる。こんな極端に変わるものなのか……。

10/04(日)

朝寝て昼に起きた。6時間も寝ていないらしいが、今日は特にコンテストもないし、生活リズムを前にずらす意味でも起きることにする。

昼食を食べた後、しばらく布団でハーメルンを読んでいた。ハリー・ポッターとオリ主がホグワーツを卒業してしまい、ちょっと読むペースが落ちてしまう。

自分は原作終わったあたりで放置してる。

個人的ハーメルンおすすめ小説集 - -!=x=!-

納得。

ACLRubyに移植するプロジェクト、最近全然触れていない。コード自体はおおむね完成していて、今はドキュメントを書いているらしい。僕が作ったライブラリのぶんくらいはドキュメントを書くべきだろう。

convolutionは実装したが、convolution_llは実装していない。NTT-Friendlymodを3つ用意して復元するのだが、本家は何を計算しているのかよくわからない。まあRubyはオーバーフローの心配がないことだし、mathの一部となっているcrt(中国剰余定理の復元)でよいだろう。わざわざconvolution_llにまとめる必要もない……と考えていた。

実際には、そもそも十分大きなmodconvolutionすればよいのである。例えばFFTが誤差なく計算できる限界ともいわれる(要出典)10^15くらいであれば、mod 1125900443713537 = 2^29*2097153+1を用いてNTTすれば一発で求まる。3回もNTTするよりは定数倍的に格段に優れるだろう。このmodを用いると、10^9くらいのmodのときの倍の時間がかかったが、3倍よりは速い。

ではlong longにギリギリ収まるような畳み込みはどうなるかというと、mod 18446744073944432641で試してみたら、さっきのものからさらに倍以上の時間がかかるようになった。つまり10^9くらいのmod4回分以上、ということだ。こうなってくるとNTT3回のほうが速い。う~ん。

よくよく考えると、10^15以下の数値を復元するためにはmod2個でいい(これは前にも書いたような記憶がある)。結局定数倍的には全然変わりがないどころか、大きな数値ではむしろ悪化してしまう。まあ10^15くらいのところではギリギリ大きなmodのほうに軍配が上がるだろう。試してはいない。

Rubyのライブラリはこのくらいにしておいて、今日は僕のライブラリも整備する。modintを書くぞ!

と気合を入れてACLの実装を読んでいたが、enable_if_tをググったりTLに質問を投げたりしていたら数時間が経過してしまった。一応納得はできたが、ここに書くのはちょっと面倒すぎる。そもそも僕が実装して僕が使うんだから、そんな真面目にチェックを入れる気にもならない。痛い目を見たら考えることにする。いやでも怖くなってきたな……。

そんなことをしていたら、こどふぉのdiv.2があるらしい。直前まであんまり出る気がなかったのだが、div.2だし適当に出てもいいよな、ということでレジってしまった。

A~Dまでを爆速で解き、この時点で全体2位。Eも解いてFが解けなくて5完か~と思っていたら、システスでEが落ちた。意味不明。

真面目に出ていないのだから真面目にupsolveする気もない。放置する。

Fはnuipさんのツイートを見て何となくわかった気になっておいた。小さな素数はセグ木なりDSTなり使って計算すればよい。大きな素数が問題なのだが、平方分割することにして、バケット内では「次に同じ素数が出現する場所」の降順に並べ、累積積を取ればよいらしい。バケット内でLCMに寄与するものというのは、LCMを計算したい区間より右に行かないと同じ素数が再度出現しないものであるから、先頭のほうに固まる。よって適切な位置の累積積を見ればよくなる。

明日の1限はリアルタイムのMeetの講義で、スライドの穴埋め形式らしい。穴埋めってなんだよ、漢字ドリルじゃないんだぞ。げんなりしていたら、ホスフィンから講義録画の存在を知らされる。つまりリアルタイムで受講しなくてもよいということだ。いいね。

おすすめのなろう小説まとめ

kotatsugame.hatenablog.com

適当にジャンル分けしました。コメントも適当です。

最終更新日:2021/06/16

芸能人

僕がアイマスの二次創作を読むのは、アイドルが主人公の作品を手っ取り早く見つけるためなので、それらはジャンル:二次創作には入れていません。

アイドルの世界に転生したようです。

これ本当に好き。外伝『Days of Glory!!』はまるまるライブをやるんですけど、マジで面白い。それまでの数百話を振り返り、泣きながら読んだ。

アイドルの世界に転生したようです。 - ハーメルン

美少女モデルのAliceは今日も片想い

多分僕が芸能界系の話にハマったきっかけだと思う。大人気俳優が主人公と話すために学校に来るシーンが好き。

美少女モデルのAliceは今日も片想い(せりざわ@咲間咲良) - カクヨム

ホラー女優が天才子役に転生しました ~今度こそハリウッドを目指します!~

https://ncode.syosetu.com/n0230fu/

だから俺は〇〇なんかじゃない!~高嶺の花をナンパから助けたら正体がばれました~

普段は正体を隠して生活してるけど、たまにトップモデルとしての影響力を発揮するシーンが好きなんだよな。

https://ncode.syosetu.com/n1910ft/

世界で一番『可愛い』雨宮さん、二番目は俺。

https://ncode.syosetu.com/n0228ge/

この○○のない世界で

何かの祖になるの、歴史を見守る系と同じ雰囲気を感じて好き。

この〇〇のない世界で - ハーメルン

青空よりアイドルへ

アイマスグラブルのクロスオーバーらしい。チートアイドル主人公好きなんだよね。あと掲示板回も好き。

青空よりアイドルへ - ハーメルン

デブオタと追慕という名の歌姫

デブオタと追慕という名の歌姫(ニセ梶原康弘@カクヨムコン落選) - カクヨム

恋愛

お隣の天使様にいつの間にか駄目人間にされていた件

かなり好き。普段はわからないけど髪をセットしておしゃれするとイケメンになる主人公、あるあるだよね。ちなみに隣人・学校一の美人・半同棲って作品は山ほどあって山ほど書籍化されている。

https://ncode.syosetu.com/n8440fe/

薬屋のひとりごと

実のところ、僕は書籍版で読んで、その恋愛要素に最も強く惹かれたんだよね。web版は読んでないのでよくわからないけど、恋愛要素は比較的薄そう。でも認識としては恋愛なんだよな。

https://ncode.syosetu.com/n9636x/

氷の令嬢の溶かし方 ~クールで素っ気ないお隣さんがデレるとめちゃくちゃ可愛い件~

設定は「お隣の天使様にいつの間にか駄目人間にされていた件」とかなり似てる。でもこんなんなんぼあってもいいですからね!

https://ncode.syosetu.com/n2567fv/

放課後インスタントセックス

注:ノクターンノベルズのため18禁

https://novel18.syosetu.com/n7640gf/

VRMMO

最強カップルのイチャイチャVRMMOライフ

掲示板回よりもっとリアルタイムの反応を楽しめるのは何か、知ってるかな?そう、配信だね。

https://ncode.syosetu.com/n2143dt/

VRMMOをカネの力で無双する

大企業の社長好き。

https://ncode.syosetu.com/n0553bs/

VRMMOで攻略とスローライフの両方を手に入れる方法

リアルチート好き。ただまあ、タイトルに反して後半は主に現実世界の話になる。個人的にはそちらのほうが好きなんですが。

https://ncode.syosetu.com/n6395ef/

Magica Technica ~剣鬼羅刹のVRMMO戦刀録~

リアルチート好き。

https://ncode.syosetu.com/n4559ff/

打撃系鬼っ娘が征く配信道!

VRMMOと配信で最高。さらにリアルチートが合わさって最強に見える。

https://ncode.syosetu.com/n9517fc/

配信

逆行転生したおじさん、性別も逆転したけどバーチャルYouTuberの親分をめざす!

何かの祖になるやつ本当に好き。

https://ncode.syosetu.com/n3530fy/

転生して電子生命体になったのでヴァーチャル配信者になります

Vtuber面白い。まあ現実のVtuberは1回も見たことないんですが。

転生して電子生命体になったのでヴァーチャル配信者になります - ハーメルン

美少女になってちやほやされて人生イージーモードで生きたい!

実際の配信をタグとか使ってハーメルン上で再現する試みは面白い。ただゴテゴテしすぎて、ちゃんと集中しないとストーリーが読めない面もある。

美少女になってちやほやされて人生イージーモードで生きたい! - ハーメルン

21世紀TS少女による未来世紀VRゲーム実況配信!

https://ncode.syosetu.com/n6398fv/

輝きたくて

これも逆行転生VTuberもの。

輝きたくて - ハーメルン

王・領主

魔王様の街づくり!~最強のダンジョンは近代都市~

あまり詳しいことは覚えていないけど、なんというかこれぞチート主人公の王道!みたいな流れを完璧になぞっていてすごい。この作者さんは多作だけどその流れは共通しているように見えるので、どれか1つが好きなら全部好きだと思う。

https://ncode.syosetu.com/n7637dj/

異世界国家アルキマイラ ―最弱の王と無双の軍勢―

王、影の実力者、歴史を見守る人。結局圧倒的な上位者視点の話が好きなんだよな。

https://ncode.syosetu.com/n0031ei/

俺は星間国家の悪徳領主!

https://ncode.syosetu.com/n1976ey/

異世界で 上前はねて 生きていく (詠み人知らず) 〜再生魔法使いのゆるふわ人材派遣生活〜

後々規模がデカくなってくると、面白くなる。

https://ncode.syosetu.com/n1832fm/

転生したらスライムだった件

現1位。納得の面白さ。

https://ncode.syosetu.com/n6316bn/

企業・経済

現代社会で乙女ゲームの悪役令嬢をするのはちょっと大変

大企業の主ほんと好き。ただ、まだ主人公が幼すぎて表舞台に立てないのがもどかしい。

https://ncode.syosetu.com/n3297eu/

玉葱とクラリオン

序盤はただのテンプレ異世界転生知識チートか……って感じに見えるかもしれないけど、どんどんきな臭くなっていく。ちなみにこれのジャンル分けはよくわからない。途中辛すぎて読み返す気になれない。

https://ncode.syosetu.com/n0632db/

予言の経済学 ~巫女姫と転生商人の異世界災害対策~

主人公は自覚してないけど周りの人間は主人公の凄さを分かっている、みたいなのちょっともどかしくなるけど好き。

https://ncode.syosetu.com/n6472dl/

プニキとはじめるリーグ運営 ~野球ゲーム?作って運営します~

「会社の社長(代表)となるための才能」というの、良い。

https://ncode.syosetu.com/n4212eh/

歴史を作る・見守る

始まりの魔法使い

長命で強力な生物になって人類を導いていくのめちゃくちゃ好きなんだけど、この作品はたぶんそのきっかけだったと思う。

始まりの魔法使い(石之宮カント) - カクヨム

滅竜山くんの一生 ~46億歳、全ての生命と魔の祖~

歴史を見守る系の話は基本長く書くほど深みが増して面白いんだけど、これは16話でスッキリ書いているにも関わらずめちゃくちゃ面白い。迷ったら読んでみてほしい。

https://ncode.syosetu.com/n3617fx/

転移先、200000年前。 帰還先、復讐。

不死者が歴史を眺めるやつ。「とんでもなく長い時間積み重ねた修練に基づく他を圧倒する技量」系のチートが好き。僕がそういう見方をしているだけで、ストーリーも面白い。

https://ncode.syosetu.com/n1996ca/

目指せ樹高634m! 〜杉に転生した俺は歴史を眺めて育つ〜

主人公が杉になるやつ。数十話前の出来事が史実として伝わってるのを見るの好きなんだよな。

https://ncode.syosetu.com/n1618fc/

ノーライフ・ライフ

魔法を科学するやつとはいっても、これだけ膨大な設定があるとただただ圧倒されるよね。

https://ncode.syosetu.com/n8390n/

東方遺骸王

「歴史を見守る系の話は基本長く書くほど深みが増して面白い」こんだけ長いともう深すぎてめちゃくちゃ面白い。ただ最初のほうからかなり細かくイベントを書いているので、全然物語が進まなくてイライラするかも。

東方遺骸王 - ハーメルン

「「神と呼ばれ、魔王と呼ばれても」」

歴史を眺めるやつだけど、歴史に対してほとんど干渉しないのはちょっと好みから外れる。

https://ncode.syosetu.com/n4845ec/

杜人記-ゆるゆる土着神-

https://ncode.syosetu.com/n1309m/

竜に生まれまして

やはり圧倒的な上位者が歴史を観察しているのは良い。

https://ncode.syosetu.com/n5244by/

少女(仮)の生活

VTuberやってる」って聞いて軽い気持ちで読み始めたら、とんでもないスケールに圧倒された。読みながらどうやってVTuberが出てくるのか不思議でならなかったが、確かに出てくる。

少女(仮)の生活 - ハーメルン

東方乱力録

東方古代スタートもの。

SS投稿掲示板

東方狐答録

東方古代スタートもの。

東方狐答録 - ハーメルン

東方蛇狐録~超古代に転生した俺のハードライフな冒険記~

東方古代スタートもの。文章にかなり難があるが、設定が良い。あとは正体を隠している要素とかも好み。

東方蛇狐録~超古代に転生した俺のハードライフな冒険記~ - ハーメルン

東方空狐道

東方古代スタートもの。良さげだが、エタっている。

東方空狐道 - ハーメルン

東方鼬紀行文

東方古代スタートもの。良さげだが、エタっている。

https://ncode.syosetu.com/n6204l/

ファンタジー(戦闘)

Tamer's Mythology

本当に好き。本当に好き。本当に好き。本当に好き。本当に好き。本当に好き。本当に好き。

https://ncode.syosetu.com/n9218ci/

天才最弱魔物使いは帰還したい ~最強の従者と引き離されて、見知らぬ地に飛ばされました~

上の作品のリメイク版。こちらも変わらず面白い。ちょっと突拍子がないと感じる個所もちゃんと説明されていて、全体として読みやすいが、小ぎれいにまとまりすぎて個人的に盛り上がりに欠けると感じている。両方読む場合は先にリメイク前のほうを読むのを推奨する。

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

無職転生 - 異世界行ったら本気だす -

古典。死ぬほど面白い。

https://ncode.syosetu.com/n9669bk/

地味な剣聖はそれでも最強です

https://ncode.syosetu.com/n9846ee/

双翼の舞う世界 ~魔法界からの帰還者~

突っかかっていた見習い魔法使いたちの前で主人公の地位と名声が明らかになるシーン好き。

https://ncode.syosetu.com/n6383bo/

陰の実力者になりたくて!

影の実力者が好き。本当のことを言えば、この作品から勘違い要素を抜いたものがあれば最高なんだけど、この作品はそれはそれで非常に面白い。

https://ncode.syosetu.com/n0611em/

最強魔法師の隠遁計画

序列!最強!学生!全部大好き。王道って感じ。僕がなろうを読み始めた頃の好み。

https://ncode.syosetu.com/n5606cq/

嘆きの亡霊は引退したい 〜最弱ハンターは英雄の夢を見る〜

仲間がめちゃくちゃ強いのが好きなんだよね。パーティーメンバーが登場してからが本番。それまでは貧弱な主人公にもやもやし続ける。

https://ncode.syosetu.com/n6093en/

公女殿下の家庭教師

設定とストーリーがかなり好き。……なんだけど、恋愛描写がクドいのと台詞回しがかなり特徴的なので、気軽におすすめできない。いやするけどさ。

公女殿下の家庭教師(七野りく) - カクヨム

ここではありふれた物語

主人公が本当に不幸すぎて読んでて辛くなる。でも面白い。

https://ncode.syosetu.com/n6359da/

サイレント・ウィッチ

正体を隠しているのはいいぞ。

https://ncode.syosetu.com/n8356ga/

転生したら皇帝でした~生まれながらの皇帝はこの先生き残れるか~

「王・領主」カテに見えるが、いかに王となるかが主題のため、こちらに。

https://ncode.syosetu.com/n6066gi/

邪神ちゃんと極大魔法詠唱者

https://ncode.syosetu.com/n5295gq/

奇運のファンタジア

「経営」で検索して出てきたやつだったけど、読んだ感じ主人公の強さをより重点的に扱っているので、ここに振り分けた。

https://ncode.syosetu.com/n8357fd/

二次創作

ハリー・ポッターと野望の少女

古典。旧1位。死ぬほど面白い。影響受けすぎて似たような口調の主人公全員ミラベル・ベレスフォードに見える。

ハリー・ポッターと野望の少女 - ハーメルン

このすば*Elona

現1位。このすばもElonaも全然知らないけどそれでもとんでもなく面白かった。

このすば*Elona - ハーメルン

うちの脳内コンピューターが俺を勝たせようとしてくる

現2位。上の「このすば*Elona」とは僅差なのでもうすぐ1位になるかも(追記:なったけどまた入れ替わっていた)。めちゃくちゃ面白い。

うちの脳内コンピューターが俺を勝たせようとしてくる - ハーメルン

Game of Vampire

ハリポタの二次創作。めちゃめちゃ面白い。特にヴォルデモートの最期までが最高。

Game of Vampire - ハーメルン

気付いたら赤木しげるの娘だったんですが、

すごいヘンな読み方をしてるんだけど、裏社会に存在感を示す主人公好きなんだよね。

気付いたら赤木しげるの娘だったんですが、 - ハーメルン

比企谷八幡 「・・・もう一度会いたかった」

逆行転生!出来事を知ってる系チートはともかく、1度目の人生で身に着けた能力を使うの好き。

比企谷八幡 「・・・もう一度会いたかった」 - ハーメルン

やはり俺の大学生活は間違っている。

そうはならんやろ、みたいな大学生活送ってるな。

やはり俺の大学生活は間違っている。 - ハーメルン

我輩はレッドである。

我輩はレッドである。 - ハーメルン

ポケモン世界に来て適当に(ry

ポケモン世界に来て適当に(ry - ハーメルン

ダリアの歌わない魔法

ハリポタの二次創作。

ダリアの歌わない魔法 - ハーメルン

バカと天使とドロップアウト

バカと天使とドロップアウト - ハーメルン

私の世界は硬く冷たい

ハリポタの二次創作。

私の世界は硬く冷たい - ハーメルン

東方有栖伝

東方有栖(アリス)伝 - ハーメルン

東方帽子屋

東方帽子屋 - ハーメルン

魔法の世界のアリス

ハリポタと東方(アリス・マーガトロイド)のクロスオーバー。

魔法の世界のアリス - ハーメルン

未分類

素人おっさん、転生サッカーライフを満喫する

逆行転生にハマってた時に見つけた作品。

https://ncode.syosetu.com/n5399el/

異世界クイズ王 ~妖精世界と七王の宴~

競技クイズ、スゲー。僕は競技クイズをしたことがないので、いろいろ登場するテクニック自体を楽しめたんだけど、知ってる人には知ってる側の楽しみ方があるんだろうなあ。

https://ncode.syosetu.com/n1867fd/

無冠の棋士、幼女に転生する

https://ncode.syosetu.com/n1783ex/

週記(2020/09/21-2020/09/27)

09/21(月)

午前10時くらいに目を覚ます。予定まで2時間を切っているのに二度寝する気にはならない。起きる。昼食のために学食に行こうとしたが、今日は祝日で休みであった。仕方がないのでコンビニで適当に買う。

ライブコードゴルフ大会に出演した。これについては参加記を書いたので、そちらへのリンクを貼るだけにしておきたい。

kotatsugame.hatenablog.com

一点、特別に書き残しておきたいことがあった。Rubyは僕は一切手を付けていないため、参加記にも欄を設けていない。このRubyについて、外部の方が引用RTでコードを縮めてくださったので、それを参照できるようにしておきたい。

$<.map{p$s&&_1>$s?0:($s=_1;1)}30B)、または$<.map{p _1>$0?0:($0=_1;1)}27B)。

特殊変数を使う発想は僕にもあったが、何か都合のいい初期値を持つ特殊変数を(しかも変数名が記号1文字のものの中から)探そうとしてしまった。30Bのほうは、初期値nilの普通の特殊変数を使って、nilかどうかの判定もしているものだ。nilかどうか判定するのは長いと思っていたけど、それは僕の直感が間違っていて、きちんと試せば短くなることに気づけたと思う。失敗。

27Bのほうは、都合のいい初期値を持つ特殊変数として$0を使ったものだ。これ思いつけなかったのかなりショックだな。実際は$0、つまり実行時のファイル名がいかなる2桁の数値よりも辞書順で大きい必要があるので、ジャッジ環境の詳しい仕様を把握していないため本当に通るのかはわからない。コードのファイル名にa.rbとかmain.rbとか使っていればよいが。

コードゴルフ大会が終わった後、ACPC day3に参加した。1時間遅れだったけど、そんなことは全く関係なく、普通に2時間くらいかけた問題が解けなくてつらくなってしまった。実際は途中でふて寝したりしてるので、椅子を温め続けたわけではない。

日付が変わるころ、今年のJOI予選第1回の問題が公開された。すかさず解いて縮めておく。自明な問題の短縮は速度が命。実際、A問題はすでに何度も出題されているような問題設定だったので、覚えていた最短コードをそのまま書いて終わり。

さて、日付が変わって9/22、秋分の日である。今年の秋分の日は秋分コンテストの日。ということで、これから午後4時くらいまでずっと秋分コンテストをやっていた。これについても参加記を書いたので、リンクを貼っておく。具体的にどういうムーブをしたのかとかは書かない。覚えてないからね。

kotatsugame.hatenablog.com

午後4時頃に、パソコンに向かっていても意識が保てなくなってきたので、寝た。当然日記など書いている余裕はないので、この日の日記は後日書いたものだ。

09/22(火)

午後10時頃に目を覚まし、すかさず秋分コンテストに参加する。R問題はtozangezanさんがリアルタイムで旅をして、撮った写真の緯度経度を当てる問題だ。僕が昨日の深夜に見た段階では、謎の夜景が1枚ぽつねんと公開されていただけだったが、今見ると10枚全部公開されきっていた。

さあやるぞ、と確認したら、最後3枚で度肝を抜かれた。富山の写真だったのだ。通っていた高校や通学路のすぐそばである。一瞬で分かった。かなり興奮した。このことは参加記にも書いたが、あまりに印象深いので、日記のほうでも強調しておく。

真夜中にコンテストが終了してから参加記を書き、ほかの人のツイートを眺めたりしているともう朝になってしまった。

布団に入ってなろうを読んでいたが、どうにも腹が減って寝れないので、学食に行くことにした。帰ってきて寝た。午後3時であった。

09/23(水)

本当は日付が変わったあたりで少し目を覚ましてなろうを読んでいたのだけれど、2時間くらいでまた寝たので、この日はなかったことにする。

09/24(木)

午前6時くらいにベッドから身を起こす。それ以前に意識は取り戻していたが、「ぽきた」のツイートをしたのはこの時間。

たいぺーと待ち合わせて学食に行き、帰ってきてラノベを読んでいると、ホスフィンから「スキャナを使わせてほしい」との連絡がきたので快諾。夜に部屋に来ることになった。少し掃除をする。

お酒を持ってきてもらったので、飲酒しながら映画を視聴する。僕の部屋に集まるときはこれが定番。なぜなら僕の部屋には遊べるようなものが何一つ存在しないので。

夜は短し歩けよ乙女」の映画を観た。原作は全然読み返していないので展開などあまり覚えていなかったから、差分を観察することはできなかったが、そういう楽しみ方でなくても普通に観るだけで超面白かった。偏屈王が思ったよりミュージカルしていてびっくりした。しかし城ヶ崎氏のダッチワイフのくだりは何の説明もなかったので、原作を読んでないとわからないんじゃないのか?

次にホスフィンが観たいというアニメ映画を見ることになったのだが、僕が限界に達して床で意識を失ってしまったらしく、視聴は取りやめになった。正直スマン。

あとは動画投稿サイトで各々の好きな動画を布教しあっていた。僕はラーメンズが好きなので、コントをいくつか見せようと思ったのだけれど、これといって心に決めていたものがなかったので、かなり迷ってしまった。

結局「五重塔」「日本語学校アメリカン」「バニー部」「受験」を見せたけど、この選択には心残りがある。新しい公演からもっと選んでもよかったかもしれない。

午前3時半、お開きになる。ホスフィンはこれから歩いて帰る。僕はもう身動きが取れないため、後片付けは明日にして即座にお布団イン。就寝。

09/25(金)

起きたらちょっと気持ちが悪い。最近翌日まで響く酔い方をしていなかったので、結構つらい。食事をとらずにパソコンを触っていたらどんどん気分が悪くなっていったので、インスタント味噌汁を飲んだ。少し楽になった。

今日はゲームセンターに行くつもりだったので、微妙に怪しい体調を抱えて行く。これ風邪の諸症状とかじゃないよね……?

本屋さんに寄って本を買った。以前から買おうと思っていた新刊が3冊と、うっかり手に取ってしまった4冊。直前に遊ぶお金を下ろしていたので財布の中身に余裕があり、手に取って迷った本は全部買ってしまった。

チュウニズムについて、9/30までのマップが2つ残っていたので、これを進める。結局終わらなかったんですが……。期限までにまた行きたい。

疲れ切っていたので、帰ってきて風呂も入らずベッドに倒れこんだ。午後11時のツイートを最後に寝落ちした。

09/26(土)

朝早い時間に目が覚めて、ハーメルンを読んでいた。午前11時ごろに起床ツイートをしたが、まったく実態に即していない。

今日はTCOのRegionalだ。今年はオンラインでの開催となった。去年は思いっきり寝坊してらてあに迷惑をかけたことを覚えているが、オンラインならば問題はない、というか、別に参加しなくとも何にも言われなさそう。交通費とか出てるわけじゃないので……。

アルゴリズムラウンド以外に興味はないので、開会式とかは見ない。正直Regionalに参加する意思表示だけしたらTシャツが降ってくるんじゃないかと思っているが、念のためコンテストに参加しておく。div.2レベルの問題と宣言されているくせに全員Ratedなのはもはや定番。こういうのでレートを稼ぐと赤になりやすい。

Easyは忘れた。Medはある数の値を決めるために中央値を使ったけれど、最小のものを出力しなければならないことを忘れてA[A.size()/2]としてしまった。これはA.size()が偶数のとき最小ではなく最大の値となってしまう……と思ったら、実装の都合上偶然符号を反転していたのでセーフ。これは本当に意図しないラッキー。2人にチャレンジされて戦々恐々としていたが、おそらくこれに関係するものだろう。

Hardはよくわからない。よくわからないなりに、適当なところまで全探索して残りはDPした。これでうまくいく理論的な証明は一切行っていないが、提出した後にありうるすべての入力を試して正答したので自信はある。手元で何並列かして試していて、本当はすべて試し終わった後に提出しようと思っていたのだが、実際には時間がかかりすぎるので待ちきれなくて20%くらい終わった瞬間すぐに提出してしまった。そのまま走らせ続けた結果すべて正答したからよかったものの……。

コーディングフェーズ終了直後は24位くらいだったか?16位以上は何かあるらしいけど無理だろうな……と思っていたらシステスでボロボロ落ちて16位に滑り込んだ。かなりびっくり。2206→2246(+40)。

とりあえずTCOワイルドカードラウンドへ進出したが、Regionalのイベントとしてもう1つ、1対1のトーナメントがある。短い時間で1問解いて、点数が高いほうが勝つ。僕は16位なので、初回の相手は1位のACRushさんだ。草。無様は見せられない。

最初、数秒差で負けて非常に悔しかったたが、ACRushさんがリサブした。このままシステスが通れば僕の勝ちだが、ACRushさんがリサブするような罠があったのだろうかととても怖かった。実際には何事もなく通った。ACRushさんの解法と僕の解法は異なっており、ACRushさんの解法だと32bit整数がオーバーフローしてしまっていたらしい。ACRushさんが配信にコメントしていたのを見た。

配信で何度か僕の名前を読み上げられたのだが、kotatsugamegameの部分は何度読まれても「ゲーム」になってしまう。わかるよ。わかるけどウケる。

2回戦は普通に問題が解けなかった。ちゃんと式を書いて変形するべきだったのに、それを怠ってサンプルから合わせにいったせいだと思っている。結局0点で、相手の人も0点だったが予選の順位差で負けた。16位はつらいぜ。

ともかく、これでTCO Regionalの僕が関係するイベントはすべて終了。あとはABC(ACLBC)の時間までラノベを読んでいた。

ABCは全完9位。F問題は畳み込みとしてとらえるのに時間がかかり、また高速化が足りず1回TLEしてしまった。同じものを何回も畳み込んでいるように見えたので、ここを2分累乗法で実装したら通ったが、計算量はよくわからない。まあでもやばそうなのは1..sqrt(N)まで1回ずつ畳み込むケースだけど、これはO(N log N)くらいでできそうなのでいいのかな?想定解は小さいほうから2個ずつマージしている。この発想は何回か見た覚えがあるが一切身についていないらしい。

ベッドでハーメルンを読んでいたら、寝落ちしてしまった。たしか日付が変わったくらいの時間だったはず。

09/27(日)

午前7時くらいに目覚めて、ずっとハーメルンを読んでいた。本当は結構眠気があって二度寝したかったのだが、ハーメルンを読むのをやめられなかった。

昼頃、あきらめて起床報告をし、食事して、またベッドに転がってハーメルンを読み続けた。結局そのまま午後8時くらいまで読み続けていた。眠気がかなりあるが、今日もAtCoderのコンテストがあるので、意地で起き続ける。今日のコンテストはChokudai Contest、つまりマラソンだ。

まず、盤面すべてを1色で塗りつぶさないとお話にならないことを確認する。次に、どんどん連結成分を大きくしていくといいんじゃないか?という直感から、同じマス目を連打することを考える。最後に、変える色は連結成分が最も大きくなるような色がよいだろうと考える。実際にはこれはたぶんよくなくて、盤面の端のほうに速くたどり着く必要があるため、それを優先するべきだったらしい。なるほど。

ともかく、コンテスト中は以上3つのことを実装した。これにはランダム性は一切含まれないので、連打するマスさえ決定すればスコアは常に変わらない。テストケースが公開されているので、それぞれに対して連打するマスを全部試し、最もスコアが高くなるものを埋め込んだ。計算は結構時間がかかるので、プロンプトを7個開いて7並列で実行していた。手作業で埋め込みを行ったので、かなり面倒だった。その甲斐あってか、終了時点で全体20位とギリギリ順位表の1ページ目に滑り込んだ。

1点変更しか実装したことがないので、今回はそれが使えずマラソンをやってる感じは全然なかったのだけど、ビームサーチができるらしい。そりゃそうか。いずれ実装できるようにならなければならない。あと焼きなまし法の温度関数もどういう風に書くのかよくわかっていないので、マラソンをするにあたっての課題はかなり多い。

日付が変わってからこどふぉのdiv.1があるが、眠すぎるので見送る。起きる時間はかなり健康的だけど、健康的な生活を送るとコンテストに出られなくてかなりつらい。

秋分コンテスト 参加記

2020/09/23に行われた秋分コンテストに参加した。

kcs.miz-miz.biz

0時から16時までと、22時から24時まで頑張った。結果としては2338点で全体7位。

運営陣による解説ブログは次の通り。

以下、各問題の感想を書く。

※問題名の横には、満点と自分が取れた点数を記載している。

A問題(0/200)

何もわからなかった。とりあえず114514とかそういう例の数字が入力に含まれていないか調べたところ、含まれていないらしい。なんで問題文はこんな口調なんだ?

多項式補完してみたけど、当然のように自然数が列をなして現れた。それはそうだね。

B問題(100/100)

なんでもいいと思って、サンプルの"Autumnal Equinox Contest"を出力したらWAになった。自分のアカウント名を出力したらACした。マジで草。

C問題(200/200)

絵を見て書いてある単語を当てる問題だが、出題範囲がリストになっていて、かなり狭い。(あとヒントで文字数がわかるのが嬉しい。)絵もそこそこきちんとしているため、満点を得ることができた。回答の一部を紹介する。

  • 問7(ちきゅう)

丸しか書いていない。4文字の単語を上から下まで見て、丸いものを全部試した。

  • 問9(きょくがくあせい)

まあそういうことするよね……。末尾が「い」の四字熟語は少ないし、どれが当てはまるかは一発でわかる。

  • 問10(りゅうとうだび)

竜……?狐だろ。緑ければいいってものじゃない、というか体を描くのを待ってから回答してくれ。

  • 問11(ひよくれんり)

男女なのはわかるので、それに関連する四字熟語を全部試した。

D問題(200/200)

重み付き無向グラフが与えられるので、頂点38から出発して、頂点1から10をすべて訪れるのにかかるコストの最小値を求める。ただし、途中で頂点25を通ってはならない。また、2回だけコストを1/4にすることができる。

普通に難しい。最初はコストと最大値2つを持つダイクストラを書いたけど、まあそういうのはできないよね……。

結局、コストを1/4にする辺を全探索した。頂点番号の最大値がN=50だと決めつけ、訪れるべき頂点を1からK=10として、辺の数Mに対して O(2K NM(K+log N)+N2 3K) で解いた。さっきまでは頂点番号がintに収まらないんじゃないの?と疑ってmapとか使って書いていたが、計算量的にそんなことをしている余裕はない。

時間制限1 secに対してACコードは0.99 secだった。定数倍高速化が本当に厳しかった、と思っていたが、よく考えたらオーダーを改善してACしていた。コストを1/4にする辺を決めるとき、スタートから1本目、1本目から2本目……と計算するとオーダーにMが出現してしまい間に合わない。正解は、スタートから1本目と2本目から最後までを全探索したあとに組み合わせる。

E問題(300/300)

botに対して質問して問題文を探り当てる。botは「入力・問題・制約について聞く」→「特殊な応答をする(対応するモードに入る)」→「単語で聞く」→「答える(モードが終了する)」という動きをする。

まず入力の最大値を聞くと、66であるらしい。また応答文からOEISが関係していて、問いの数列が66項しかないことがわかる。次に問題文を聞きたいのだが、対応するモードに入るための質問文がわからない。結局「問題文に素数は含まれるか?」みたいなことを聞くと対応するモードに入ってくれることが分かったので、日本語通じてないけどこれで進めることにした。ちなみに、書いてる途中に試してみたけど入ってくれなかった。ACした瞬間タブ閉じちゃったので会話の内容はうろ覚え。

数列について聞くと、やはりOEISが関係していることがわかる。先ほどは黒塗りで4文字だったが、今はOEくらいが見えていた。また、秋分に関係することもわかるので、次に秋分について聞くと、数列の番号が関係するらしい。

このあたりでA000922とかA200922を調べたところ、A200922が確かに66項の数列なので、これを出力して終わり。

A200922 - OEIS

途中で問題に素数が関係することも判明していたが、埋め込むだけなので使わなかった。

F問題(0/100)

何もわからなかった。通知のタブを見ればよかったらしいが、コンテスト中は一度も訪れなかった。これは誕生日コンテストに参加するものとしては失格。

G問題(42/100)

くそなぞなぞを解く。4問目は東京23区が答えであることがわかるので、全部試した。

H問題(100/100)

変体仮名。このサイトを見て頑張る。

変体仮名を調べる 歴史的仮名書体を探す

2行目は_なりあ_ふ_つのすう_が__いにそで……のように読める。これは復元できて、「隣り合う2つの数字が互いに素で」だ。

あとはエスパーする。1行目にNが、2行目にN項の数列が与えられると決めつけて、隣り合う数が互いに素なペアの個数を数えて出力したら通った。

I問題(0/100)

変体仮名字母だと思って調べてみたのだが、全然埋まらない。自分の考えた読みを当てはめようともしたが、あまりにスカスカだったので放棄した。

J問題(40/300)

Try It OnlineJ言語があるので、それで試しながらやる。最初2つはわかるが、3つ目でボックスが出現してもうわからなくなった。

Try It Online

2つ目の入力がinvalidだったらしく、途中通らずに苦戦していたが、リジャッジされた。

K問題(0/100)

38を出力したが、ダメだった。この38は適当に考えた数値だと思っていたが、思い返せばD問題のスタート地点の番号じゃないか。遠隔操作されている。

L問題(100/100)

入力を調べてみたが、どうやら与えられていないらしい?なんてしているとひらめいた。正という単位がある。

M問題(0/200)

なんも考えてない。

N問題(100/100)

とりあえず絶対値を出力すると、3ケースだけACする。入力はちゃんと数値だけ(.to_i.to_sするともとに戻る)。しばらく考えて、ふと絶対値記号に違和感を覚えて問題文をコピペしてみると、vmatrixだった。これなんだっけ?……行列式1 x 1行列の行列式は要素そのままなので、そのまま出力してAC。

O問題(100/100)

つい最近Twitterで話題になっていた通り、wikipediaオートマトンが書いてあるので、正規表現やるだけ。→RE……。

RubyUTF-8を含む正規表現を書いたのだが、ジャッジの関係でエラーになっていたらしい。すでに解決済みだが、解決する前に通した。

カタカナは.bytesすると3つの数値になるので、3つ区切りにして要素を比較しながらif-elseを書きまくる。「イ」の次に「-」がないのは、一方通行っぽい矢印が書いてあってダメだと考えていたものの、wikipediaの例を見る限り良いらしい。

P問題(0/200)

東京?どこだよそこ。さすがに解ける気がしない。

Q問題(20/200)

スカイツリーだけはわかる。

R問題(120/200)

最後3枚の写真はそれぞれ富山駅、富山城、総曲輪(これは「そうがわ」と読む)のものだ。地元なので無限回訪れたことがある。かなり興奮した。まあ緯度経度を調べるのにミスりまくったんですが……。

最後の写真の場所はここだ。このアーケード好き。でもダイワデパートにここから入ったことはない。

Google マップ

移動しながら撮影していることを鑑みると、電車は高山線だろう。これは利用したことがないが、富山駅に乗り入れている電車で見覚えがないものは逆に高山線に絞られる。これ関係の2つも分かった。

高山には朝市があるので、それを探したが、街灯も橋の形もどうも合わない。あきらめて川の柵だけ合わせ、適当に出したら通った。以上で6つ正解した。

あとから知ったことだが、どうやらストリートビューの写真が撮影されたあとにできた橋と街灯らしい。

S問題(0/100)

問題文からsが削除されているのは分かったが、何をしたらいいのかわからない。解けず。

コンテスト後に聞いた話によれば、ソースコード中からsを削除すればよいらしい。数式に必要なsが抜けているとばっかり思っていた……。

T問題(100/100)

あみだくじを頑張る。画像をダウンロードしたりすると罠があったらしいが、原始人であるところの僕はスクリーンキャプチャをしたので気づかずにACした。

線が適当に書かれていてビビったが、つながっているとしてよいようだ。これも質問タブに明記されていたが、僕は気づいていなかった。半分くらいあみだくじを進めたところで、微妙につながっていない線に気づいて真っ青になった。

U問題(0/200)

なにもしなかった。

V問題(20/200)

equinoxprogrammingだけ。

W問題(140/200)

これ↓をインストールして、含まれる文字を全部表示して目grepした。

フォント「春秋-tsu」|太郎次郎社エディタス

呂官不糸_各上少行阜歩__

X問題(0/100)

なにもしなかった。

Y問題(100/100)

とりあえず出すとWA。詳細を見ると、メッセージで/を使用してはいけないと書かれている。次にRubydivを使って出すと50点。メッセージにはdivを使うと減点と書かれている。

ちゃんと真面目に繰り返し二乗法を引き算でやってAC。

Z問題(100/300)

最初の3問だけ。チェスの特殊な移動を知っていれば、ガチャガチャするだけで解ける。あとは……ナオキです

[問題(10/100)

適当にYesと出力したらメッセージでなんか言われたのでNoと出力したら10点もらえた。

これコンテスト中10点しか見てなかったので10点満点だと思っていたけど、本当は100点満点で、どうやらYesで0点の時に提出の詳細画面から得点をクリックすると自由に値をいじることができて、それで100点にできるらしい。本当に草。

\問題(0/100)

普通に書いて微妙に通らなかったので、あきらめた。逆に11stとか書くのかな、とも考えたけど試さず。

本当は日付を約分するらしい。呆れかえった。

]問題(100/100)

OEISに投げると1件だけヒットするので提出すると微妙に違う。多項式補完してみたが全然ピンとこない。

1,2,5,7,11,15,21,26,32,39 - OEIS

なんだかややこしそうなことを計算している。また、2014年にいくつか間違っている項が修正されたらしい。まだ間違ってるんじゃないの?と思って、WAしたケースのうちn=12を手で構成してみると、1多くなった。提出するとそのケースが通った。マジで草。

それ以上手で計算するのは嫌だったので、ほかのWAのケースも1だけ増やしてみたら全部ACになった。

これ本当にすごい。感動してしまった。メッセージ性すら感じられる。

^問題(0/100)

なにもしなかった。

_問題(200/-135)

問題文には「200点満点です」と書かれているが、問題一覧から見ると-135点満点になっている。よく確認せずに解いた人を罠にはめるいつものやつだろう、と思って、あえてgets putsを提出した。

そのあとしばらくして、この問題で200点を取得する人が増えてきた。あとテストケースが謎に100個もあってジャッジを詰まらせている。不思議に思って提出の詳細を見ると、部分点が細かく設定されている。

多分対応するケースだけ狙い撃ちすることで正の部分点をかき集めると200点満点が得られるのだろう。対応するケースを計算するのは、100ケースもあることだし、何らかのアルゴリズムを適用する必要がある。

よく見ると、負の点数がついた部分点は、対応するテストケースがそれぞれ1つしかない。これを利用すれば燃やす埋めるで解けそうだ。以下解法。

最小カット問題と充足最大化問題 - うさぎ小屋

これに従って解く。まず各テストケースに対応する命題変数を用意した。「真ならば解かない」ことにする。

正の部分点に対しては、まず答えに点数を足しておき、関係する命題変数のどれか1つでも真⇔「必要な問題のどれか1つでも解かない」ならばペナルティを受けると表現する。「または」の形なので表現できる。

負の部分点に対しては、命題変数が真でなければペナルティを受けると表現する。これは関係する命題変数が1つなので表現できる。

これで作ったグラフの最小カットを求めて、先に足しておいた点数と合計すると、見事200になった。あとは残余グラフでsourceから到達不可能な命題変数をリストアップし、それだけechoするようなコードを書いて満点を得た。フローを流すのにはACLを使った。

`問題(0/300)

なにもしなかった。

a問題(116/200)

簡単なものは一瞬だが、わからないものはとことんわからない。7番の「いのうただたか」は言われてみれば納得だが、コンテスト途中は天気図にしか見えていなかった。

最後に7番に「いっしゅう」と提出するとクエストキーを得られたのだが、ジャッジが詰まっていた影響ですでにコンテストが終了してしまっていた。

b問題(30/0)

E問題でクエストについて聞くともらえるやつと、しりとりの「おちば」と「むかで」。

TSG LIVE! 5 ライブコードゴルフ大会 参加記

こういう大会があることは結構昔から知っていて、五月祭に足を運んでは実況を見ていたのですが、今年はなんと外部プレイヤーとして参加するチャンスがあるとのこと!意気揚々と立候補して、無事外部チームの1人として参加できることになりました。

追記:外部チームとして一緒に参加したx20さんの参加記が公開されました!リンクはこちらです。

i-i.hatenablog.jp

また、対戦したTSGチームのうらさんの参加記も公開されました!リンクはこちらです。

n4o847.hatenablog.com

5月にもコードゴルフ大会があって、そちらは東大と京大が合同で開催した、かなり大きな大会でした。僕以外の外部の人も数名参加されていて、たとえばanarchy golfの管理人であるshinhさんもいらっしゃいました。この大会のWriteupはここです↓

第6回東大京大コードゴルフ大会 Writeup · hakatashi/esolang-battle Wiki · GitHub

今回は特にそういった場が設けられているわけではないので、自分が書いたコードについてこのブログ記事をWriteup代わりにします。

問題概要

それ以前のどの数値よりも真に小さいか判定せよ。

入力

2桁の数値が50個、改行区切りで与えられる。入力の末尾には改行が付与される。

出力

与えられた数値それぞれについて、それ以前に与えられた数値のいずれよりも真に小さいとき1、そうでないとき0を出力せよ。

※ちなみに、出力中の空白文字(\s)はすべて無視されます。

制約

  • 同じ数値は2度以上出現しない。
  • 入力の数値は10以上99以下である。
  • 初日については1を出力すること。

C言語(55B)

main(a,p){for(;~scanf("%d",&a);)puts(p>a?p=a,"1":"0");}

初めに手を付けた言語です。最初問題を読み間違えていて、大きいかどうか判定して2回WAを出してしまいました。修正してACし、さらに3度縮めたのが開始6分半のことで、そのあとは誰にも取られませんでした。かなりシンプルなのでこれ以上縮まないと思っています。

強いてテクニックを挙げるなら、pの初期値を設定する代わりに、main関数の第2引数が十分大きいのを期待していることでしょうか。あとは親の顔より見たコード、といった感じに手癖で書けました。

Go言語(87B)

package main
import."fmt"
func main(){p:=100;for{a:=0;Scan(&a);if p>a{p=a};Print(p/a)}}

上にリンクを貼った、以前の大会のWriteupを見て書きました。一応最初の提出から25B縮んでいます。まず出力するのにif文とPrintを2回書くのは明らかに長いので、そこを何とかします。p/aすれば10が得られるので、場合分けがなくなってよさそうです。書いてる最中はGo言語の割り算が整数に切り捨てるか知らなかったのでちょっとドキドキしました。

これは副次的な効果をもたらします。aの初期値として0を入れておけば、Scanに失敗したときにそのままa=0となってp/aがゼロ除算で落ちてくれます。こういう終わり方でもAC判定を得ることができるため、50回のループから無限ループに書き換えることができました。

周りにTSGチームの陣地がないので、一切脅かされませんでした。例えばp:=99にするだけでも(1/90の確率でWAするようになりますが)1B縮みます。Go言語はほとんど使用したことがないので、探せばまだ少し縮むと思います。

Python3(49B→47B)

x=':'
while t:=input():
 if u:=x>t:x=t
 print(+u)

これはTSGチームに縮められてしまいました。ループ内部をx=min(x,t);print(1-(x<t))とすると48Bのようです。ifのせいでインデントが入っているので縮む余地はありそうに見えていたのですが……。

配信アーカイブを見ていて気付きましたが、これで47Bになります。

x=[]
for t in open(0):x+=t,;print(+(min(x)==t))

while t:=input()for t in open(0)になっているのは、同じ長さ(!)なので更新点ではありません。Pythonには配列のminがあるので、以前の最短を特別に保持する必要がなかったようです。この発想は大会中、一切出てきませんでした。

追記

x,r=': '
while t:=input(r):
 if r:=+(x>t):x=t

しーあるさんの改善により、45Bになりました。

GolfScript(27B→16B)

~].99\{[\]$~;.}%\;]zip{~=}%

~]は入力全体を数値の配列にするイディオムです。まず入力が1つの文字列としてスタックに入っているので、~evalして数値に分解し、]で配列にまとめます。[と対応していない]は、公式のドキュメントにも載っている由緒正しい使用方法です。

次に、その配列をdupして、cumminを計算します。苦労しました。mapで実装することにしたのですが、以前の最大値を変数に持つ必要があるように見えます。

mapの仕様がよくわからなかったので、インタプリタの実装を確認しました。スタックサイズを記録したあとに要素をpushしてブロックを実行し、増えた分だけ取り出して新しい配列にしているみたいです。つまり以前の最大値をスタックに残したままやりくりすることができるはずなのですが、なかなかうまくいかず苦労しました。しかしハマっていたのは別のところだったらしく、結局かなりシンプルなコードになりました。

{[\]$~;.}が実行するブロックです。先頭2要素を配列にまとめ、sortしてからdumpし、大きいほうの要素を削除して小さいほうの要素をdupします。このdupされた要素のうち、片方は新しい配列に入れられて、もう片方はスタックに取り残され、次のループに備えます。

cumminする前とした後の配列をzipしたあと、それぞれのペアについて値が等しいかどうかをスタックに積んでいきます。{~=}です。コードが終了するとスタックの中身がすべて出力されるので、明示的に出力を書く必要はないです。

さすがにこんなコードが短い訳がない。ということで書き直しました。16Bです。

~]1\{.[@]$~<\}*;

美しいですね。mapでもeachでもなくfoldを使っているのがポイントで、これで仮の最小値として99を置く必要がなくなりました。代わりに、最初の出力として1を用意しています。

foldするブロックでは、これまでの最小値をa、今見ている要素をbとしてa bの状態で実行が開始されます。dupしてa b b[@]するとこの3つが配列にまとめられます。sortしてdumpするのは同じで、a<bならa b ba>bならb b aになります。後ろ2つの大小比較で0 or 1を作り、先頭の要素は新しい最小値になります。この2つをswapして次のループに備えます。

最後に計算してきた最小値を捨てれば、出力だけがスタックに残り、自動的に出力されます。

Crystal(38B)

x=":"
while a=gets
p x>a ?(x=a;1):0end

GolfScriptを取ったことによって提出できるようになった言語です。これより1B長いものが書きあがって提出しようとしたところ、ほんの1分ほど前にx20さんが全く同一のコードを提出していました。コミュニケーションをとっていなかったため、お互い同じ言語を縮めていることに気づけませんでした。試しに0endの間の改行をなくしてみたところ動いたので、そこで-1Bしました。

CrystalにおいてgetsString? = String or Nilを返します。本来であればこれをStringと比較するとCEになるのですが、whileの条件式に書くことでNilではないという推論が働き、String型になってくれます。

while · GitBook

あとはまあ、Rubyとほとんど一緒です。CharStringが別物のようで、x=?:と書くとCEでした。

><>(45B)

aa*v      ;
i~ >:i:0(?^68*-a*i68*-+:@(:1$-n?~

最後に焦りながら取った言語です。書きあがったのが終了3分前でしたが、提出場所を間違えているのに1分間気づかず、冷や汗を流しました。ほとんどゴルフできていません。例えば文字コードから数値に直す部分など、48を2回引くよりも48*10+48を1回引いたほうがどう考えても短くなります。というかそもそも、比較するだけなので定数を引く必要すらありません。仮の最小値を適切に大きくしておけばよいです。

最初は1行目に処理を書いて2行目で先頭に戻るコードを書いていたのですが、仮の最小値を持つ部分との兼ね合いで処理が2行目に来ました。すると2行目だけでループできることに気づき、先頭に戻る処理を省くことができました。これは数少ないゴルフしたポイントといって良いでしょう。

頭がGolfScriptになっていたので、コマンドの違いに苦労しました。pop;ではなく~dup.ではなく:swap\ではなく$@rotateする方向が逆……。

まとめ

時間中に触れたのは全部、以前に書いたことがある言語でした。意気込みとして「いろんな言語を触る」と言ってはみたものの、時間が圧倒的に足りません……。

RubyPython3が取られたのは、結構ショッキングでした。Ruby三項演算子はただでさえ正しく解釈されるために非自明な空白の入れ方をしないといけない上、_1が絡むといろいろ試すべきことが増えます。今回の短縮はx>_1 ? T:Fと書くと空白が2つ必要になる一方、演算子を逆にして_1<x ?T:Fと書くと1つで済むというものでした。

問題はかなり面白かったです。75分という短い時間でそこそこ盤面を広げるにはちょうどいい難易度でした。盤面を日本地図にするのも、提案されたときは結構度肝を抜かれましたが、何度かアンケートでバランス調整されたこともあってか、特に引っかかることなく楽しめました。(これは外部チームの手を出せるマスが広かったので不自由しなかっただけかもしれませんが……。)

時間がないとは言いましたが、これ以上長くすると配信に影響が出そうなので、触れない言語があったのはしょうがない話です。事前説明で聞いた話では、UnlambdaでもACできるアルゴリズムを開発してはいたそうです。すごすぎます。

大満足の大会でした。共に参加したx20さん、対戦してくださったうらさん、博多市さん、またこのような場を設けてくださったTSGの皆さん、本当にありがとうございました!

週記(2020/09/14-2020/09/20)

09/14(月)

夕方くらいに起きる。今日はHUPC day1だったが、起きた時点で終了していた。悲しいね……。

VimからJuliaを呼び出すやつで1つ、縮められていた。数値を変数に代入していたのだが、これはうまいことすると補完で書ける。補完で書くときは数値が1桁だと単語と認識されずにうまくいかないのだが、数値リテラルの先頭に0を書けばよいらしい。これはRubyなど大体の言語で8進数という意味になると思っていたのだが、Juliaはそうではないらしい。こうして0をくっつけておくと数値が必ず2桁以上になって、補完で呼び出すことができる。

eval"A,B,...="+`dd`.split*?,;c=0というコードは(cが定数変数になることを許せば)eval"A,B,...,C=#{`tr ' \n' ,`}0"に変形できる。

週記(2020/09/07-2020/09/13) - kotatsugameの日記

これはさらに1B縮む。空白と改行をtrの第一引数にしたいが、範囲指定をうまく使うことでエスケープやクオートの必要なしに書ける。例えば文字コード1の文字と文字コード33の文字(これは!のことだ)はどちらもクオートしなくてよいため、' \n'[1]-![1]文字コード1の文字とする)と書ける。これは文字コードでいえば1~33の文字を指定しており、空白(文字コード32)と改行(文字コード10)はどちらも含まれる一方、数値'0'~'9'文字コード48~57であるからどれも含まれず、置換の対象とならない。

これを適用して、先週縮めたものが軒並み-1Bされた。本当にビビった。こういうイディオムで自明な更新点を残してしまうのはかなり危険である。

こどふぉdiv.2があるので、出る。A問題のサンプルが合わない。ちょっと考えてもよくわからなかったし、なんとなく僕ではなくサンプルが違うような気がしたので、B問題に移動して読んでいたところ、アナウンスでA問題に間違いがあることが知らされた。unratedである。

A問題が直って、やはり最初に書いたコードが正しかったことを確認し、提出。B問題も書いて出した。B問題はジャッジが壊れていたらしいが、通った。どういう壊れ方をしていたのかには興味がない。

Eは期待値をmod 998244353で求める問題だ。AtCoderか?なんとなく苦手意識を感じながら、適当に式を作って通す。

Fが全然通っていない一方、Gは結構通されている。これはdiv.2の最終問題だけ解いて終わる人々の影響もあるだろうが、実際にAから解いてF飛ばしてGを通した人も多い。なのでGを読む。結局わからなかったので途中であきらめてしまった。

Gは、数列が与えられるので、その部分列であって各要素がちょうど3回ずつ出現するものの個数を数える問題だ。ハッシュを使うらしい。baseを用意して、ある要素xを数列全体から探して、先頭から1,4,7,...番目にあるものにはbase^x*(-2)、それ以外にはbase^xを対応させると、各要素が3の倍数回ずつ出現する部分列は対応する数の和が0になる。あとは6回以上出現しないように範囲を絞るとよい。なるほど~。

通販サイトで本を購入した。今月出た新刊たちを10冊くらい。しばらくリアルの本屋に行く用事がないことが予想されるため、買っておいたほうが良い。できればリアルの本屋で買いたいと思っていたが、別に品ぞろえが特別良いわけではないし、それほど気にする必要はないかもしれない。

完食した。かなりつらかった。賞味期限は9か月前に切れている。消費速度を上げるため、毎回2食ずつ食べて(飲んで)いた。

Rubyで1000ACを達成した。これで1000ACを達成した言語は6つになった。

明日は昼からオンラインで打ち合わせがあるので、午前6時頃に布団に入る。うっかりハーメルンを開いてしまう。?????

ドハマりして、確か午前11時くらいまで読んでいたはず。さすがにまずいと思って、寝た。

09/15(火)

死ぬほど頑張って13時ごろに目を覚ますと、ちょうど10分くらい前に打ち合わせが始まっていて、メンションが飛んできていた。許容範囲とみなす。自分で打ち合わせの時間を設定したので、一歩間違えればとんでもない無礼者になっていた。すでに無礼者かもしれない。

眠い目をこすってzoomに接続し、しばらく喋る。終わって布団に倒れこみ、昨日から読んでいるハーメルンをしばらく読んで、再入眠。

起きたら午後8時くらいだった。今日はコンテストは何にもないので、ハーメルンを読み切る。日付が変わったあたりで読了。

syosetu.org

昨日から読んでいたのはこれである。評価値ランキングにおいて、現在1位の「このすば*Elona」が登場するまで、ずっと1位に君臨していた作品で、超有名なものだ。

マジで、死ぬほど、面白かった。

作品の存在自体は知っていたが、ハリー・ポッターを読んだのが小学生のころでもうほとんど話の内容を覚えていないということもあり、ちょっと敬遠していたのだが、もうそんなこと関係ないくらい面白かった。

本当に信じられないくらい面白いので、二次創作が地雷じゃない人はぜひ読んでほしい。心の底からおすすめしたい。

終わり方も超きれいで、余韻が強すぎて読み終わった後1時間くらい身動きができなかった。

何とか身を起こしてコンビニに行く。真夜中なので原付に乗っても怖くない。コンビニまで行ってみると、営業が終了していた。6~24時らしい。コロナ許せないな?

帰ってきてパスタを食べ、また寝っ転がってハーメルンを読む。ハリポタ二次創作を探した。

午前6時になったので、再度コンビニに行って、お菓子とサラダとおにぎりとパンを買ってきた。最近全然野菜を食べていないため、ここらで1つテコ入れをする必要がある。

食べ終わって、また布団に寝っ転がったら、寝てしまった。

09/16(水)

起きたら午後3時だった。うつらうつらしながらハーメルンを読んでいると、生協から弁当が届いたので、受け取る。寝過ごさなくてよかったね。

また布団に戻ってハーメルンを読んでいたら、寝落ちしてしまい、次に目を覚ますと午後8時だった。意味不明。寝てしかいない。それもこれも昨日の「ハリー・ポッターと野望の少女」が面白すぎたのが原因で、作中世界からまだ脱出できておらず、全然現実感がないためである。

3年春学期の成績をツイートした。

これはいつもなら8月下旬、成績が出そろうや否やツイートしていたものだが、今回はタイミングを逃してしまっていた。ホスフィンから指摘を受け、投稿。各講義の感想ツイートもできていない。これも指摘を受けたため、今度書く。

よく考えたらHUPCは3日間一回も出れていない。AOJに追加されるのを待ってupsolveしたい。アリーナの方でやるのは何となく気が向かない。

最近全然ACLを書いていない。Rubyを見てみると、最大流・最小費用流が実装されていたので、コードを読んでコメントをした。この際、本家の実装も読解したのだが、現在自分が持っているライブラリとだいたい同じアルゴリズム・実装だったので助かった。

何もしていないのもアレなので、中国剰余定理を実装してプルリクエストを送る。これのverifyには、yukicoderの次の問題を使用した。

yukicoder.me

本来ならgarnerアルゴリズムを使用して、64ビット整数に収まる範囲で計算する必要があるのだが、Rubyなら多倍長整数が使えるため、中国剰余定理のライブラリでそのまま計算できる。modが互いに素になるように正規化する必要もない。

VimからRubyを呼び出すやつで2つ縮められていた。どちらも998244353関連だ。

998244353を補完で呼び出すのだが、たとえば999を入力して補完しても、入力される数値によってはそちらがヒットしてしまうことがある。これを回避する方法が新手。

998244353=2^23*119+1=0x3b800001なので、この16進数の数値を書けばよい。+1Bだが、0を入力して補完することで必ずヒットさせることができる。なぜなら、先頭1文字が0であるような10進数の数値は0以外になく、0は補完にヒットしないからだ。

例のごとくRubyコードの短縮によって片方は取り返したが、もう片方は縮まなさそう。もう諦め気味。

と思って、朝方に寝るつもりでここまでの記事を書いたが、結局そのあとも起き続けていた。徹夜の構えだ。諦めそうになっていたコードも縮んだ。

atcoder.jp

これはたぶん、Vimのほうの更新と言ってよいだろう。削除しつつレジスタに保存するときに、直前の空白も含めるようにする。こうすることで、まずRubyのメソッドpの後ろに空白を挿入せず即座にペーストしてよくなる。このままだと更新にはならないのだが、ほかのところでも空白が役立つ。この空白の存在によって単語がそこで切れていると判断され、文末まで入力した後にBコマンド一回で戻ってこれるようになった。そこでコマンドを一回使用する用事があるのだ。

具体的に言えば、デクリメントをする。<CTRL-O>で使用するとカーソルの位置が単語の後ろまで行ってくれないので、以前は一旦挿入モードから抜けて、デクリメントして、もう一度挿入モードに入っていた。単語がうまく切れてくれたので、そのまま最後まで入力を終えたのちにBしてデクリメントできる。-1Bである。

ニコニコしていたが、別の問題でまだ更新されていた。いつも挿入モード中に<CTRL-R>でペーストしてばかりだったのだが、一旦抜けてPやらpしたほうが短くなる場合もあるようだ。他のコードもこれで縮みそうなものだが、あまり検証していない。

昼前、月曜日に注文していた本が届いた。通販、速い!

下に書いているようなライブラリのテスト作業の合間に、さっそく1冊読んだ。2巻で打ち切りになりそうな気配をビンビン感じている。

競プロライブラリは、これまで手作業でテスト(適当な問題に提出)してたけど、あこがれからonline-judge-verification-helperを導入することにした。ドキュメントがかなりしっかりしているので、よくわかっていない人が良く分かっていないなりに使用するのは全く問題ない。変なことしようとしないしね。

あとファイルの依存関係とかがチェックされていて、テストを作っておけば対応するライブラリを更新しただけでちゃんと必要なだけテストし直してくれるみたいだ。例えば、僕の線形合同式を解くライブラリは内部的に拡張ユークリッドの互除法のライブラリをインクルードしているのだが、この時互除法のほうを更新しても線形合同式のテストが走ってくれた。いやまあそうでないと困るのでそうであるだろうと予想はつくが、まじめにドキュメントを読んだりしていなくて、何回もpushして確かめる方法を取った。

ちなみに、デフォルトの設定ファイルだと毎回NimC#の環境も作ってしまい、テスト時間が1分以上かかっていたが、これはC++使いの僕にはいらないので、ちゃんと設定ファイルをいじっておくべき。何回もテストを走らせた後、設定ファイルのコメントを読んでようやく気づいた。最初に読んでおこうね!

oj-bundleというコマンドを使えば、ライブラリの依存関係を解析してうまく1ファイルにまとめてくれるらしい。これもめちゃくちゃ便利だ。ライブラリの整備意欲がいや増す。とりあえず現在持っているライブラリのテストを書くことにした。

途中学食に行きつつ、いろいろ書いた。とりあえずyosupo judgeにある問題でライブラリそのままの問題は大体書いたと思う。b-フローはよくわからなかった。

Lowlinkのライブラリは、グラフが連結である場合にしか対応していなかったみたいだ。実装の参考にした螺旋本でそうなっていたからだ。これまで一般のグラフに対して橋や関節点を求める機会がなかったの、結構衝撃的だな。確かにほとんど使わないライブラリかもしれない。二重辺連結成分分解のライブラリもこれに依存しているので、こちらも連結グラフに対してしか使ったことがなかったらしい。バグが見つかってよかったね。

結構頑張ってテストを書いたが、いくつかまだ残っている。残っているものはtxtファイルに残して管理してある。前時代的かもしれない。

午後7時に寝る。木曜日は消えるだろう。

09/17(木)

消えた。

09/18(金)

日付が変わったあたりで起きてしまう。起床ツイートをせずにしばらくハーメルンを読んでいた。野望の少女に影響を受けたのと、あとエカスドクィナさんがツイートしていたのを見て、別のハリー・ポッターの二次創作を読んでいる。

ecasd-qina.hatenablog.com

起きて、別のラノベを読んだ。「お隣の天使様にいつの間にか駄目人間にされていた件」の3巻。これ好き!かなりいいので、かなりいい。ふぁぼん氏におすすめされたいくつかの作品との類似性を感じるため、これもふぁぼん氏に教えられたものかと思ったが、違って、確か店頭で惹かれて買い始めたはず。1巻がすでに最高に面白く、続刊を待ちきれなくてなろうの方で当時掲載されていた分を全部読んでしまったことを覚えている。

屋根がない場所で横倒しになった自転車を長期間放置した跡について。

足でこすってみたけど全然消えない。駐輪のマークってこうやって作るんだなあ。

AtCoderへの提出回数が40000回に到達した。つい半年くらい前まではvjudgeの1つに勝っていたはずだったが、最近確認すると1~5すべてに大差をつけられていた。競技人口の増加には勝てない。

1000ACを数える言語が6つもあって、かなり自慢。なんの自慢になるんですか?実際のところratedでまともに使えるのはC++だけである。

yukicoderに出たが、あまりに眠すぎて考えがまとまらない。必死に意識をつなぎとめてデバッグしていた。早めに寝る。

09/19(土)

午前7時くらいに起きて、しばらくハーメルンを読んでいた。1作読み終わった。読み終わったというのは掲載分を読み終わったということであり、この作品は更新が途絶えてしまっている。ネット小説の宿命。

syosetu.org

人は未完の小説を読んだ数だけ強くなる。(適当)

結構面白かったけど、とんでもない場面で更新がストップしているため、読後の精神状態もとんでもないことになった。

今日はACPC day1。ソロ参加行くぜ!したら7完で7位だった。途中解けなくてお布団インしたりしてたけど、それがなくても順位は変わっていなさそう。

AはA問題。BはFAだった。Bみたいなやつはとりあえず書いてから合わせに行くのがいいはずで、これはパソコンを一人で占有できるソロ参加の利点が効きそう。知らんけど。

C、D、Eを解いて、F。フローの流し直しで答えは出そうで、計算量はよくわからないけど書いてから考えよう、ということで書いたら4回もWAを生やした。辺の削除がへたくそだった。そこを直したら通ってびっくり。後から計算量を考えると、毎回探索は1回で済みそうだな、ということが分かった。ちなみにこれにはACLのコードを利用した。辺の情報の書き換えなど必要になるとは思っていなかったため、自分のライブラリでは対応していない。

Gはしばらく考えてもわからなかった。眠くなってきたので布団でゴロゴロしていたら降ってきて解けた。

夜まで頑張って起きて、ABCに参加した。全完3位だった。本番中は双対セグ木を2回貼ったが、どちらも必要なかった。いらないlogをつけてしまったが、AtCoderのTL設定はゆるゆるなので余裕。

コードゴルフもやったけど、よくわからない。これを書いている時点ではB以外の最短コードを保持しているが、Fとかはさすがに縮むだろう。見るからに同じことを2回書いている。とはいえ自分ではどう書くかわからないので、このままにしておく。

AはsedよりVim1B短かった。文字列末尾への追加で差がついた。

こどふぉにレジり損ねたので、眠いし出ないことにする。明日はARC級のコンテストだ。ライブラリの整備などしておきたい気分だが、まあ明日は公式のライブラリを使用するだろう。

ACLFFTがないのは、convolution_llで代用できるからだろうか。けんちょんさんのツイートによれば、FFTよりもconvolution_llNTT3回)のほうが速くなったらしい。にわかには信じがたい。

そういえば、FFTで誤差が出ない10^15くらいの計算をするなら、NTTは2回でよくなるのか。ATC001-CはFFTだが、これは要素の最大値が10^9くらいに収まるので、modを選べばNTT1回で計算できてしまう。ここまでくれば確実にNTTのほうが速いが、2回ならまだしも3回実行するconvolution_llFFTよりも速くなるのか……。いずれ自分で検証してみたい。

ABCの最中、結構強めの眠気が来て困った。ARC級のコンテストの最中にこれが来るのは何としても避けたいため、今日はしっかり寝たい。朝起きてすぐにハーメルンを読み始めるなど言語道断。

09/20(日)

9時ごろ起きて、小説家になろうを読み始めた。ハーメルンじゃないからいいとかそういう話ではなく、眠気をとるためにしっかり二度寝するべきなんだよな。

https://ncode.syosetu.com/n1309m/

連載中になったまま8年経過しているらしく、途中で止まるのか……と思って読み始めたが、本編は完結していた。番外編として短編をいくつか投稿している最中に更新が停止していた。

「上位存在として人間の発展を見守る話」が好きだと宣言していて、これもその一種として読んだ。この作品に限らず一般に、いくら上位存在だからと言って向かうところ敵なしというわけではなく、同格の存在とのバトルシーンがある。物語としては必要な描写であると理解しつつも、ちょっと読んでいて精神に負担がかかる。それだったら主人公最強系をずっと読んでろという話だが。

無職転生」という超有名ななろうの作品があるが、これは同格どころか明確に上の存在にやられる描写がかなりあって、読んでいる途中はものすごく辛かった。しかし全体としてみれば、やられる描写まで含めてとんでもなく面白いという結論になる。物語として必要な描写というのは、そういう意味で言っている。

読み終わったのがちょうど昼頃だった。昨日のF問題がPerlで縮められている。変数の値を変数名に使用するテクで、同じことを2回書かなくてよくなっている。型グロブでさらに縮めることができた。

昼食を食べてACPC day2に参加する。1時間弱で5問解いて、そこから1問も解けなかった。悲しい……。

途中、TSGのオンライン五月祭の配信を視聴していた。コードゴルフの部分だ。明日は僕も外部ゲストとして参加できることになっている。

ここでのゴルフはAtCoderと違い、途中でエラーを吐いてもそこまでの出力でジャッジが行われる。よくあるのは、入力の末尾まで到達したらゼロ除算をして落とす、というものだ。AtCoderでばっかりゴルフしているので、そういう見方が完全に頭からすっぽ抜けていた。ちゃんと覚えておいて明日に生かしたい。

夜、ARC級のコンテストがある。1時間ほど前から緊張してきて、2回もトイレに駆け込んだ。野菜をあんまり食べていないのもあり、おなかの調子が良くない。

実装がバグっていると分かった。issueを立てた。

週記(2020/09/07-2020/09/13) - kotatsugameの日記

これがRTされていたので、調子に乗って説明を加える。mod 998244353で計算しようとして壊れるのは、畳み込む配列の長さの和が2^22を超えだすあたりからなので、実用上問題になることはほとんどない。

コンテストが始まった。結果から書くと、ABCDEの5完で全体24位、パフォーマンス2943を記録した。レートは32上がったが、これはコンテストの手ごたえに比べると少なく感じる。僕のレートが直感より高くて困る。

A問題は3回WAを出してしまった。特に最後の1回はfirstsecondを取り違えていたことによるものだ。これはひどい

B問題も、愚直解と突き合わせるためにコードを書き換えている時間が結構長かったばかりか、デバッグ出力の消し忘れで1WA生やしてしまった。すでにA問題で3回WAを出しているので、あまり気にしなかったように思う。

C問題はもう見るからにフロー。制約も謎に小さい。

D問題はひらめきが冴えわたっていた。まず条件の一部をダブリングで求められることに気づく。場合の数を求めるのは、互いに素な区間の要素の個数を数えることに落ちるので、区間の両端それぞれで和を取って足し引きすればよく、これもダブリングで一緒に計算できる。このことに一瞬で気づけたのがかなり天才的だった。

E問題は期待値の問題。ライブラリコンテストじゃなかったんですか……?何もとっかかりが見えないので、とりあえず愚直に計算しようとしてみる。今回の問題では愚直コードが結構簡単に書けた。O(N^3)だ。ここから高速化を目指す。

まず、一番内側のループは等比数列の和を取っているので、公式に置き換えて消せる。次に、ループごとに値の変わらない変数がたくさんあるので、これをくくり出す。ループの順番を入れ替えることもした。

これでO(N^2)だ。ひとまず提出すると、WAが出なかった。今のところは間違っていないらしい。

最後にもう1回ループを削るのがかなり大変だった。P_iP_jの大小関係に応じて足すのと引くのを入れ替える必要がある。さらに足す数もmaxminが入り混じっていて、分離はかなり面倒そうだ。このあたりで順位表を確認すると、ABCEの人がたくさんいてびっくりする。僕はABCDなので負けている。このままではレートがとんでもないことになる!

面倒そう、との意識からあんまり頭が働かないが、1つずつ場合分けして、ループを分割してmaxminを消していく。最後に、足す数のijを分離して、今jのループを回しているからiのほうをデータ構造で管理して、O(N log N)が完成した。残り5分。サンプルを試す。合わない!BIT区間の右端が1足りていなかった。震える手でもう一度サンプルを試す。答えが合う!ファイルの内容をcatしてクリップボードに入れるだけのコマンドを打つのに、タイプミスを何度かする。残り2分半で提出。ジャッジを待つ間に、ほかに高速化できるところがないか探そうとしたら、ジャッジが爆速で終了した。AC!思わず机をたたいて立ち上がり、部屋を歩き回った。

全体としては、最初のほうの問題でペナを生やしまくっていて全然よくないはずだが、E問題をギリギリでACできたことにかなり影響を受けて、良い結果を残したように感じてしまう。

E問題で必死に高速化をしていたが、そもそも最初に等比数列の和を取ったところで、もう少し計算を進めると1/2になった。いわれてみれば直感的にも納得できるのだが、本番では閉じた式にできたことに満足してしまっていた。

明日は昼からコードゴルフ配信に参加するので、確実に起きる必要がある。最近6時間で起きてばかりだし、生活リズムもちゃんと合わせてあるのでかなり安心できるが、変なタイミングで突然12時間睡眠をキメる癖があるため、用心したい。