週記(2020/08/24-2020/08/30)

08/24(月)

スキップした。

08/25(火)

真夜中に一度目を覚ます。この時点では眠気も残っていて二度寝上等だったのに、うっかりatgolferを確認したりして目がギンギンに冴えてしまう。

結局二度寝できず、ベッドで昼までなろうを読んでいた。

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

今期の専門科目の成績が出そろった。全学教育科目の成績はまだ出ていないので、フル単かどうかはそれの結果次第。

水曜日の演習はかなり頑張ってレポートを出していたつもりだったが、結局グループ用問題を2回出さなかったのが響いたのか、Aに留まった(一番上はAAで、実はそれを意識していた)。

8/18にフニャフニャになりながら期末レポートを提出した計算機数学はAAだった。この講義は、Classroomに上がる動画を視聴する形式の講義で、視聴した後フォームに名前を記入して送信することで出席を取っている。

僕はこのフォームを前半6回分しか記入していない。これは別に見なくても送信できるのだが、そういう小賢しいことは好きではないので、潔く諦めていた。これでもAAが来るのは結構謎だ。

なろうを読み切った後、コードゴルフをする。Other Contestsを進めていく。akouryyさんとRubyでバトったりしている間に、ほかの人が別の問題をボコボコ縮めていく。大赤字。

さすがに眠いので、午後10時くらいに寝た。なぜこういうことが書けるかというと、この日の日記は眠すぎて書けなかったので後から書いているからだ。

08/26(水)

午前8時に起きる。かなりまともな生活リズムじゃないか?

全学教育科目の成績が出た。今期はフル単だった。

やっぱオンラインの……講義を……最高やな!

基幹科目は3勝4敗とやっとのことで卒業要件を満たした。本当に興味がない講義なので苦痛だった。嫌すぎて何も学べなかった。

昼ご飯を食べに出かける。富山県立山町のそうめん金龍という店に行った。人がかなり並んでいてびっくりしてしまった。炎天下なので日陰に人々が密集してちょっと危機感を覚える。

ただのそうめんだと思っていたので、家で食べるような感覚で一瞬で平らげてしまった。有名な店なのだからちゃんと味わえばよかった。

上のほうに滝があるらしいので、階段を上って見に行く。

金銭を支払って霊的アイテムを得ることができるが、その支払いの場所に電子マネーQRコードが貼ってあって面白かった。時代って感じだ。

帰ってきてもう一度お出かけする。高校のころまで通っていた公文式を訪問して先生とひとしきりお話をしたりした。

5時間くらい塾に滞在して、帰ってきてatgolferを確認すると、死ぬほど更新が流れてきている。どうやらVimからdcを呼び出すのが強いらしい。

入力をソートする必要があるときは、これまでの感覚だとbashで空白区切りを改行区切りにしたあとsort -nしてdcにパイプで流すことになる。これは結構つらい。そもそも改行区切りの入力を読み込むのはどう書けば短くなるのかわからなくなりがち。

これはVimで書けば解決する。なぜなら、ソートした数列をdcプログラムとして解釈すれば、全要素が積まれた状態になるからだ。さらにループも必要ない場合が多い。回数を数えて+を追加したりすればよい。

絶望してベッドに倒れこんだら寝落ちしてしまった。2時くらいに目を覚まして、コードゴルフを始めたらまた寝られなくなってしまう。結局頑張って切り上げて、5時に再度就寝。

08/27(木)

昼頃起きる。ちょっと眠いが、今日はゲームセンターに出かける日と設定していたので、頑張って起きる。

富山駅まで出て行って、駅前のゲームセンターに行く。昼の電車は1つの座席に1人座っている感じで、そこそこ人がいる。外はクソ暑い。

ゲームインさんしょう富山駅前店につく。プリクラコーナーにはいくらか人がいるようだけど、僕が用があるのはそこではない。音ゲーのフロアに行くと誰もいなくてさすがに笑ってしまう。いつだったかコロナの前あたりにチュウニズムを4台に増やしたとのツイートがあって、楽しみにしていたが、見てみると3台だった。

僕がチュウニズムを始めた頃は2台だった。別の友達はその前からやっていて、その頃はたったの1台しかなかった。2台になっただけでもすごい大きな変化に感じられて、その友達は増えたことを聞いて随分と羨ましがっていたものだったが、今や3台である。4台並んでいるのを見てみたかった気持ちもある。コロナ許せないな……。

しばらくやっていると、徐々に人が増えてくる。みんな制服姿なので、駅前の高校が放課になって集まってきたのだろう。このゲーセンは駅前にたった1軒ということもあり、放課後は学生であふれかえることで有名。コロナ禍にあっても変わらないようだ。というかまだ8月なのにもうどこの高校も始まっているのか?夏休みが短くて大変そう。

実際に3台埋まる時間帯もあったが、待ちが出るほどではなかった。後ろのほうの椅子に何人か座っているのでプレイするか聞いてみたら、別の人の付き添いで座っているだけらしい。帰る直前の時間帯はなんか別の台の周りに5人くらい集まって1人のプレイを見ていた。感染症対策は?

汗だらけになって帰宅。電車の時間ギリギリまでプレイしていたので、駅まで走る羽目になって、車内に駆け込んでしばらくすると腕が汗でびしょびしょになっていた。汚い。

成果としては、Ascension to HeavenでSSSを達成した。帰省の直前に仙台のゲーセンで鳥寸を出していたのだが、これは途中のタップスライドが抜けてしまっていて、手袋があればスライダーの反応する面積を増やせて出せると考えていた。実際のところは、手袋をつけていてもタップスライドにはかなり苦戦したが、何とかひねり出した。

9/2までのイベントマップがたくさんあるが、多すぎて終わらなかった。チュウニズムデュエルは終わらせた。

帰宅してコードゴルフをする。非常に眠いが、何となく止め時を見失って午前4時くらいまでやっていた。

08/28(金)

昼過ぎに起きる。今日も塾に行く。採点のバイトをするのだ。水曜日もやたら長く塾に滞在したのは、話の流れで同じく採点していたからだが、今日は初めからバイト目的で向かう。

6時間くらいやっていた。僕は最後の方まで採点や質問の対応にかなりてんてこ舞いだったのだが、聞くところによると、塾の先生はいつも最後数時間は一人で切り盛りしているらしい。何らかの効率化があるのだろう。僕が生まれる前から塾の先生をやっているのだから、それは、そうだ。

僕が通っていたころとは、生徒の顔ぶれは全然違っていたが、今高校生の人たちには結構見覚えがある人もいる。僕が高校生のころには、彼ら彼女らは小学生だったのだ。時の流れを感じる。

帰ってきてコードゴルフをする。塾に滞在している間に新手が出てめっちゃ縮められている……というようなことは、今日はなかった。atgolferを確認できない時間が続くとかなり精神的なストレスになってつらいことが分かった。

atcoder.jp

文字列の末尾からできるだけ長く回文を取り出して、それの開始位置を答える。

ところで、RubyPerl正規表現は、回文を判定できる。拡張が強い。具体的には、正規表現のパターンで再帰ができるのだ。このこととRubyのマッチングが開始位置を返すことを利用して、上のコードが作れる。実際に回文にマッチするパターンを作ろう。

正規表現 (Ruby 2.7.0 リファレンスマニュアル)

Rubyでは部分式呼び出しというのを使う。親切にも、下のほうに回文を判定するパターンの例が掲載されている。回文を判定できるというのは、それほど偉大なことなのだ。

例はこんな感じ。\A(?<a>|.|(?:(?<b>.)\g<a>\k<b+0>))\z。ここからいじっていく。

まず、文字列の先頭を示すアンカーは題意に合わないので、外す。文字列末尾は\zではなく$にする。\zと違い$は改行の直前にもマッチするので、これで.chopなどが要らず、入力をそのまま使えるようになる。

|.というのは、0文字または任意の1文字にマッチする。ここが再帰の終端条件になっているわけだが、.?でまとめることができる。

(?:は、パフォーマンス向上のために正規表現のグループをキャプチャしないための記法だ。パフォーマンスなど知ったことではないので、外す。よく見たらそもそもこのグループ化は必要なかった。

以上でこんな感じ。(?<a>.?|(?<b>.)\g<a>\k<b+0>)$

?<a>(?<b>はグループに名前を付けている。これはいらない。<a>は1番目のグループなので\g<1>で参照できる。<b>は2番目のグループなので\k<2+0>で参照できる。この+0というのは、パターンで再帰するときに、その再帰レベルの上下でマッチした文字列にアクセスするための記法だ。同じ再帰レベルで2番目のグループ(.)にマッチした文字列を参照している。ただ\k<2>と書くとうまくいかない(このとき実際にどこにマッチしているのかは、仕様をよく知らないためわからないが)。ともかく、\k<2>ではなくk<2+0>と書かなければならない。

これで(.?|(.)\g<1>\k<2+0>)$なるパターンの完成だ。実際に文字列末尾から取れる最長の回文にマッチする。

仕上げのテクニックとして、p gets=~ではなくp`dd`=~とすることでスペースが削れて、上のコードになる。

眠くてガタガタになりながらゴルフしていたら、夜が明けてしまった。寝る。

08/29(土)

起きたら午後5時。ちょっと眠い。

コードゴルフしていたら午後7時くらいになった。かなり眠いが、ここまでくるとABCに確実に出るために必ず起きている必要がある。一度うっかりお布団に転がってしまうが、何とか這い出ることに成功する。

ABC177で初めての優勝をした。

順位表を見たらみんなF問題でWAを生やしている。コンテスト後の感想ツイートを見ていると、どうやら始点が(1,1)固定だと勘違いした人が大量にいたらしい。それは100点問題。

あとAのFAも取った。入力順序がdcに優しい。具体的には、3つ数値を読み込んだら後の2つを掛けて1つ目と大小比較する。これは読み込んだままスタックの順序をいじることなく行えて、美しい。

優勝したとのツイートをしたらかなりいいねが来た。この際だからもう少しイキっておこうとして、全完する前にコードゴルフをしている提出一覧の画像を張り付けておいた。ちなみにここで縮めたコードはコンテスト後に取られた。

FHC Round 2がある。1問以上解いたらTシャツがもらえて、上位200人がRound 3に進めるらしい。

1問目はかなり自明。意気揚々と2問目に進んだが、2時間くらい考えて結局解けなかった。そうこうしているうちに200位ボーダーが3完になったので、諦める。結局1完。Tシャツはもらえた。

ABCのコードゴルフの話をする。D問題はUFで連結成分を管理し、そのサイズの最大値を答える問題。Perlで実装すると121Bになった。

この過程で以前に書いた似たようなコードが縮んだので満足していたら、Pythonnetworkxで縮められた。connected_componentsというそのものズバリな関数がある。

かなり悔しいので、グラフを構築した後DFSして連結成分のサイズを計算する方針で、もう一度Perlで書いてみた。95Bになって最高。今度こそもういいだろ、としばらく別のことをしていたら、自明な更新があって-1Bされた。mapforに直すやつだ。

グラフ読み取りまで含めて1つの式に収まっていることに気づかなかった。グラフ読み取りを含めたコードで、mapforに直して縮むコードというのはとんと記憶にない。

atcoder.jp

かなりシンプル。入力される曜日をそれぞれ次の曜日にして出力する問題だが、これはdateコマンドの+%aフォーマットできれいに書ける。

-dオプションで曜日を指定し、さらにその次の日を参照する。それは-dday\ Friなどと書いていたが、-dday-Friで良いらしい。info dateとか読んでみたけど、どういう解釈をされているのかわかっていないので、縮む余地があるかもしれない。

元の最短コードはxargsで入力を1つずつdateコマンドのオプションの途中に挟んでいたが、オプションの順番をいじれば挿入する位置を最後に持ってこれる。こうなってしまえばsedが最も短くかけて、各行の先頭にdateコマンドとオプションを付け加えてシェルコマンドとしてevalすればよい。

さらに、1行目においてはdateコマンドがオプションの解釈に失敗して何も出力せずエラーを吐くため、わざわざ読み飛ばす必要もなくなった。

08/30(日)

午後4時前に起きる。結構眠気が残っていたが、二度寝できなかったので諦めて起きる。

「うちの脳内コンピューターが俺を勝たせようとしてくる」という、ハーメルンでランキングにも載った「りゅうおうのおしごと!」のオリ主二次創作がある。かなり好きな作品だったので毎日更新を楽しみにしていたが、最近完結した。これが非公開になっていることに気付いて愕然とする。何があったのだろう。作者の活動報告には特に何も書いていないのだが……。いつかのために、ここにリンクを貼っておこう。

ハーメルン - SS・小説投稿サイト-

作者名で検索すると(これも結局Google検索から辛うじて見えるキャッシュに頼る羽目になった)小説家になろうのほうでも書いているらしい。作者さんのマイページも貼っておく。

https://mypage.syosetu.com/763216/

夕食は外に食べに行くことになった。近所の回転寿司屋さんに行くと受付が終了していた。コロナ許せないな。仕方なく足を延ばして焼肉屋さんに行く。父は完全に寿司の気分だったとボヤいていた。

帰ってきてしばらくコードゴルフをした。昨日「グラフ読み取りを含めたコードで、mapforに直して縮むコードというのはとんと記憶にない。」などと書いていたが、見つけてしまった。記憶にないのは見たことがないのではなく僕が忘れていただけ。

実際のところ、長く覚えている最短コードなんてのはかなり限られている。さらに言語アップデートからこちら大変な数のコードが更新されたので、昔のものを覚えていてもしょうがない。しかし、最短コードで使用した解法や発想などをぼんやりとでも覚えておけば、たいていは同じコードを再現できる、と自負している。

こどふぉに出る。なんだか眠気がすごいのでちょっとためらったが、今回は記念すべき第666回らしいので、参加することに決めた。

Bの題意を把握するのが遅く、さらにCで5WA出してすべてが終了した。システスはすべて通ったが、そもそも落ちている人がほとんどおらずレートは-68。悲しいね。2400台に戻ってしまった。IGMになれる日はいつ来るのだろうか。もしかして精進しないとレートは上がらないのか?

それにしてもあまりに眠いので、日記を早めに書き上げることにした。この後すぐ寝るかはわからない。

今週の記事の文字数は少な目だが、これはコードゴルフの解説を全然挟んでいないからだ。最短を取られすぎて虚無になってしまった。