週記(2020/08/31-2020/09/06)

08/31(月)

朝なんとなく起きてしまい、寝られずにしばらく起床報告のツイートをせずなろうを読んでいた。

昼頃ツイッターを眺めると、なんと涼宮ハルヒの新作が発表されていた。もう内容覚えてねえぞ……当然買うけど。僕が涼宮ハルヒを読んだのは中学生のころで、当時すでに現在の最新刊である驚愕が発売されてからしばらく経過していた。調べてみたら驚愕は2011年発売らしい。まさに驚愕だ。

そのあと夜までずっとコードゴルフをし続けていた。Other Contestsもいよいよ大詰め、すでに2019年に開催されたコンテストに突入している。せっかくだし1つ書いておこう。と言ってもこれはOther Contestsのやつではないが。

atcoder.jp

3通りの場合分けは基本的にどう書くか悩ましい。Vimの場合は、3行用意してどの位置にカーソルがあるかで場合分けするのがよいだろう。これは2通りの場合分けを書くときの、SYes Noして{DGDするテクの自然な拡張である。

で、狙った位置にカーソルを持っていくのに苦労した。とりあえず、2回検索コマンドを打つのを短縮したい。1度目は完全一致なので*でよい。2度目は大文字小文字を無視したい。

これは、検索パターンに\cと入れるのがよさそうだ。オプションなど設定している暇はない。*というのを手元で実行してみるとわかるのだが(というかhelpに書いてあるのだが)、結局/\<word\>している。つまりこれをもう一度呼び出して、\cを追記すればよい。

僕は検索パターンやコマンドラインでの履歴呼び出しは上キーを使うことでしかできないものと思っていたのだが、最近<CTRL-P>でできることを知った。これを利用した短縮を見たためだ。結局、/<CTRL-P>\cとすればよいことになる。

で、検索した結果入力に応じてカーソルの位置を3つに分けるため、工夫を凝らす必要がある。最初に書いていたのは、まず下にカーソル移動してヤンク、直上に張り付けて上にカーソル移動することでもとに戻る、というものだ。コマンドで書けばjYPkとなる。

カーソルの位置を確認してみよう。この状態で*と打てば、sameならば2行目に、それ以外は1行目にとどまる。次に/<CTRL-P>\cと打てば、sameまたはcase-insensitiveならば1行下に、differentなら1行目にとどまる。結果、出力に応じてカーソルの位置が3行に分かれる。

行きつ戻りつするのはいかにも長そうだ。コマンドによるカーソル移動は1回でできないだろうか?いくらか試行錯誤して、Ypjができた。先ほどのものと原理は同じだ。検索元の文字列ではないほうを2倍して、あたかもクロマトグラフィーのようにカーソルの位置を分離する。検索は下まで行って失敗すると上に戻るので、1行目を2倍してもよい。

さて、下にばかり検索しているのも芸がない。上方向に検索するコマンドとして、*の対となる#/の対となる?がある。これらを駆使して、何とかコマンドによるカーソル移動をなくしたい。Yした直後にpやらPをすると、どうにもうまくいかない。これは全探索をすれば確かめることができた。なので、1回目の検索と2回目の検索の間でp、またはPすることにしよう。*/pとそれぞれの対になるコマンド、都合2^3通りの組み合わせがあるので、片っ端から試していくと、うまく分かれるものが見つかった。それが上に掲示したコードの内容である。

こちらでもわざわざカーソルの位置を確認することは、面倒になってきたのでしない。

今日で8月が終わることに嘆き悲しんでベッドに身を投げたところ、無事寝落ちした。

09/01(火)

9月である。人はなぜ9月。

寝落ちしたので朝早いころから目を覚ましてしまったのだが、運よく再入眠に成功して、そこそこ満足のいく睡眠ができた。偉い!

午前中はコードゴルフをする。最後は駆け足になってしまったが、無事Other ContestsのAC済問題全てに目を通すことができた。まあ一安心。これで終わりということは当然なくて、一度目を通した箇所を再度見直すことは怠ってはならないため、またABCに逆戻りになるだろう。その前にARC-EFやAGC-BCなどを見るが。

ゲームセンターに行く。明日はアップデートで、いくつかのイベントマップが終了してしまうため、何とか駆け込みで終わらせようとしている。

ひたすらに精度が出ない。至る所で赤が出てしまうため、99AJを狙っているのに全然取れなかった。が、13で2つ99AJが出た。よくわからん。

conflict(斉唱)は序盤のエアーが遅れて同時に6つ出たのだが、最後の謎のトリルがうまかったのか99AJだった。これはかなり奇跡的だ。ラストのエアーをぶんぶん振り回しながらコンボ数をガン見していると、見る見るうちに値が増加して2700に乗ったのは面白かった。赤は27個だったので本当にギリギリだ。AJかつ赤が全体のノーツ数/100個以下であれば、スコアが1009900点を超える、いわゆる99AJになる。

結局イベントマップは終わらなかった。執念でキャラクターだけは全部集めた。

人と会う。卵生みらーじゅ(@asakaakasaka)さんとestis(@estis_jk)さんだ。

タイミングよく(?)前回のABCで優勝していたので、新鮮なネタで場をドッカンドッカン沸かせた。たぶん。ただのイキリである。感染症対策の観点からすれば、場がドッカンドッカン沸くことは望ましくなさそう。

ラーメンを食べた後、そのビルの上階にあるサイゼリヤに移動しておしゃべりをする。感染症対策ヨシ!

サイゼリヤの間違い探しでひとしきり楽しむ。かなり天才的な発見がいくつもあった気がしたのだが、結局9個しか見つからずにインターネッツで答えを検索してしまった。負け犬。

サイゼリヤにはワインがあって、ツイッターで話題が流れてきたこともある。試しに頼んでみる。卵生みらーじゅは飲酒をほとんどしないそうなので微妙な顔をしていたが、その場の雰囲気で押し切ってしまう。振り返ってみればただのアルハラである。

調子に乗って500mlのデカンタを頼む。一口飲んでみるとめちゃめちゃ苦い。自分にはまだこれの良さがわからないため、遠慮なくドリンクバーで割り散らかす。ジンジャーエールがよい、とメニューには書いてあったのだが、目が節穴なのでトニックウォーターを持ってきてしまった。これで割ってもよさそう。舌もバカなので基本何もわからない。苦味は抑えられた。

ピザも頼んで、腹が大爆発して食べられなくなったりしたものの、ひとしきり会話を楽しんで、富山駅で別れた。帰って入浴し、コードゴルフをしようとパソコンの前に座ったあたりで眠気が限界を迎え、お布団にイン。そのまま日記も書かずツイートもせず就寝してしまった。なのでこの日の日記は9/2に書いている。

09/02(水)

朝7時くらいに起きてしまう。眠かったのでもう一度眠りたかったのだが、何となくなろうを読み始めてしまう。

朝ご飯を食べて、再度ベッドに寝っ転がりなろうを読んでいると、待望の眠気がやってきて、再度入眠。しばらくしてお昼ご飯に起こされた。

かなり眠かったのだが何とか起き上がって食べ、いい機会だからと本日の活動を開始する。具体的にはコードゴルフだ。この時になってようやく起床報告ツイートをした。

atgolferを確認してみると、何やらC言語のコードが縮められている。何度か短縮合戦をした結果の、現在の最短を示す。

atcoder.jp

qsortの比較関数を短く書く方法については、このQiita記事を参考にしている。

qiita.com

これの、non-printableな文字を埋め込む部分で更新されたようだ。あとは純粋なコード短縮が1か所あって、都合-9Bであった。

また、これと同様にqsortを用いたコードが最短となっている問題がほかに2つ見つかって、そのうち片方は僕のコードだったので、同様にして縮めておいた。

あまりコードゴルフに身が入らず、youtubeでゆっくり実況を観ていた。実家に来てから回線の悪さなどを理由に視聴を溜めていたシリーズを、一気に最新の動画まで観た。満足。

ノートパソコンの購入に興味があるので、電気屋さんに行って現物を見る。UbuntuにするにしてもWSLで頑張るにしても、オフィスソフトはいらないよなあ、という考えになったので、おそらくこの店では買わないだろう。わざわざ案内してもらった店員さんには申し訳ない気持ちもあるが、そういう人情はパソコンを買う際には必要なさそう。これは僕が大きな買い物に慣れていないだけだ。

その後本屋さんに行って新刊を漁る。前回本屋さんに行ってから2週間経過しているため、いろいろ出ている。前もってチェックしていたものだけ買う。

帰ってきて少しだけコードゴルフをした後、本を2冊読んだ。

09/03(木)

起きてatgolferを確認すると、今日もたくさん取られていた。以前にRubyコードをVimで作ってシェルに流すコードを書いたのだが、それの10**9+7に更新があった。

9回9を挿入した後8回インクリメントすれば1000000007=10**9+7が作れて、1B短い。

思い立ってRubyコードのうち入力が簡単なもの、つまりeval'A,B,...='+`tr ' ' ,`で読み込んでいたものを一通りVimで書いてみると、かなりのコードが縮んでしまった。

その後しばらくすると、<CTRL-O>(挿入モードにいながらコマンドを実行する)を利用してさらにいくらか縮めたコードが提出された。このうちいくつかは、Rubyコードの改善によって縮め返した。

夕食は、日曜日に食べられなかった回転寿司屋さんに行った。

夜、家で縄跳びを見つけたので、少しやってみる。二重跳びに挑戦してみたところ、めちゃめちゃ頑張ってジャンプしないと縄が2回回らなくなっており、連続で跳ぶとすぐに疲れ果ててしまった。

しばらく本を読んだりちょっとだけコードゴルフをし、寝る準備を整えてベッドに入る。そのままなろうを読んでいて、午前4時前くらいにふと思い立ってatgolferを確認すると、今日書いていたVimコードが死ぬほど縮められていた。

!によるシェルコマンド呼び出しの際、コマンドの最初数文字を打った後<Tab>キーを押すことで候補の先頭が補完されるようだ。これを利用して、例えばrubyru<Tab>factorfa<Tab>と書ける。

僕が気づいたときはもうかなり取られているように見えて、パソコンの起動を待ちながら気づくのが遅すぎた……と絶望していたが、今日VimRubyを書くことによって縮めたコードのうちいくらかはまだ更新されていなかったので、焦りながら提出しなおした。

取られてしまったコードたちを何とか取り返したい。Vimの改善は望み薄なので、Rubyコード自体の改善を目指す。対象は4つあった。とりあえずすぐに思いついたもの2個を取り返して、もう2つはしばらく考えていても縮まなかったので、また明日チャレンジすることにする。寝る準備を整えたときは十分に夜中だったのに、もう朝である。

09/04(金)

起きてatgolferを確認すると、Vimでいくつか更新がある。

空白区切りの単語を改行区切りに変換する方法として、2<CTRL-W>vgww:s/ /\r/gがある。しかしこれらは短い代わりに遅く、TLEしてしまう問題が存在した。このとき、!tr \ \\nを使用すれば間に合うということで、これを使うコードがいくつか存在した。

factorコマンドは空白や改行区切りの数値を1つづつ読み取ってくれるため、これを利用することでも空白区切りの単語を改行区切りに変換できるらしい。

昨日、明日考えると言っていた2つのうち、1つをさらに縮めることに成功する。これもRubyコード、というより解法による短縮である。

外出をする。今日もパソコンショップをめぐる。そろそろ仙台に帰るつもりなので、今日で決めたい。

水曜日の時点ではオフィスソフトがついていないものを買おうとしていたが、今日最初に行った店で聞くところによると、オフィスソフトが付属するというのはライセンスがついてくることを指し、別に当該パソコンでなくとも使える、とのことだったので、あまり気にしなくなった。実際にオフィスソフトのライセンスを使う機会が来るかどうかはさておき、消し飛ばすのに比べればはるかにマシという感じ。

ということで3店舗回った。父に買ってもらうのだが、思ったよりお金を出してもらえるらしい。欲を出して、結構性能が良いものを選択した。やっぱり店頭で買おうとするとどれもこれもいい点と悪い点が両方目についてかなり迷ってしまう。大人しくインターネットショップでカスタマイズして購入したほうがよかったのかもしれない。お金を出してもらった挙句終わったことにあれこれ言うのはよくないが。ともあれ、性能が良いものを選択させてもらったので、買ったものについては大満足である。本当にありがたい。

家に帰ってニコニコしながらセットアップをする。windowsの起動は適当に済ませて、Ubuntuのインストールに備える。まず一応リカバリイメージを作っておく。その後Ubuntuのisoイメージをダウンロードしてくるが、これはとんでもない時間がかかってしまった。大体1時間半くらいかけてダウンロードをした。仙台には、以前別のノートパソコンにUbuntuをインストールした時に使用したisoイメージを焼いてあるUSBが存在するが、まさかこの帰省で新しくノートパソコンを買うとは思いもしなかったため、当然持ってきていない。

ようやっとダウンロードが終わって、リカバリイメージとは別のUSBにこれを書き込む。パソコンに刺したまま再起動し、BIOSに入ったが、ここで操作が分からなくなってしまった。USBから起動するためにそれらしいタブに移動したものの、どこにも「USB」という文字が見当たらないのだ。認識していないのかと思い、刺しなおしたり再起動したりいろいろやっていたが、結局調べると「linpus lite」というのがUSBから起動するときのオプションだということが分かった。最初にUSBを刺してBIOSに入ったときはこれが選択されていたのだが、うっかり設定を変えてWindows Boot Managerを選択してしまっていたため、BIOSに入るのに失敗したときもずっとwindowsが起動し続けていた。

その後もRapid Storage Technologyの無効化に失敗したりしていたが、何とか無事Ubuntuをインストールすることに成功。事ここに至ってようやく写真を撮影し、ツイッターに投稿した。当然文面は以下の通り。

プログラミングのための環境を整える。なぜUbuntu、というかLinuxにしているかというと、できるだけAtCoderのジャッジサーバと同じ環境でコードを実行したいからだ。

言語アップデートのスプレッドシートを見ながら、いろいろインストールしていく。と言っても参考にするのはバージョンくらいで、基本はaptまたはsnapで簡単に入れていく。

AtCoder 2019/7 Language Update - Google スプレッドシート

そこそこの回数提出したことがある言語については、すべてインストールしておいた。特にCrystalの処理系を手に入れることができたのは革命的だ。

CrystalはRubyっぽいコンパイル型言語だ。しかしPythonとPyPyみたいにほとんど同じコードが動くなんてことはなく、いろいろ違う。 手元に環境がないし、ググラビリティも低い。旧ジャッジでは、AtCoderのコードテストでコンパイルエラーが表示されなかったため、仕方なく次のサイトで試行錯誤していた。

週記(2020/07/27-2020/08/02) - kotatsugameの日記

あとはdcのバージョンが1.4.1だったのもうれしい。確かこれまでは1.3.95の処理系しか持っていなかったはず。

ところで、このようなことをしている間にもatgolferでは着々と最短コードが取られて行っている。最近全然勝てなくてかなり絶望している。JuliaVimで書いたら縮んだらしい。Juliaは以前よりほとんどbash経由で呼び出すコードが最短だったので、さもありなんと思う。急いで他の物を探し、縮める。

昨日Vimで取られてしまったコードのうち、最後の1個を取り返すことに成功した。これもRubyコードの短縮によるものだ。

結局、Vimではちっとも勝てないが、Rubyでは(まだ)勝てるというだけの話。これまでのRubyの最短コードをVimに移植して、それをさらに縮めているのだから、ほかのRubyコードも腰を据えてじっくり取り組めば縮むということが明らかになってしまった。

09/05(土)

昼前に起きる。今日は仙台に帰る日である。

予定通り、古本屋で買いあさった本をいくらか残してほとんど仙台に送ってもらうことになった。ちなみにまだ全然手を付けていない。で、これの段ボール詰めをしなければならないのに、昼食を食べた後「神様のメモ帳」をずっと読んでいた。これ好き。好きなんだけど読み終わった本ということで実家に送ってしまい、仙台では読めないので、手が伸びてしまった。

結局出発一時間前にようやっと重い腰を上げる。目いっぱい段ボールに詰めると33冊入った。未読のまま富山に残していくのは20冊弱である。

出発前に自室を見渡していると、これが目に入った。

これは科学の甲子園の物販コーナーで買ったものである。それ以来ずっと机の上に鎮座している。かなり人気のある商品だという噂を聞いて、買い物が可能になると即座にダッシュして手に入れた。

仙台に帰る。新幹線はそこそこ人がいる。大宮駅で降りたときは、だいたいどの席の塊にも乗客がいた。3人掛けのシートを1人で使えるのは相変わらずだ。大宮からやまびこに乗ったが、こちらもそこそこの人数がいた。

新幹線の中で「オニキス II」を読んだ。警察小説、だと思う。かなり大仰だったり大時代的だったり形式ばったせりふが多くて微妙に読みづらくはある。

帰ってしばらくコードゴルフをやったりノーパソの設定をちょっと頑張ったりした。snaprubyを入れていたのだが、この状態でnokogiriをインストールするとglibcのバージョンが合っていないようでエラーを吐く。apt-getで入れなおすとうまくいった。最初にsnapを選択したのは、確かsnapで入れるとruby 2.7.1で、apt-getで入れるとruby 2.7.0だったからだと思う。AtCoderruby 2.7.1なので、それに合わせたかったのだ。

09/06(日)

昼、起きる。「池袋ウエストゲートパークXIV」を読んだ。好きなシリーズなのだが、単行本を買う気にはならなくて、文庫化を待っていた。

富山から発送した荷物がもう到着した。段ボール2箱で、1つは昨日用意した本、もう1つは食料品だ。

いそいそと本を本棚に入れようとしたが、棚が足りないように見える。実際には詰め込めば余裕で入るだろうが、とりあえず新品の本だけ入れておいて、古本はむき出しのまま放置することにする。いつか整理するが、それは今ではない。

ずっとコードゴルフをしていた。今はARCを古いものから順に見ている。夜、こどふぉがあるようなので出る。久しぶりだと思っていたけど、別にそんなことはなかった。前回出たのは666回で、667回はdiv.3オンリーだったので、サボってはいない。

3完。Cはかなりちゃんと考察した。まず条件をいろいろ言いかえて、クエリもソートして、データ構造で決めるという感じ。セグメント木上の二分探索はまだ理解していないのでlogを2つつけた……と思いきや、よく見ると使っていたのはBITだった。これの二分探索はライブラリに実装してあるので、いらんlogをつけてしまったと後悔。まあなぜかTLが4secなので、かなり余裕があったが。

コンテスト中にフレンドの順位表を見ると、めちゃめちゃな人数がE問題を解いていてびっくりしてしまった。div.1全体としてはsolved数はちゃんとA~Eの中で最小なので、かなり意味が分からない。問題を見ても全然わからなかったのですっぱり諦めて、その時考えていた問題に戻った。

コンテスト後のTLを見ていると(このTLはタイムラインの略で、少し上で登場したTLはタイムリミットの略だ)、Eは会津合宿2018の1日目の問題で既出らしい。そんなん知らんがな……当時の順位表を見る限り、僕も参加しているが、その問題はコンテスト中のACが出ていない。解説聞いたことも何一つ覚えていない。

3時過ぎにうっかりベッドにダイブしてしまい、そのまま寝落ちしてしまった。なのでこの日の日記は月曜日に書いている。投稿も遅れてしまった。