/ 最近 .rdf 追記 設定 本棚

脳log[2025-09-30~]



2025年09月30日 (火) 初耳単語2つ。添え乳(そえぢ)。貰い乳(もらいぢ/もらいぢち/もらいちち)。乳を単にチと読むのはそういえば乳飲み子(ちのみご)もそうだった。あれ、乳首(ちくび)もそうか。乳(ちち)というとき自分は白い液体とそれを分泌する胸部を区別してないけど、本来は液体の方だよなーと思って辞書を引くと、(1)が液体で(2)が胸部で予想通り。そこから(3)旗・幕・羽織などの縁につけた、竿やひもを通すための小さな輪、(4)釣鐘の表面にある、いぼ状の突起、と続くのが予想外。(3)に関連しそうな乳環という単語は見たことあるなと思ったけど、これはカーサスの乳環というダークソウル3に出てくる指輪の名称だった。乳環からのつながりで貫乳(カンニュウ。陶磁器の釉(うわぐすり)の表面に現れた細かいひび)と乾乳(カラチチ。乳汁の出ない乳房。また、その女)を発見した。乳という文字が喚起する全体像を自分はまだまだ知らない。


2025年09月21日 (日) [AtCoder] 精進。昨日あった AtCoder × Engineer Guild オンサイトコンテスト ~集結!高レート人材~予選(ABC424)-E「Cut in Half」。K と X の上限の高さに対処する問題。問題に二等分と書いてあるからじゃないけど二分探索を考えた。何を? たとえば長さの上限を探索するとしたら……Ai を何回二等分する必要があるかがわかって、何回倍々に本数が増えるかがわかるので、増えた本数の総数が N+K を超えたかどうかで判断できる。ところで、倍々はビットシフトで計算できるけど半分半分を右シフトでやると小数部分が計算できない。右シフトして消えたはずの部分も固定小数点数みたいに保持したらソートできるかなと考えたりもしたけど、答えが小数なのだから半分半分は小数で計算することにした。自分の解答で探索する上限がストレートに長さの上限(小数)ではなくビット長の上限なのは、思考の回り道の名残か。小数を引数にした2の累乗が普通に計算できると知らなかったことも理由にある。■提出 #69507299 (WA×21/AC×15)。時間内の提出は WA だった。ミスが2つある。■提出 #69515602 (WA×2/AC×34)。1つ目のミスを修正したら WA が2つまで減った。差分は何か。倍々に増えていく棒がぎりぎり N+K を超えないボーダーを探索したあと、ちょうど N+K 本になるように長い棒から半分にしていくシミュレーション部分で慎重さを欠いていた。同じ長さの棒について何本まで折るかという判断をせずに全部折るか全部折らないかで判断していた。ちょっとくらい N+K 本を超えてもええやろの精神。あとで X 番目を数えるのだからダメです。■提出 #69515755 (AC)。2つ目のミスを修正したら AC。18 行目に長さ a の棒を半分半分にして倍々になった本数をカウントする処理があるけど、a よりも探索した上限が大きい場合は手を加えずそのままの a を1本計上するのが正しい。ビットシフトで計算する本数にはシフト数が負にならないようにリミットがかけられていたけど、a の値を増やしてしまうかのような逆二分割を防ぐリミットがなかった。こんなんでは D 問題に費やして無駄になった1時間があっても時間内に AC できたかは怪しい。■提出 #69518302 (AC / 2000 ms)。一番最初に考えたプライオリティキューを使ったシミュレーションは K の大きさを見てすぐに捨てたのだけど、実は倍々で増えていく同じ長さの棒をまとめて操作できるので K の大きさはそれほど問題ではなかったのだった。これは 10 分で書けてバグもなかった。しかし実行時間が2秒ピッタリ! 制限時間は長めの3秒かなと確かめてみたら2秒! プライオリティキューにソート済みの配列を渡して初期化しているのだけど、これが空のキューに1つずつ追加していくようになっていたら間違いなく TLE だったね。Ruby だと想定解法が通らない通っても記述の違い定数倍の違いでふるいにかけられる最近の AtCoder の制約は今回も精度が高い。高精度で確実に Ruby を締め出してくる。何が想定解法かこの E 問題に関しては知りませんが。■■■F 問題「Adding Chords」。セグメント木だと見かけたので何を乗せるのか考えた。提出 #69576332 (AC / 533 Byte / 812 ms)。使ったのは BIT。線分同士の関係は何が許容されているか。交差はダメ。隣接と包含は OK。1本の線分は円を左右2つの領域に分ける。領域の境界をまたぐように新たな線分を引くことができない。しかし同一領域内に新たな線分を引くことはできる。2本の線分が作る4個の領域の関係は? 一方が一方を含んでいるか交わらないかのどちらか。BIT で領域のスタックを管理する。新しく線分を引きたいとき、始点と終点の土台が構成を同じくする領域のスタックであれば既存の線分と交差なく線が引ける。領域をどのように表現し重なり合った構成を区別するか。1領域に1ビットを割り当てるとあらゆる重なりが区別できるけど、N ビットは大きすぎる。大きな素数で割った余りを領域の ID とし、(領域 A)+(領域 B) が (領域 C)+(領域 D) とたまたま一致する偶然が起こらないことに期待した。前々回の ABC422-E「Colinear」に関連して「確率的な操作を書いたことがない」と書いたけどあれは嘘だ。ローリングハッシュを2回くらい書いて提出したことがある (z-algorithm が理解できないので必ずロリハになる)。


2025年09月19日 (金) 「大動脈解離」と言う病気を、専門医が子どもから医師まで5段階に分けて140文字以内で説明した投稿が分かりやすい - Togetter [トゥギャッター]」■初めて名前以外の具体的なことを聞きました。剥がれる裂けるって何が? 3層ある血管の最も内側が裂けて内側の外側に血が流れ込んでいる状態。最も内側の血管壁がダメージを受けている。その結果1層減った2層で血圧に耐えていて(中膜が2層に裂けると書いてあるから 1.5 層かも)、血管から血が噴き出すまでのカウントダウンが進んでいる。また、変なところに流れ込んだせいで主要な枝への血流がバイパスされれば臓器が死にかけている。3つ目の致死要因である心タンポナーデというのは心臓を包む膜の中にたまった液体が心臓の働きを阻害している状態らしいが、大動脈解離からどう繋がるのかはまだイメージできていない(どこからどのように流れ込むのか、すでに破滅が訪れた後というわけではないのでしょう?)。A 型って何? 解離の部位によって深刻度がかなり違う。上行大動脈がスタンフォード A 型で下行大動脈がスタンフォード B 型。上行というのは左心室から出てすぐの頭の方に向かっている部分のことで、下行というのはそこから折り返したあとの胸部腹部にある部分のことらしい。心臓に近い A 型がより起こりやすくより深刻だというのは負荷を考えればまあそうか。まず半数以上が生きて病院にたどり着かないし、治療が遅れると遅れただけ、1 時間に 1 % ずつ2日(48時間)で半分が死ぬ。こちらのページも参考にした。「大動脈解離が起こるとその生存率は?(前編) - 高齢者の病気いろは」 とにかく手術をして血管を補強するのが A 型で、B 型はまずは内科的治療が主だとか。


2025年09月18日 (木) 自分の(初&現)スマホが Xperia 10 (初代) なので。「ニュースリリース | 「即撮りボタン」を搭載したスマートフォン『Xperia 10 VII』を商品化」■ニュースサイトを見てからリリースまでさかのぼっても同じ表現で困惑しているのだけど、「発売されたタイミングから起算して最大4回、最新OSへのバージョンアップが適用されます。適用回数は購入タイミングによって異なります。 」が意味わからん。後半はわかるよ、買うのが発売後しばらく経ってからだと購入時点ですでにアップデート済みだったりするのでしょう。わからないのが「最大4回」の部分。これは何も保証してないよね。「6年間のセキュリティアップデート※8と最大4回のOSバージョンアップ※9に対応し、長く愛用できます」とあるけど、アップデート回数の上限を定めることと長く使えることが繋がらない。好意的に不確かな解釈をするなら、6年間セキュリティアップデートをします、その間に OS アップデートがあれば4回までに限って対応します、ともかく6年間は安心して使用できる環境を提供します、という意味なのかなと思うけど、不確かだ。だって6年間はセキュリティアップデートに関する言及であって、OS アップデートへの言及ではないからだ(注を読めば何が何を修飾しているか区別がはっきりする)。1年目に OS アップデートがあってそれに対応しなくてもリリースは嘘にならない。最大4回は3回や2回や1回はもちろん0回も含むのだから。「最大4回」と宣言されてもこちらとしては何の意味もなさない。後でアップデートをサボったときの言い訳に使えるというそちら側にとっての意味しかない。それが本意ではないなら日本語と論理を学んでくれ。■「※8 発売されたタイミングから起算して最長6年間、セキュリティアップデートが適用されます」 あらためて読めばセキュリティアップデートも最短6年間が保証されているわけではなかったな。最長6年と言わず最長100年とはったりを効かせてくれても意味がないという点で変わりがないので全然かまわへんかってんで。こちらにとって有益な意味を込めたのなら、伝わるように日本語と論理を学んでくれ。勝手に都合のいいように解釈したら詐欺に遭うのが今の世の中だ。


2025年09月15日 (月) 『ホロウナイト シルクソング』をプレイしている。前作はエクストラステージやエクストラボスまで全部やったけど、それでも今作は難しい。それも良くない難しさ。延々と続く下段切りジャンプ。いつまでも死なない敵。複数で押し寄せてきて接触ダメージで削られる。ふわふわとこちらのレンジ外を漂い一方的になぶられる。当たり前にできてほしいことを補うだけのアクセサリ。常にストレスをかけられ続けていて忍耐力を試されている気分。俺はもちろんブチギレて PS5 の電源を切る。でも次はうまくできる気がしてすぐにまた始めてしまう。で、ブチギレですよ。それでもなんだかんだ進捗はある。序盤はまったくたまらなかったロザリーもいまは使い道がなくて余っている(代わりに破片が足りないが破片は無限に掘れる。じゃあなんで消費制にした?)。序盤は地図買えない地図に情報が足りないベンチ使えない駅使えない攻略しているエリアの敵がロザリーを落とさないマップで拾ったなけなしのロザリーを死んでロストするでひどかった。いろいろとやりすぎてるんだよな。エクストラステージや闘技場はおまけだからそれでいいのに、開発者がプレイヤーのいじめ方を知りすぎている弊害。ホーネットはかわいい(設定で声を消したりはしない)。アートワークもいい。音楽も音響効果もすばらしい。音が吸い込まれる地形、逆によく反響する(くだ)の中など、臨場感を大いに増している。多くのキャラクターが自然に歌とともにあるのも、とてもごきげんでとてもいい。でも不利なルール不利な状況でなぶられてなにがおもしろいん? こっちは気絶してひっくり返ってる大型の敵に触れるだけで2ダメージなんよ(こちらのライフは1増えて6)。それにプラスして小型の敵中型の敵がふわふわふわふわと迫ってきたらなにができる? なにがおもしろいん? (ブチギレて今はネットをしているらしい)■L1 2回押しでエリアをまたいだマップが表示されるの便利だよ。■漢数字の「二」を使うべきところでカタカナの「ニ」を使っているらしいところが少なくとも2か所あったと思う。同じ画面内の「三」(明朝体)にはあった止めの三角(うろこ、serif)がなかったので、カタカナだったのではないかと。■■■DualSense の左スティックが壊れました。ある瞬間にぬるっと滑る感触があって、以降はずっと軸がぬるぬる回転する。これはかなり深刻で、スティックを倒し続けていたいのにぬるっと指がスティックの向こう側に行きすぎてしまいそうになる。原因はスティックの頭にかぶせてあるゴムキャップの固定が外れたことみたい。親指の腹を乗せる部分に浮きがあるなと思っていた。爪でゴムを剥がしてプラスチックをむき出しにしたらぬるぬるするよりずっと使いやすい。買い直すと1万円以上するからこれでいいや。DualSense Edge だとスティック部分だけ簡単に交換できるし値段も 2500 円程度なんだけど、コントローラー自体が3万円するので追加ボタンがあったりキーマップの切り替えができたりするらしいとはいえありえない高さだと思う。重くてバッテリー持ちの悪い高級コントローラーを望んだことはない。軽くてバッテリーフリーモーターフリーのチープなコントローラーの選択肢があってもいいと思う。実は原因が明らかになる前にコントローラーを分解していた。スティックを抜き取って初めてゴムキャップが滑っていることに気がついた。使用頻度を考えて右スティックと左スティックを入れ替えてゴムなしの方を右スティックにしてますよ。分解するときにマイク付近のフレキシブルケーブルをちぎってしまったくさいので、たぶんマイクが使えない(まだ具体的な不具合には直面していない)。■■■第2章に入ってから印象が変わってきた。ボスを後回しにしてあちこち探索できるし、アクセサリがそろってきて場面に合わせて最適化できるし、アクションの幅が広がって敵に対処もしやすい。ライフと糸巻きは初期から3つか4つ増えた。どうして1章がこうではなかったんだ。■■■@2025-10-25 第3章、達成率99%、残りは漆黒のレースと記憶のロケット(1個どこ?)といくつかのメメントだけという状態。2章は明らかに1章よりぬるかった。倒せないボスも釘を強化して再挑戦したらなんとかなった。3章でもやっぱりフィールドアスレチックはやりすぎで、フラストレーションがたまる場面があったけど、後回しにして他のマップの探索をしてホーネットを強化する選択肢があったのが1章との違い。印象的なボスが多かった。一番好きなのは踊り子のカーメリタ。押し引きする敵の動きに対応して攻撃を加えるホーネットの動きは、カーメリタと一緒になって踊っているかのようで、つまりプレイヤーがまんまと踊らされているというわけで、見事にデザインされた攻撃モーションだったと思う。楽しかった。劇場のドロッピオも印象に残っている。あいだを空けて2回戦ったのだけど、初回撃破時の芝居気たっぷりのやられモーションを見て、あ、こいつは殺しても死なねーやつだな、絶対また出てきて戦うなと思ったもので、果たしてその通りになったのだった。2回目の撃破時もやはり死ななかった。シルクの憤怒をくれる最初の罪に問われし者も、いっぱい死んだし釘を強化してからやっと倒したけど、無理という感じはしないし挑戦しがいがあった。実はぼうっと立っている時間が長くて攻撃チャンスがいっぱいあって、見かけ倒し疑惑がある。ワープ直後にフックショットで距離を詰めるとしばき放題なんだよね。体力が多いだけ疑惑。あとシルクがたまりやすいのかな。それもあって戦い易さがある。反対に3章から出てくる黒く染まった敵はしばいてもシルクが貯まらないし逆に手持ちのシルクを溶かしてくるので非常に戦いにくかった。でもこの敵がいたから、2章で十分強化したホーネットでも3章のマップを緊張感を持って再探索できたのであって、作業感なく変わってしまったファールームの様子を確かめてまわることができたのだった。胆液の沼には絶対に近寄らなかったけども。アスレチックは二度とやりたくないけど、それ以外、特にボスは、緑の王子も良かったし、印象に残る個性的なボスがよく作り込まれていた。ホロウナイトは2周くらいしたけど、シルクソングは二度とやらない。もし1年後に気の迷いを起こしてもすぐに後悔してやめると思う。


2025年09月14日 (日) [AtCoder] 精進。今日あった ABC423-E「Sum of Subarrays」。累積和3つと累積和の累積和1つで解いたけど、絶対何か無駄な回り道をしてると思うんだよね。提出 #69368469 (AC / 1424 Byte / 662 ms)。■いろんな累積和という意味で印象に残ってるのは ABC338-G「evall」。たぶん言及するのはこれで3回目。E 問題を累積和でやると決めてから、求めるものがストレートには得られないので区間の始点と終点を分類し包除を考え累積和を組み合わせ1時間以上のあいだに何度も頭を抱えたことをふまえると、G 問題の方が難しかったとは言えない。ただ、適切な道具を適切に組み合わせればすっきり解けるのではないか、無駄にこねくりまわして自分で問題を複雑にしているのではないかという懸念はある。■どうやら累積和が3つで解けるみたい?■■■F 問題「Loud Cicada」。累積和と累積和の逆という説明と図がわかりやすいこちらのツイート「フェネック「このメビウス変換っていうのはゼータ変換の逆のことで、ゼータ変換っていうのは累積和をとることだねー。例えばセミ1,2,3がいたとき「少なくともセミ1,2が発生」は「1,2が発生+1,2,3が発生」っていう"累積和"をとった状態だから、それを戻してるよ」」を参考にして書いたものはサンプルが合うものの N=20 の最大ケースで数分かかってしまった。累積和の逆を計算するときに各要素ごとに添字の補集合の部分集合を列挙しているのが良くないのだと思う。うまい計算手順があるのだろうか(ゼータ変換、メビウス変換について調べない)。■E 問題。累積和3つがどのようにして導かれるか。「アライグマ「求めたいのはΣ(A[x]×(x-Li+1)×(Ri-x+1))だから、xxA[x],xA[x],A[x]の累積和を求めておけばO(1)で計算できるのだ! この問題に1点変更クエリもありにしたのがだいたいABC256Fと同じなのだ!」」 おかしいな、簡単な問題に見えるぞ。


2025年09月08日 (月) 信号無視をした話。■渋滞している道路を走っていて赤信号で自分が先頭になった。その少し前、そろそろ赤になるな自分は抜けられないなと思っていたときにどこかから救急車の音が聞こえてきて、ミラーに赤色灯が見えたので後ろから来ているとわかった。なので一応左端に寄りつつ、赤信号なので停止線で止まった。ミラーで車体が確認できるくらい、救急車はたぶん4、5台後ろまで近づいてきていた。右車線はあいにくとダンプが3台連なっている。そもそも工事をしていて車線が減っているから渋滞しているという背景がある。ダンプも渋滞も偶然ではない。救急車は右折レーンに入って抜けようとしたようだけど、中央分離帯に寄ってあいだを開けようとしたダンプと動きがかぶって進路を塞がれたかたち。自分の直後の車は今になって左端に寄ろうとしている。しかし前が詰まっていて思うように寄れない。さあどうする? 交差点に車の動きはない。サイレンの音が聞こえているからか歩車分離で歩行者信号のみが青だったからかは確認していないので知らない。普通のドライバーは赤信号を安全に無視するためにどこに注意を向けるべきか知らない。とにかく交差点は空いていた。横断する勇気はないので左端に寄ったまま交差点に進入して、そこで止まって様子を伺おうか一瞬迷ったけど左折して走り去ってしまった。本当は直進する予定だったのだけど。このことで切符を切られることがあっても行いは行いとして仕方がないなと思ってるけども、交通ルールを守るために救急車を無視するのは仕方がないことではないというのが自分の優先順位だった。現場の創意工夫はだいたい東海村臨界バケツ事故で黙らされるイメージがあるけども、自分は自分が納得したルールのみに従い意味がわからないルールは無視ししがちな、軽率な側の人間です。


2025年09月07日 (日) [AtCoder] 精進。昼間にあった AtCoder Beginner Contest 422。■A 問題「Stage Clear」。ステージ数が倍のスーパーマリオブラザーズ。がっぴの処理と同じ。0始まりに文字列置換して8進数にして1足して文字列にして1始まりに置換するのは書いてて嫌になるほど無駄なのでやらない。じゃあなんで書いた? 一瞬やろうとしたから。■B 問題「Looped Rope」。サンプル図を見た感じ、1本のひもが交差するのは許されるけど折り返して接するのは許されない、というのを表した問題名らしい。そんなのは関係なく全マス目について「黒マスではないか、隣接する黒マスが2個か4個であるか」を判定する。最初に書いた条件は「黒マスであって、隣接する黒マスが2個か4個であるか」だったけどサンプル実行前に修正したからセーフ。■C 問題「AtCoder AAC Contest」。A と C の少ない方に合わせて AXC を作ったあとで、余っている A_C を崩して AAC/ACC を何個作るかが問題。単に文字の数を数えて3で割るだけなんだけど、解説によると最初に AXC を作るパートを飛ばしてそういう計算をしていいらしい。飛躍が過ぎてわかりません。■D 問題「Least Unbalanced」。想像通りであるしサンプルの通りでもあるように平らに均します。再帰的に分配する過程が操作の逆再生になっている。■E 問題「Colinear」。時間内には解けなかった。過半数っていうんだからテキトーに選べば当たるのはわかります。でもそういう確率的な操作を書いたことがないし、決定的な方法を探して諦めてしまった。翌日に2か所で乱択の文字を見かけたので、そっち方面に突っ込んで考えてみた。半分が同じ直線に乗っているなら、テキトーに選んだ2点が乗っている確率は4分の1。点の数が最大で 50 万なので、線形時間の処理が 20 回で 1000 万。Ruby の限界は数千万のところにあるので試行回数は数十回が限度か。仮に 20 回試行するとして、外れのペア(が定義する直線)を引き続けるのは (3/4)^{20} で 0.3 % くらいらしい。不安だけどまあ。提出 #69170329 (AC / 455 Byte / 1034 ms)。やっぱり 20 回の試行でもけっこう時間がかかっている。lazy が遅い? それはあると思う。以前から常々思ってるんだけど、find_map メソッド欲しいよね。find が目的だから map{}.find{} だと一度全要素を変換するのに抵抗があるし回りくどくも感じる。かといって find{} で返ってきた値に find の条件ブロックで判定に利用するために施したのと同じ変換をもういちどかけるのも冗長で嫌だし nil 判定はもっと嫌だ。そういうわけで今回は lazy.map{}.find{} になった。でも遅そう。■F 問題「Eat and Ride」。ゴールから BFS をすればゴールまでのステップ数(増加する一方)が揃うので、同一ターンではイコール条件になり前後のターンでは優劣がはっきり決まることになり、ウェイトにゴールまでのステップ数を掛けて消費燃料に換算した値が比較可能になる。毎ステップ各頂点においてゴールまでの消費燃料の最小を更新したもののみが次のステップに進める。ダイクストラ法と違って燃料消費の最小値が更新されることがあるので最悪で2乗のオーダーになるが N≦5000 なので2乗は通る。だからこの問題は各 i をゴールにしたときの最小燃料を問うている。2乗が3乗になった。やるだけの問題にはしないということだ (TLE)。じゃあ唯一のスタート地点である頂点1からたどりますか? そうするとゴールまでのステップ数が不明なために、(ここまでに消費した燃料,消費燃料の増加量=ウェイト) という2つのパラメータが関わってきてダイクストラ法の基準になるコストが一意に定まらない。提出 #69169539 (AC / 1003 Byte / 117 ms)。パラメータを2つ持ってダイクストラ法をしたらけっこうな速さで通った。消費燃料を基準にしつつそれを絶対条件にはしないで消費燃料の増加量の最小を更新するものにも可能性を残している。それはプライオリティキューを使ったダイクストラ法ではない何かですね。通るとは思っていなかった。というのは、キューに入れるときに消費燃料最小か燃料増加量最小のどちらかを更新する可能性があるかを調べてから入れてるんだけど、そのときに基準値を更新していない。基準値を更新するのはキューから取り出したときに限っている。そうしないと答えを間違えると思ったからそうしているのだけど、結果としてキューが取り出してすぐに捨てられるダメな要素で膨れ上がって出し入れに時間がかかり過ぎるおそれがある。これはダイクストラ法を実装するときの罠であり勘所だから、それをしないのでは TLE になると思ったがならなかった。想定解法はなんだろう。Ruby での F 問題へのすべての提出 を見たら想定解法は通らないっぽい? 最近の制約はまじでクソだと思う。3乗が通らない N=500 と2乗が通らない N=5000 と NlogN が通らない 5×10^5 のことだよ。俺は Ruby を書くために AtCoder をやっているので、Ruby お断りの AtCoder につまらない思いをさせられたらできることがない。■オンタイムで参加していないので E, F が解けなくても平穏だ。Rated だったら入緑していたね。■■■F 問題。想定解法がようやく理解できた気がしたので書いてみた。提出 #69198045 (TLE×26/AC×25)。かなり気を使って普通でない書き方をしたけど TLE が 26 個。他の人のを見ると、提出 #69146527 (TLE×29 / tinsep19 さん)、提出 #69145173 (TLE×23 / fumta さん)。Ruby では全然見込みがなさそう。一番 TLE が少ない fumta さんの提出はちょっとおもしろくて、辺を頂点ごとにまとめずにそのまま DP の遷移に利用している。そうするとループの回数がちょうど半分になる。ループ1回の処理は往路、復路で2倍になっているので全体の処理量は変わらないけど、ループを回す負担は半分になる。Python で一番速い提出を見てみたらたこつぼのページでたびたびお世話になっている ikatakos さんの提出 #69123541 がコンテスト中に提出されていて、解法が自分のなんちゃってダイクストラ法と同じに見える。Python の層の厚さはすさまじい。Ruby でからくも TLE を免れた遅延セグメント木の問題でも、2人か3人の人がそれぞれの手法を突き詰めてどんどんとタイムの「桁を」縮めていく様子が提出一覧からうかがえたりもした。何をやって縮めてるのか全然わからないんですよ。見た目が違うからたぶん採用している手法は異なってるんですよ。


2025年09月06日 (土) [AtCoder] 今日は AtCoder Regular Contest 205 (Div. 2) があった。div.2 に Rated でいつまで参加できるのか先行きが怪しいこの頃ですが、まだ Rated です。■A 問題「2x2 Erasing」。与えられた矩形の中の白4マス四角の数を素早く数えたい。右、下、右下がすべて白マスである白マスを1と数える2次元累積和で数えられそう。提出 #69078973 (AC / 640 Byte)。枠で区切られた部分の調整で無駄なことをしてる気がする。SR と SC は不要で、i1,j1 をそれぞれ -1 するだけでよかったのではないか。■B 問題「Triangle Toggle」。解けない B 問題に残り時間をすべて奪われました。時間さえかければ解けた C 問題、D 問題に着手したかった。■C 問題「No Collision Moves」。制限時間が3秒と長めなんだけど、何が難しいのかわからなくてなんの罠を見落としているのかと疑心暗鬼だった。S に基づいた人の並びと T に基づいた人の並びが異なっていれば、必ずどこかで移動の交差が起きるので答えは No。じゃあ Yes のときは端から整列させていけばいいんちゃうの? その通りなんだけど、端の人を移動させる前にその先の人を移動させる玉突きを処理する必要があった。サンプルがその例。でもそれだけだった。提出 #69089475 (AC / 486 Byte / 550 ms)。■D 問題「Non-Ancestor Matching」。全方位ではない木 DP。どうしても残ってしまう白色頂点の数を子を頂点とする部分木ごとに数えたら、それをうまくマージして白色頂点を最小化する。提出 #69091151 (AC / 670 Byte / 1192 ms)。うまくない場合というのは、1つの子の下にペアを作れない白色が大量にぶら下がっていて、他のすべての子の下にある白色の頂点と黒色のペアを解消して用意した頂点を使い尽くしても余ってしまう場合のこと。■5×10^5 の制約はまじで良くないよ。ARC はもちろん ABC でも見たくないよ。■日曜の昼は毎週ほぼ確実に時間がとれないので明日の ABC はお休み。


2025年08月31日 (日) [AtCoder] 精進。昨日あった ABC421-F「Erase between X and Y」。クエリを先読みすれば前に詰めたり後ろにずらしたりしないでいいように適切な空間を空けて要素を挿入・削除できる気がした。1本の配列をどう切り分けて必要な情報をレイアウトしようか考えていたけど、結局必要なのは次の要素が何かという単リンクリストだけだった。クエリ2で問題になるのが x と y のどちらが前にあるのかという情報だけど、クエリ1のみを先読みして作った木構造を深さ優先でたどって通し番号を割り振って順序にできる……というのは各要素を決まった場所に並べて動かさないでいいという最初のアイデアと同じことを言っている。発想の順番としては木構造の方が先で、各ノードが要求する最大サイズが事前に先読みできるから、1本の配列上に木をレイアウトしたとしてそのあとノードを挿入したときに全体の再レイアウトが避けられるなと考えて、それからクエリ2によってノードが削除されたときに木構造を維持するために必要な更新をシミュレートしていたら(前から削除していくと子を残して親が先に消えるので子のつなぎ替えが必要)、木のような立体的な構造である必要はないな、ただの直線(リスト)だなと気がついて実装がとても簡単になった。■提出 #68964752 (TLE×2/AC×34)。なんでなんですか。一番に考えたのが 25 行目が無限ループになっているためにメモリを 1.5 GB ちかく消費し時間を 2.3 秒ほど費やしたところで実行を打ち切られているのではないかということ。しかし x と y の前後関係を見誤ってリストにループを作ってしまった場合、そのクエリの最中にリストを末端までたどった末に nil を演算に使用してランタイムエラーを出すはずなのだ。RE を出さずに無限ループをお膳立てする方法がわからなかった。それに他の AC になったケースをよく見ると、1.6 秒で約 1 GB のメモリを消費するなど、実行時間に比例してかなりのメモリを消費しているが異常ではないらしい。どこで多大なメモリを消費しているのかよくわかりませんが。■提出 #68969535 (AC / 924 ms / 352228 KiB)。2か所を while 文に書き直したらメモリ使用量が劇的に減って、したがってメモリ操作にかかる時間も減った結果 TLE が解消した。1つは .reverse_each.injectwhile .pop に、もう1つは .eachwhile .shift に。たぶん2つ目は時間に効くけどメモリに効くと意識したことはない。じゃあ Enumerator を返す使い方の Array#reverse_each に罠がありますか? あと、ちょっとだけ余分な時間がかかり、TLE と AC を分けることもあると知られている多重代入が複数の代入に分解されているのも確認できるけど、これは最初にこれだけをやってみて効果がなかったのでカウントしていない>提出 #68965976 (TLE×2)。■提出 #68970098 (MLE×2)。これは最初の TLE 提出の .reverse_each.inject.reverse.inject に書き換えただけのもの。reverse_each が罠なのかどうかを確かめたくて。結果は全体的に実行時間もメモリ使用量も何割か改善しているけど MLE になってしまった。そういえばメモリ制限は 1024 MiB だった。.reverse_each を .reverse に書き換えることで TLE は解消したけど MLE がそのままだったので AC にならなかった。ただの数値配列なのにメモリ制限が厳しい。使用済みのデータを随時破壊的にシュリンクしていって GC させないといけませんか。■Ruby の提出を時刻の早いものから見ていってる。提出 #68945143 (konayuki さん)。BIT を使って何をするのかわかりません。提出 #68947172 (hmmnrst さん)。なんとクエリ先読みが必要ない。クエリ2では x からと y からの両方を同時にたどってどちらが他方にたどり着くかを確かめている。自分の TLE/MLE の原因は x,y の順序を決めるための先読み部分の深さ優先探索にあったから、両方をたどってみるのが労なく AC できて正解だった。準備せずやってみるだけ! 同時にたどるのがたぶん重要なポイントで、順番にたどってみようとするとリストの全体をたどってしまうことを覚悟しないといけなくて、それは Q^2 のオーダーで TLE になる。他の提出は全部 BIT を使わないリスト解法かな。リストを二重リンクリストにして x から両方向にたどってるっぽいヴァリエイションもあった。■直近4回くらい緑パフォ安定で結果は出ないしコンテスト中は全然おもしろくないんだけど、だからふりかえりも書かないんだけど、精進日記や精進未満日記が3つ続くところを見ると問題自体に問題はなくて解くのを楽しめているような気がするんだよね(そのように見える判断できるというだけで楽しいと思ってはいない)。でも圧倒的に時間が足りていなくて、この F 問題は問題を読んだのが今日だった。この難易度の問題を後日提出の宿題にしてしまってはいけないんだよ。でも D 問題も F 問題も1時間では AC にならないし、E 問題は解けてもいない。メモ化再帰で書こうとして書けていない。キープする面の組み合わせをを選んでその場合の数を数えたいけどできない。■■■D 問題についても書こ。時間内に1時間かけたものは半分 AC で半分 WA だった (#68940840)。おしまい。終了後に最初の実装を捨ててもう一度書いた。実装の機微がすでに明らかなので、位置関係を分類して (左,右,同じ)×(上,下,同じ) の9通りを実装するのはやめて、現在の両者の距離と1秒後の両者の距離がゼロかどうかと変化量を見て判断することにした。分類して予測するより単位時間の経過を見る! 提出 #68953965 (AC)。D 関数がある時点の両者の距離で、X 関数がある時間の両者の重なり回数。実装し直しただけで AC になるのだから最初の提出の WA は実装ミスなんだろう。変化量が負になりうることを全く想定していなかったのでたぶんそのあたり。問題を一読したときから考える要素は1秒分もなかったけど、重なっている回数をうまく数えることができなかった。簡単な実装方針が見極められるのも実力のうち。ありませんでした。■■■リストを同時にたどるというアイデアが自分の頭から出てくる見込みがなさすぎて悔しいので、これが悔し紛れになるのかは知らないけど本で得ていた知識を1つ書こう。リストがループを持っているとき、その形は輪っかか輪っかにしっぽがついた「の」の字になるけど、輪っかがあるかどうか、あるとしたらそのサイズは何かを知るために2つのポインタでリストを同時にたどる方法がある(らしい)。アルゴリズムのキモはポインタの進む速さが異なっていることで、遅い方は1つずつ速い方は2つずつ進めていって、いつ2つが衝突するかを観察することから始めて、しっぽとサイクルの接続点を2つ(3つ)のポインタ以外の記憶領域を必要とせずに求めてしまう。そのときにはサイクルの長さもしっぽの長さも(数えたいなら)数え終わっている。というようなことが『プログラミング原論』の 2.3 衝突点 (pp.23-28) に書いてある。本の最初の最初のただの前置きみたいな部分なのに難しいね。


2025年08月27日 (水) 至極もっともなことがグラフを使ってわかりやすく整理されているこちらの記事。「「読みやすいコード」を依存グラフで考える」■内容はいいんです。読んで読みやすいコードのあれこれの裏付けを知ってそうだったのかと納得すれば良い。最後のまとめのうちのひとつ「宣言的でないコードは分離して端に掃き出すとよい」を自然と後押ししてくれるのが関数型言語のモナドだと思ってるけどよく知らない。■波線がないところに「波線」と書かれていたので、これは破線(ハセン)の変換ミスだなと思って自分でも変換してみたところ、破線と波線の読みがどちらもハセンだと知って驚いたのが今日の日記の中身。ナミセンには項目も立っていなかった。区別できないじゃん。


2025年08月25日 (月) [AtCoder] 日曜にあった ABC420-G「sqrt(n²+n+X)」。精進じゃないよ、解けないもんね。順位表を見たら F よりずっと多い 1000 人以上に解かれていたみたいだけど、それを知って取り組んでいたとしても解けなかったので結果は変わらなかった。今年の東大の何かと同じ式変形だとか、ただの受験数学とかのコメントが見えたけど、ただの……ねえ。■最初に考えたのは、なんで答えの数が有限なのかなということ。n がとんでもなく大きかったり小さかったりすると、n(n+1) が支配的になって X が無視できるから(都合のいい言葉)、n(n+1) は平方数ではなく、そのルートは整数ではないということだと思った。そうすると X が n(n+1) と n^2 の差分を相殺するときに答えが見つかるなということがわかる (n=-X は常に答えのひとつ)。n(n+1) と (n-1)^2 との差分を相殺するとき、(n-2)^2、(n-3)^2 との差分を相殺するときもそうかもしれない。いったいどこまで考えればいいのか。サンプルにあったように X 自身が平方数のときは n=0 と n=-1 も答えになる。こんな感じで思いつきを列挙していってどうして全部列挙できたと言えるのか。なんもわからん。


2025年08月23日 (土) 毎週 21 時の AtCoder を待機しているときに Windows の時計を「今すぐ同期」するのだけど、これが決まって 15 秒程度遅れていたかのような調整がなされる。1週間で 15 秒遅れるの? こういうのを精度はあるけど正確ではないというのだろうか。一度にいっぱい変わったのでなんともいえないけど、ミニ PC に替えたからというのを考えられる理由のひとつから外してはいない。あとゲーム実況動画の音声が違うように聞こえるというのもある。これもいっぱい変わりすぎていて、スピーカーは同じだけど音声の経路が途中まで HDMI になりモニタを経由していたりという変化がある。そもそも録音機材であるマイクを変えましたというので聞こえ方が変わってくるものでもある(とはいえ以前見た動画の音声が違うように聞こえているのは機材の違いではない)。マザーボードが違えば違ってくることってあるのかなあと考えたりなかったり。楽譜データを演奏するのに音源が~とかいうのとは関係ない話なので変わらないとは思うんだけど。あとは変な音響効果がオンだった、オンになった、とか。