/ 最近 .rdf 追記 設定 本棚

脳log[2023-04-04~]



2023年04月04日 (火) 人はこうして見る目を養っていくのだ。あなたは味のしない苺を食べたことがありますか。私は今日初めて食べました(幸運の終わり)。甘くも酸っぱくもない、水だった。おいしくない水だった。赤丸ほっぺのアホづらが見える。クマが憎い。今シーズンはもう終わっていたんだな。■終わった……? 「[B! 果物] 米紙の疑問「日本では、なぜイチゴが冬にとれるのか?」 本当は「春の果物」なのに… | 高すぎる環境負荷と市場のニーズの間で揺れるイチゴ農家


2023年04月03日 (月) [AtCoder] 精進。パ研合宿2022 第2日「パ研杯」-C「Collaboration」。基本的な解答方針はすぐに見える。階差の最小値はセグメント木に聞けばいい。クエリで与えられる2つの範囲の値域が重ならないなら A 列の階差を乗せたセグメント木と B 列の階差を乗せたセグメント木にそれぞれ尋ねて小さい方を答えにする。範囲が重なっているなら加えて A 列と B 列を混ぜてソートした C 列の階差を乗せたセグメント木にも尋ねる。基本的にはこれで答えが出る。なかなか消えない WA の原因は交差する範囲に隣接する(一方の範囲にだけ入っている)要素の取り扱いにあった。それから A 列と B 列に等しい値が存在する場合も C 列内でうまく序列が付けられなくて扱いが難しかった。4WA するあいだに (818 Byte / 2217 ms) だったものが (1196 Byte / 3313 ms over) になり、やっと WA が解消しても TLE だった>提出 #40299812 (TLE×10 / 1331 Byte / 3312 ms) ■提出 #40310343 (AC / 1257 Byte / 2457 ms)。二分探索を省くために前処理することも考えたけど、ローカルで作成した最大ケースでは逆効果だったので二分探索は残してある。逆に二分探索があるから IA/IB というデータが省けた。あとは細々と、&:to_i_1.to_i にしたり、2要素の配列を要素に持つ Hash を2つの Hash に分けたり。蓋を開けてみれば 500 ms の余裕をもっての AC だった。■つぎは day1-H「Attack Survival」への提出 #40291192 が 21 ms over で TLE×1 なのをなんとかしたい。たった 21 ms ではあるけど、ジャッジサーバーで慎重に繰り返し実行してそれでも TLE だったということなので、いじって出し直すと逆に悪化したりする。解答の方針を転換する妙案もなく。


2023年03月31日 (金) [AtCoder] 精進。Sky株式会社プログラミングコンテスト2023(AtCoder Beginner Contest 289)-F「Teleporter Takahashi」(黄 diff)。とにかく取っ掛かりが見つからなかった問題。今日の最初の気付きは X 座標と Y 座標を分離して考えていいのではないかということ。X 座標に限定して考えてみる。グリッドを軸として線対称の位置にしか移動できないので、始点と終点の偶奇が一致していないと絶対に辿り着けないことがわかる。次は1差の2点を順番に使用することで±2単位で移動していけることがわかる。±2という最小単位の移動を繰り返しても許される制約になっていることを確認した。あとはまあ細々(こまごま)と、長方形 R が小さすぎて1差の2点が利用できない場合や、利用できそうに見えて実は始点と一致しているために有効に利用できない場合に注意して。■提出 #40189807 (AC / 781 Byte / 502 ms)。非常に気持ちのいい AC。解けて嬉しい。テストケースがまだ利用できないんだけど、最初の提出 #40189747 が WA×2/TLE×10 だったときは一瞬絶望しかけたよね。サンプル3を通すための 6,7 行目のハック(<<x<<y)が雑だったのと、11 行目の判定が早すぎて 15 行目の前にあるのが良くなかった。たった2要素を得るために 20 万要素の配列を作るのが憚られたので Enumerable#lazy メソッドを初めて使ったよ。■「利用できそうに見えて実は始点と一致しているために有効に利用できない場合に注意して」 嘘だよね。長方形 R に2つきりしかない1差の2点の X 座標(Y 座標)の一方が始点の X 座標(Y 座標)と一致していても±2ずつ移動していけるよね。早とちりで No と答えてる気がするけど、テストケースの甘さに助けられたのか?■まだちょびっとだけ理解が及んでいない部分があるらしい。提出 #40200554 (WA×1)。長方形 R の縦と横の長さを最大限に利用して終点を目指してみたのだけど、1つだけ WA になってしまった。どこに考え漏らしがあるというのか。AC はやはり偶然だったのか。■いいや、大丈夫。完璧だ。提出 #40201186 (AC / 506 Byte / 377 ms)。3行目の SY を SX と間違えていたうっかりミスが 1WA の原因だった。考え漏らしはナシ! 十分に整理して満足のいくスクリプトになった。


2023年03月27日 (月) [AtCoder] 精進。ABC228-E「Integer Sequence Fair」(水 diff)。以前に WA を出している>提出 #36786504 (WA×15)。今日改めて取り組んでみて書いたものが図らずもその WA 解答と一字一句同じだった(違ったのは空行が1つあるかないかだけ)。まるで成長していない……。■提出 #40106188 (AC / 92 Byte / 66 ms)。テストケースを利用しました。どうやら良くなかったのは mod を取った累乗を指数にしてまた累乗を計算したことらしい(mod を取らずに指数にする累乗を計算したら AC と解答不能に分かれたので)。足し算引き算掛け算は mod 付きでも自由にできるけど、割り算はちょっと制限があって、そして累乗もそのままではできないらしい。がちゃがちゃデバッグをやりました。逆元の計算でおなじみフェルマーの小定理があるじゃないですか。勘違いして最初は P-2 を mod にしたのだけど、P-1 にすると具合がいいようだった。だけどときどき間違える。そういうのはだいたい全か無か、P か P-1 か 0 かという違いですよ(「悲しさを考える前にまず m で割った n 個の余りについて考える。(中略)。余りが 0 の項の悲しさが 0 であることに注意して……」)。というわけで 0 に目を付けて P-1 に補正したらうまくいきましたね。こんなんで AC をとっても身にならないね!■「勘違いして最初は P-2 を mod にしたのだけど、P-1 にすると具合がいいようだった。」 勘違いしていたというのが勘違いだったみたいで、モジュラ逆数を計算するなら P-2 乗で間違いない。P-2、P-1、P 乗がそれぞれ 1/A、1、A に対応する雰囲気。


2023年03月26日 (日) [AtCoder] 精進1。昨日あった ABC295-D「Three Days Ago」(緑 diff)。いやあ、これ難しいよ。一日置いてもまだ考えたもんね。組み合わせを考える N^2 の処理が許されないから、右端を決め打って右端にある文字に応じて決まる嬉しい文字列の左端を数えることが許されない。よね?■提出 #40082295 (AC / 116 Byte / 145 ms)。昨日には訪れなかったひらめきはこう。文字列の先頭からの累積で 0-9 の数字の出現数の偶奇を記録する。状態数 1024。そのビットパターンの出現数を記録する。たとえば 10 文字目までの累積でビットパターンが 0b1010011000 になったとする。そしてこれまでに 4 文字目までの累積と 6 文字目までの累積でも同じビットパターンが出現していたとする。すると (l,r) = (4,10),(6,10) が嬉しい文字列としてカウントできる。これって全然明らかではないよ。1文字目からの累積状態を記録していく。数えるのは現在の累積状態と同じ状態の数。知りたいのは区間の状態だけど先頭からの状態と状態を比較する。前回の ABC-G について書いた「根からの距離がわかると2頂点間の距離がわかるか? 「頂点 1 からのパスによって決まる値だけを考えて答えを出していい理由は、たぶん LCA までのパスが相殺されるからとか?」からの連想で、LCA を使って引き算すれば求められる気がした」。これと同じレベルの考察だと思うよ。ABC294-GARC045-C と同じ。でもまあ、解かれたからの緑 diff 下位なんだけど。しかたない、AtCoder には自分を除いて天才しかいない。■■■精進2。ABC232-F「Simple Operations on Sequence」(青 diff)。以前は TLE だった。N≦18 という制約を見て2週間前の精進を思い出す。「順列総当たりが許されない制約(N≦16)だけど、A<B、A>B を区別せずに2回目以降の数え上げがサボれるなら許される」。提出 #40085558 (AC / 1181 ms)。はい、許されました。


2023年03月25日 (土) [AtCoder] 精進。今日あった ABC295-G「Minimum Reachable City」(黄 diff)。有向グラフがあって、最初は1番の頂点を除いて小さい頂点から自身に向かう辺がある。つまり、ある頂点は自分より大きい頂点に向かう複数の辺を持つ可能性がある一方、自身に向かう辺は必ず1つだけある(頂点1を除いて)。制約には書かれていないけどクエリ1において u>v であり、v->a->b->c->d->u という関係があるときに u->v という辺を追加することになる。u から逆辺をたどって v に到達するまでに通る頂点はすべて v に到達可能になり、クエリ2において答えるべき最小の頂点が v になる。辺を順方向に辿るのは行き先が発散して良くないので、クエリ1による変化は行き先が唯ひとつに決まる逆辺を辿って伝える。しかしクエリのたびに逆辺を辿るのでは O(QN) になって TLE が必至。UnionFind のようにグループを管理して、UnionFind の Find 関数のように経路を圧縮したい。■提出 #40061939 (AC / 350 ms)。UnionFind のようにやりました。R=Root, P=Parent, T=Tell, F=Find. ほとんど扱いが同じである R(根)と P(親)を共通化できるかと思ったけど、根へは到達できるのに対して親へはクエリ1が来て T(ell) 関数が呼ばれるまで到達できない違いがあるので分かれている。実は F(ind) 関数はいらないんじゃないかと取り除いてみたりもしたけど、しっかり答えが違ってきてたしかに役に立っているようだった。■D と E と F の精進はまだだよ。詰まってしまった D を後回しにして E にとりかかってそのまま E と心中した結果 A-C の3完だったんだよ。パフォーマンスも新しいレートも知らないよ。G 問題が(事後でも)解けたくらいのごほうびがないとやってられないよ。■なんとなく脳内イメージが 20210902 で解いた ARC056-B「駐車場」に似ている。似ているだけで、共通点があったりヒントにできるかどうかは知らない。たぶん状況の整理が必要な点が似てるんだろう。さっき例にあげた v->u->v という環状構造があるときに、u->b という辺が追加されたらどうか、b->x (ただし x<v) という辺が追加されたらどうか、そして UnionFind がこっそりうまくやるように、すでに環状構造がある2つの連結成分を繋ぐようなクエリ1が来たらどうなるか、を整理する。ああ、だから F(ind) 関数を省くと良くないのはクエリ1の第2引数である飛び先にすでに別の飛び先がある場合があるからだ。それでなくてもクエリ1でショートカットしているからすべての頂点が最終到達点を必ず知っているわけではない(だから F(ind) 関数が必要)。


2023年03月19日 (日) [AtCoder] 今日は ABC294 があった。コンテスト成績証自分のすべての提出。F がほぼ既出の問題(水 diff)だったからなのかは知らないけど、6完でも渋いパフォーマンス。■D 問題「Bank」。この手の、前提知識なしで非効率的ではないデータの持ち方を考えさせる問題好き(賢くて効率的なデータ構造を知識なしで再発明することはもちろんできない)。「Notebook」とか「コンテナの移動」とかも同様。「Simplified Reversi」なんかは工夫した単純なデータの方が BIT を使った場合より log が落とせたりして最高(@chokudai「F問題とても好きな問題なんだけど、データ構造でいくらでも殴れちゃうのが残念……O(N)で解いてみてね><」)。実装しながらもずっと考えていて、検索してみても空振りだったのは、窓口に現れたということをメモする変数の名前。これが一番難しくて頭を使った。適切な名前が付けられたかどうかは知らない。他の人の提出を見て気が付いたけど、数字1つで済ませられるところで自分は配列を2本使う無駄をしてしまっている。■E 問題「2xN Grid」。数字の変わり目を2列で混合してソートして順番に見ていけば一致を数えられる。コンテスト中に不思議なことがあってね、サンプルの3だけ答えが合わないと思って、デバッグプリントを仕込んで数え違いがないかどうか順番に調べていったら手計算と完全に一致していたの。じゃあ自分の問題解釈が間違っているのかと思ってふと見たらサンプルの出力例とプログラムの出力も一致してるの。どこに間違いがあったのか。目か?■F 問題「Sugar Water 2」。「食塩水」とほぼ同じ問題。以前に解いています。「これまで何度も解こうとして解けていなかった問題。(中略) 最終的な濃度を決め打てば各溶液ごとに溶質の過不足が具体的な重さでわかるので……ということでした。」 自分では解けなかったんだね。■G 問題「Distance Queries on a Tree」。やることは難しくない。効率的にどうやるか。HLD の名前を聞いたことはありますよ。コンテスト中は「絶対に初心者でもわかるHL分解/Heavy-Light-Decomposition - Qiita」を読んでお勉強していた。見覚えがあるので以前にも読んだことがあるらしい。具体的な実装方法については知らないまま、同ページによると「かなり重い」らしいですが、雰囲気でまねごとをしてみた。ヌルポみたいなエラーを直せばサンプルが合ったので提出してみたら TLE×18/AC×55 だった。5秒で TLE なのなら頑張るけど 500 秒で TLE なら頑張ってもジャッジに負荷をかけるだけなので考えてしまう。■あ! 部分木のサイズでなく辺の重さで第一子を選んでた! ちょっと待って、修正する。提出 #39886338 (AC / 1797 Byte / 3935 ms)。制限時間ぎりっぎりではあるけど無事 AC でした。■AtCoder Problems に難易度が出たね。F が青 diff 上位なのに対して G が青 diff 下位で逆転している。パフォーマンスが渋いのはこのせいか。G 問題がしっかり崖として聳え立っていれば結果は違った。F 問題について、過去の水 diff が今日の青 diff であるなら、よくいわれる傾向とは逆の結果ということになる。■G 問題。オイラーツアーで解けると何か所かで見たけど解けるイメージがわかなかったので、もうちょっとしつこく考えてみた。オイラーツアーは部分木を一列に連続して並べる方法。辺の重さの変更を部分木にまとめて適用できると何がどうなる? 根からの距離が効率的に更新できる。根からの距離がわかると2頂点間の距離がわかるか? 「頂点 1 からのパスによって決まる値だけを考えて答えを出していい理由は、たぶん LCA までのパスが相殺されるからとか?」からの連想で、LCA を使って引き算すれば求められる気がした。提出 #39906499 (AC / 1407 Byte / 2456 ms)。短く速くなった。しかもバグが .keys 抜けが1つと L[] 抜けが3つだけと実装も素直。根からの距離を BIT で、LCA をダブリングで求めた。根からの距離をセグメント木で管理するなら LCA もセグメント木で求めたらいいと思う。BIT+セグメント木は無駄だし面倒すぎるのでナシ。だってセグメント木は BIT の上位互換でしょ?■提出 #39951562 (TLE×24)。試しにセグメント木で根からの距離の累積和と LCA の両方を管理してみたら派手に TLE だった。累積和は BIT でやる方が軽いのかな。■提出 #39954631 (AC / 3966 ms)。頑張りました。セグメント木にダミーの0番目の要素を入れて添字計算の微調整を省いたり、&:method 形式は Symbol#to_proc が呼ばれるせいなのか知らないけどやや遅いみたいなのでブロックを渡すようにしたり、せっかくセグメント木で累積和を管理しているのだから根からの距離を求めてから LCA を引き算するのでなく LCA からの距離を直接求めたり、オイラーツアーで作成する配列のサイズが 3N くらいになっていたのを節約して 2N に抑えたり。最初の AC だったなんちゃって HLD よりよっぽど厳しい。■モノイドが乗せられるようにまじめに ST クラスを改良したので、クラスを書く時のマイルールを。まずクラス利用者が知りたいであろう public インターフェイスを書いてから部外秘である private メソッドを並べる。public メソッドの中では、最初に呼ばれるであろうコンストラクタ(イニシャライザ)をまず書いて、つぎにアクセサ(読み取りメソッド)を書く。最後に、なくてもいい存在であり有害にもなり得るので書きたくないミューテータ(内部への働きかけ)を書く。クラスはオブジェクトのテンプレートであり、型通りの処理(不変部分)を書く場所だけど、ではオブジェクトのアイデンティティがどこにあるかというとコンストラクタへの引数でありインスタンス変数(メンバ変数)にふるまいを変える固有の値(可変部分)がある。すべてのメソッドがインスタンス変数に依存するべきだというのはそのため。その依存がないならメソッドの置き場所が間違っているサイン。とかとかいうことを考えながらクラスを書いている。あとはまあ名前だよね。よく言われるように名前重要。ソフトウェアという形のないものにはっきりした輪郭を与えるのは名前。適切な名前さえあればその実体をどう実装するかはどうとでもなるしどうでもいい。好きに、うまくやればいい。コーディング対象として適切な抽象に紛れのない輪郭を与える唯一無二の名前を見出すところが決定的に重要(形容詞増し増しで強調しました)。自分が常々疑問なのは、変数名に型名を使うというひとつの典型パターン(var arr = new Array; みたいな)。そりゃね、飼ってる猫が1匹だけならその呼び名はネコでも十分わかりますけどね、それは消去法や文脈でそう判断できるというだけであって、直接的な命名ではない。解釈や判断という余計なステップ、疑問や誤解の入り込む余地がある。クラスではなくインスタンスの、それそのものの本質を掴んだ命名をするのだ。■いやでも適切な命名は文脈に依存するということも言えるんだよな。識別子が機能するためには他と区別するのに十分な長さを必要に応じて使うのでいい。1文字変数を使い切ってから2文字3文字変数を使う、みたいな。ハフマン符号的な。その対極がたぶん Java の説明的で長ったらしい命名で、自分は HTML の p タグとか好きでいっぱい使いたくなる人間だからどちらかといえばアンチ Java なんだな。そのくせ、よそ者として文脈を共有しないで他人が書いたコードを眺めてるときに限って「変数名に型名を使ってる」とかを批判的に見てしまうわけだ。勝手な。


2023年03月16日 (木) Twitter で AtCoder を検索した結果をよく眺めている。このところ @zenn_news の自動ツイートがちょくちょく流れてくる。べつにそのこと自体にどうこうはないのだけど(atcoder-alert に対していうべき言葉がないのと同じように!)、現状がシグナルかノイズかというとほとんどノイズに近い。なんでか考えた。まず、新着記事を紹介するのに更新日の情報はいらない。スクリーンショットが Zenn の統一スタイルでありどのツイートでも代わり映えしない。結局、ユニークなのは著者とタイトルだけなのであり、そこと新着ですよという3点から「○○さんが□□□□という記事を投稿しました」ということだけが知りたいかなと思った。そこが目立たなくなるくらいならタグと更新日はいらない。スクリーンショットも、リンクのクリッカブル範囲を広げる役には立つのかなと思ったけどただの拡大表示だったので、場所を取るだけでどうでもいい。Zenn であることを識別する役には立つかもしれないけど、やっぱり自分にとってそのことに意味はない。■ちょっと前にデザイナーが UI をデザインをするときに何を考えているか、という記事を読んだんだけど、デザイナーは見る人間使う人間のことを徹底的に考えていた。一方で典型的な技術者は情報を取捨選択したり強弱をつけたりせずに羅列して済ませていた。わかりますよ。情報を隠していいことはないし、タグ情報が欲しい人もいるかもしれない。インターネットブラウザがドメイン名を強調したいがためにホストやパスの視認性を下げたときは即座に設定でキャンセルしたし、1時間前とだけ表示された着信履歴に対して「1時間前の特定の時刻の前か後かに意味があるんじゃボケが」と日本語ではあるけどまったく日本向けにローカライズされていない Android のプリインストールアプリに腹が立つ。話を戻すと、データベースビューアならそれで正しい。でも検索結果として他のツイートと混ぜて並べられたとき、何の引っかかりもなく流れてしまう現実がある。検索する人のためにツイートしていないかもしれない。それはそう。なのでいうべき言葉はない。有用ではないけど検索結果を決まった時間で分断してしまうほど大量というわけでもないし、それに対してもできることはない。■読んでみたい記事もあるはずなのに、目には入ってもまったく頭に入ってこないなーと逆に不思議で気になったのでした。そして最近とみに増えたプロモツイートはさすがというか当然というかよくやっている。


2023年03月15日 (水) [AtCoder] 精進。ABC041-D「徒競走」(青 diff)。先月(20230228)にトポロジカルソートがわからんから解けないと書いた問題。どこで手が止まっていたかというと、サンプル3の答えが 10461394944000 とべらぼうな大きさになるにもかかわらず、停止するときに1を返す再帰関数を書いたところ。1ずつ数えて間に合う数ではない。■提出 #39755560 (AC / 237 ms)。すでにゴールしたウサギの集合をキーにしてメモ化再帰をすると何が起こるかというと、前後関係のない無関係なウサギ A と B のどちらが先にゴールしたかという経路情報がいい感じに無視される。順列総当たりが許されない制約(N≦16)だけど、A<B、A>B を区別せずに2回目以降の数え上げがサボれるなら許される。■1つだけ桁違いに速い提出がある>18 ms (#1290069)。45 行目に割り算と掛け算がある(自分は足し算しかしていない)。再帰の停止条件で 1 ではなく順列を数えて返してる。入力の受け取り方も違う。自分があるウサギをキーにして先行ウサギを記録しているところ、逆に後続ウサギをメモしている(とはいえそのことに実質的な違いはないかな)。


2023年03月12日 (日) [AtCoder] 今日あった ARC158 のふりかえり。■A 問題「+3 +5 +7」(茶 diff)。最初にわかるのは、差を2か4単位でしか詰められないから、3数の偶奇がすべて一致していないと揃えられないということ。偶奇が一致していたら、考えやすいように3つの数をすべて2で割っておいた。そうすると1回の操作である要素に1を足し、別の要素に2を足すことになる。1操作あたり3を単位として最大の要素との差が詰まるので、へこんでいる2要素のへこみ具合の和が3の倍数でなければ揃えられない。ここから2つの場合に分かれる。へこんでいる2要素の小さい方に +2、中くらいの方に +1 をしていくのだけど、最小の要素が真ん中の要素に追いつくのが早いか、真ん中の要素が最大の要素に追いつくのが早いか。簡単なのは2要素がへこんだ状態のままお互いの差が詰まる場合。この場合は1操作あたり3の最大効率で全体を均すことができる。一筋縄でいかないのがありがたくもサンプルのいの一番に提示されている、先に2つの要素が並んでしまって1つだけがへこんだ状態になるケース。1要素に +3 することはできないので、2回の操作で3つの要素に(+2+2),(+1+0),(+0+1)することになり、結果的に2操作につき3の効率で差が詰まる。という感じにステップを刻み、泥臭く場合分けをして答えを出した。提出 #39675549 (AC / 269 Byte)。本当はステップも場合分けもまとめられるものはまとめた方が良い。式が3つあればバグは3か所に潜むし、場合分けにより実行パスがテストケースごとに分かれてしまうと、実行されないパスのデバッグ機会が限られてしまう。たとえば、ツイッターでちらりと見かけたんだけど、操作を +0,+1,+2 と見る代わりに -1,+0,+1 と見ることができるらしい。そうすれば2つの場合分けが、まず2要素が並ぶまで次に3要素が並ぶまでの2ステップに共通化できそう(場合分けがステップに変わっただけで減ってないように見えるけど、さっきの提出ではそれぞれの場合で2ステップの処理をしていたので2×2が2に減る見込み)。提出 #39706817 (AC / 194 Byte)。シンプルになった!■B 問題「Sum-Product Ratio」(水 diff)。すべての要素を1以上に限定して考えてみた。分子は3要素の和で、分母が3要素の積。和より積の方が早く大きくなるから、大きい要素を使うほど分子に対する分母の比率が大きくなり、全体として値は小さくなる。逆の場合は大きくなる。本来の問題に戻ると、ここに負の値が加わってきて、さらに正数、負数の個数が3未満だったりして正負混合の場合も考えなければいけない。具体的に考えるよりも最大値最小値を作りうる極端な値(正数の最大最小値、負数の最大最小値)を 12 個まで取り出してきてテキトーに組み合わせることにした。提出 #39678373 (AC)。正直 B 問題の方が A 問題より簡単だった。■C 問題「All Pair Digit Sums」(青 diff)。解けてないよ。繰り上がりをどう処理していいかわからなかった。具体的な組み合わせを考える N^2 が許されない制約だけど、繰り上がりの連鎖は完全に個別の組み合わせに固有なので。組み合わせを考えるにあたり、ある桁について、繰り上がってきた1がある・ないと分かっている集団の内部では、桁の数字で一括りにして計算ができる。案外1の位から順番に繰り上がりの有無で分岐と分裂を繰り返していくと、組み合わせを考えるべき個々の集団は先細りで消えていったりするのかなとムシのいいことを期待したりもして。でもうまく実装できないのでは祈って提出することもできない。足し算をビット演算に分解できないか考えてみたりもしたけど、足し算は消えない。以前に本から抜き出した文が言うように、足し算は強力なのだ。「キャリーの連鎖が単一のビットをその左側にある全ビットに影響させることができるという事実から、広く認識されていない形で、加算を特別強力なデータ操作演算にしている」■■■@2023-03-13 精進。C 問題。kotatsugame さんの動画を見ていたら k 桁目を見ているときにその桁の数字と同時に 10**(k-1) で割った余りを持てばいいと教えてもらった。たとえば A={1234,9876} だとして 10^2 の位に注目しているとき、(2,34),(8,76) を処理対象にする。余りの部分は小数点以下の数字みたいなもの。言われたら、たしかにそれでできそうではあるけど、でも、そういう発想はたぶん待っていても出てこなかっただろうな。提出 #39714388 (AC / 3055 ms)。自分で書き始めたから動画を見るの中断してしまった。3055 ms は他の人の2倍3倍遅い。まだどこか頭を使わずに指を使って数を数えているところがあるみたい。


2023年03月11日 (土) [AtCoder] 精進。今日あった ABC293-E「Geometric Progression」。■最初の提出 #39640397 (RE)。M==1 のときに Integer#pow(M-2,M) は許されない。■2番目の提出 #39640942 (WA×24)。さっきの RE が AC と WA に分かれた。この提出の問題は、M が素数とは限らないのに、だから A-1 と M が互いに素だとは限らないのに、逆元を求めようとしているところ。それと最初の分岐で p X を答えにしているが、正しくは p X%M。■終了後の提出 #39648781 (AC)。mod M の世界で A-1 で割りたいけど A-1 の逆元を掛けることができない。どうするか。以前にやってるんだよな。「L 問題だけが解けずに残っていた。余りをとる M が合成数でなければ 9 の逆元が使えて解けるんだけど」。Ruby なので (A-1)*M が 70 ビットになっても気にしないよ。D 問題で時間を使いすぎて 30 分ちょっとしか使えなかったのも悪かったな。■■■D 問題「Tying Rope」。ロープを分岐なしで繋いでいった結果、輪っかがいくつあるかと直線がいくつあるかを答える問題。それだけの問題。■最初の提出 #39629872 (TLE)。40 分かけてこねこねした謎処理が TLE になりました。■2番目の提出 #39631843 (AC)。その後7分ででっちあげた UnionFind が AC でした。どうして当たり前の問題を当たり前に解けないのか。■心当たりはある。道に迷ったとき、とりあえず引き返せばいいものを、前に進んで知っている道に出ようとする子供だった。来た道通った道を2度通るのは退屈なことだ。ABC292-D「Unicyclic Components」、ABC291-E「Find Permutation」、ABC285-D「Change Usernames」というように似たような見た目の問題が続いていたので、似たような解答を書くのには抵抗がある。それで間違えてりゃ世話がないってもんだけど。■提出 #39651186 (AC)。謎処理でも通しておきました。謎っていうか単に左右のノードをたぐるだけなんだけど、だけど、定型から外れた途端に間違えるんだなあ。■■■@2023-03-14 E 問題の問題名って等比数列の意味だったの? 英語名難しすぎる(等比数列・等比級数が幾何~と呼ばれるためには何かエピソードが求められると思う。三角数……と考えてもみたけど、それはむしろ等差数列に近い)。そうすると A-1 で割るっていうのは等比数列の和の公式の分母にある r-1 (あるいは 1-r) のことだよね、たぶん。自分は A 進数で 111...1 で表される数字を 1000...0 から求めるつもりで式を立てたけど、意外な繋がりがあったもんだ(決してぼんやりしているから意外に感じられるのではない)。■■■@2023-03-14 D 問題に関連して Dancing Links という名前を初めて見たと思ったら、全然別のところでも Knuth 先生の名前とセットで見かけたりして。どうして今日一日だけそんなに有名になったのか。


2023年03月10日 (金) honto って予約注文した本が発売日に届かないどころか発売日に発送すらされないことが常らしく、そこはアマゾンが優れているところなんだよなあ。■@翌日。毎回そうなんだけど、発送メールを確認する前に荷物が到着している。発売日当日は発送メールなし注文状況も発送待ちで、翌日9時前に発送メール。午前に到着。今回はこうだった。メールには「夜間に出荷したご注文は翌日発送扱いとなります」との定型文があるけど、これをどう考えればいいのか。■可能性1。発送メールの通りに発送されたあと2時間で届いた。■可能性2。夜間に出荷され注文ステータスの更新を見逃した。発送メール送信は翌朝に繰り延べられた。翌日発送扱いになるはずだけどヤマトがすっごく頑張って翌午前に届いた。■可能性3。発送メール前日(発売日当日)の日中には出荷・配送されていて、発送メール時点では配達拠点に届いていた。注文ステータスと発送メールが嘘。■さあどれだ。あるいは4番目があるか。■あとね、些細に見えて毎回導線の途切れにひっかかってしまうんだけど、出荷メールから注文履歴に飛べない。そこがすべての起点であるのに。1クリックでヤマトのページで荷物の追跡情報が見られないのも地味に残念。どちらに至らない点があるのかはわからないけど。


2023年03月09日 (木) 今日読み始めた本が『人はどこまで合理的か?』(スティーブン ピンカー) なんだけど、「認知反射テスト」「システム1(ファスト)とシステム2(スロー)の思考」という用語で説明される間違えやすいテストが紹介されている。こういうの。「スマートフォンとケースを1つずつ買うと110ドルになります。スマートフォンの値段はケースの値段より100ドル高いです。ケースの値段はいくらですか?」 110という数字を反射的にキリよく100と10に分けると間違える。こういう問題を 20230203 のときの簡易版職業適性テスト(Gテスト)の検査 C (数理)で見たぞ。残念ながらその手のひっかけは中1のときに散々間違えたあとだ(「100gの水に 5gの NaClを溶かしてできる食塩水の質量パーセント濃度は?」という問いに 5%と答えてしまうおバカな中学一年生でした」)。20230203 のときも実は一度ひっかかったけど逆方向に検算するのが習い性なので(答えを出す前に)訂正できた。以前に「ぶつかってそれではダメだと気がついたら定義に立ち返ってひとつひとつの手順を確かめながらたどるのが方法。ここでは注意が必要だと学習したから立ち止まって確かめることができるというだけで、失敗しないうちや失敗を回避できるようになれば、やっぱり中間を飛躍して答えに飛びつく高速のパターンマッチングの出番だと思う。それが人間の基本で、トライ&エラーで最適化を重ねた結果が思慮や洗練として見えているという気がする」と書いた。2011 年のベストセラーらしい『ファスト&スロー』(ダニエル カーネマン)がすごくおもしろそう。それでね、定型発達であることの不幸は、エラーに遭遇する機会の少なさにあると思うんだ。短絡思考を修正する機会に恵まれていない。■■■@2023-03-11 日本語の話。116 ページから「20世紀前半の哲学者たちはヒュームの論述を深刻に受け止め、道徳的言説が論理に関するものでも経験的事実に関するものではないとしたら、いったいどういう意味があるのだろうかと悩んだ」。さて、この文は道徳的言説が論理に関するものであると仮定しているだろうか、そしてまた、経験的事実に関するものだと仮定しているだろうか。■「~でも~でもない」の形であれば迷いなく論理に関わるものではないし、経験的事実に関わるものでもないと読み取れる。では実際に見られたように「~でも~ではない」の形はどうだろう。自分は意味を変えずに次のように語を補うことができると考えている。「(たとえ)~で(あって)も~ではない」。そう書いてあるのだろうか。同ページの直前の文がこう「確かに道徳的言説は、論理的言説とも経験的言説とも区別しなければならない」。論理的言説と経験的言説はそろって道徳的言説と区別されるべきものだと書いてあるのであり、道徳的言説が仮に論理的言説であっても、というのは話の流れに合わない。「~でも~ではない」をどう読み取れば良かったのだろうか。もとはの違いが大違いなのではないか。