/ 最近 .rdf 追記 設定 本棚

脳log[2025-04-05~]



2025年04月05日 (土) [AtCoder] 今日は AtCoder Beginner Contest 400 があった。3桁順位に入りたいよー。■A 問題 ABC400 Party。細かいことだしどうでもいいこだわりかもしれないけど、「テストして実行」よりも「実行してみて可否を見る」方が好み。テストと実行のあいだには無限の隔たりがあるから、テストの成功は必ずしも実行の成功を意味しない。これには鍵をかけたあとで鍵がかかっていることを確認する母の影響もあるかと思う。鍵をかけること(かけたつもり)と鍵がかかることのあいだにも隔たりがある。■B 問題 Sum of Geometric Series。一応まじめに考えようとしたんだけど、さっぱり頭が働かなかった。Ruby なのでオーバーフローを気にせずやるだけでいい。最大ケースでも TLE になる気配はなかった。あ、そうだ。なぜか今日起動した irb (1.6.2 on Ruby 3.2.2) はこれまでなかった補完と色分けが有効になっていて、極めて使いにくかった。なぜなのか。Ruby-1.8 で使っていた mp3info を Ruby-3.2 で使うために gem でインストールしたのだけど(単にコピペしただけではタグのセットはできても取得ができていなかった)、そのときに gem 自体にもアップデートがあるとお知らせされて gem のアップデートをしたというのが唯一関連がありそうな心当たり。なぜ関連があるかというと、ruby/bin/irb にこう書いてあったから。「This file was generated by RubyGems. The application 'irb' is installed as part of a gem」 だけどこのファイルが更新されていたわけではない。たぶん %USRPROFILE%\.irbrc に書き込むんだけど、どうやって色分けと補完を無効にするんだよ。……。IRB.conf[:USE_AUTOCOMPLETE] = falseIRB.conf[:USE_COLORIZE] = false を書き足して心の平穏を得た。俺は出しゃばりな機械を憎んでいる。■C 問題 2^a b^2。方針を定めるのが難しい。平方数を列挙したいと思ったけど、N の上限が 10 の 18 乗だからといって 10 の 9 乗までを列挙することはできない。それに b が 2 を含んでいるときに同じ良い整数を表す2通り以上の方法があって重複を除かなければいけない。そこで、b は 2 を含まない(奇数である)ということに決めてしまった。a を決め打ってから b の上限を二分探索で。■E 問題 Ringo's Favorite Numbers 3。扱う素数がいくつあるかをまず調べた。8万以下だった。定数倍が2分の1以下だとしても組み合わせを列挙すると2乗で厳しいなーとか考えていた。べつに厳しくはなかった。p^{2n}q^{2m}10^{12} を超えない範囲ですべての p^nq^m を列挙してソートしておいてから、2乗して A を超えない最大のものを二分探索で探した。サンプルの1ケース目が合わなくて困っていたのだけど、これは p^nq^n を列挙していたことが原因。p と q の指数は偶数であるという点が共通するだけで独立しているのに勝手に揃えてしまっていた。■D 問題 Takahashi the Wall Breaker。F と D を見比べて見込みがあるのは D だと思ったので一度飛ばした D に戻った。方針が立たなかったのだ。前蹴りしたはいいけど他の連結成分に合流できないケースの扱いに困っていた。それはどういう状態なのか。どの状態からやってきてどの状態へ移行するのか。どうやって現実的な時間で遷移を網羅できるのか。わからなかった。だけどグリッドの処理を書いているときに、前蹴り何回で現在のマスにいるのかを書き込んでいけばいいのだと気がついた。サンプルが有能で助かったんだけど、前蹴りで破壊される2マス目の扱いに罠がある。処理が重複する無駄があると TLE になるおそれがあるので、最短を更新したときだけ次の処理をキューに入れるのがお約束。ところが、前蹴り1マス目が最短を更新しなかったとしても、前蹴り2マス目は最短を更新することがある。前蹴りには向きがあるからこのようなことが起こる。だから前蹴り1マス目に関しては最短を更新しなかったとしても2マス目の処理を進めなければいけなかった。解けてみれば実装問題枠として置かれていたのだと思うけど、普通に考え込んでしまった。もともと大したことがなかった脳みその退行が著しい。悲しいね。自分がやっていたような精進というのは、問題に対するパターンマッチ、ヒューリスティクス、反射神経を鍛えているのであって、規模と速さにおいて決して敵わない AI に対して AI の土俵で戦いを挑む行為なのではないかと思ってしまう。自分は考えるという行為を未だ知らない。■■■Ruby の Integer.sqrt にバグが見つかっていた。「Bug #21217: Integer.sqrt produces wrong results even on input <= 1e18 - Ruby」 きっかけは ABC400 の C 問題らしい。提出 #64512377 (WA×2 / Ruby で C 問題最速の提出)。本番で絶対合ってるのに WA が出たら……かなりつらい。固執してペナルティを重ねるか、俺は間違ってないこれが違うならもう何もわからんと投げ出すというのが自分の典型的反応。


2025年04月04日 (金) トランプさんの関税。効率は悪くなっても国内で自給自足するぞということなのかなとか、グローバル企業から国家に主導権を取り戻すことにつながるのかなとか考えると、それは割と共感できるのだな。鎖国もお上も日本語にある言葉だし。物価が上昇しても国内で循環しているなら国単位で見て損はしていない。逆にいくら安いからといって外国から買うばかりでは国から富と仕事が流出している。それが嫌なんでしょう。バイデンさんがある部分ではそうしたように、次の大統領が今期のトランプさんから何を引き継ぐのかに興味がある。


2025年03月29日 (土) [AtCoder] 今日は AtCoder Beginner Contest 399 があった。精進の目途が立たないのでダメだったとだけ書く。まず D 問題が解けなかった。WA を重ねた末にランダム入力と愚直解でダメケースを探してデバッグをしたけど、提出するとそれでも WA が出る。根本的なところで勘違いをしていて愚直解が間違っているかと疑って問題とスクリプトを読み直すけど見つからない。お手上げ。次に E 問題が合わない。サンプルの4が親切でループがあるケースに手当てが必要だとわかるけど、それをやっても合わない。他に考えるべきことがあるのか実装が間違っているのか、どちらともわからない。お手上げ。■■■寝起きに思いついたんだけど、手当てができないケースを過剰に見積もっていたかもしれない。帰ってから試す。■WA が2個減ったけどまだだめ。■■■ループにしっぽがついてるものは1手損しないらしい。note で読んでしまった。たしかに、輪っかとしっぽの合流部分をしっぽの先に繋ぎかえれば損しない。十分に解けるチャンスはあったと思えるタイプの難しさであり、気持ちがいいくらいみごとにやられた(やられたくはない)。■F 問題はまあ、項数が増えたときに K 乗の増分がどうなるか、というのを管理して足していくんだろうなあと思うんだけど、やったんだけど、完成しません。


2025年03月26日 (水) 人生で去年初めてだったこと。指先の表面がかさかさとひび割れてシャツをなでると引っかかること。指紋に沿ってぱっくり開いたひび割れが痛いこと。指の関節の内側の表皮が折れ目に沿って割れていること。痛いのは1本だけなんだけど、これが毎年だったり、増えていったりすると、嫌だなあ。指は使うものだから、痛いか不便かのどちらかになる。テープで貼り合わせて開かないようにすると、痛くはならないけど指先の摩擦と感覚が失われて不便。


2025年03月25日 (火) [Win11] デスクトップにごみ箱だけを置いているとき、デスクトップに新規作成したファイルに名前を付けるとごみ箱の名前まで同じ名前になろうとして拒否されるということが起こっていた。今も起こる(24H2)。巻き込まれるのがごみ箱でなければそのまま同じ名前になる。複数のファイルを選んで同じ名前を付ける機能については知っている。拡張子が異なるなら同名で拡張子だけが異なるファイルになるし、拡張子が同じなら「name (N).ext」という連番が付与される機能。知っていると便利な機能だけど、なぜそれが暴発するのか。なぜできたてほやほやでまだ名前が確定していないファイルに名前を付けると巻き添えが発生するのか。名前をデフォルトの「新規 ファイルタイプ.拡張子」のまま Esc で確定してわかった。ファイル名が確定した瞬間に、デスクトップで最後にフォーカスを持っていた(しかし選択されてはいなかった)ファイルが新規作成したファイルと同時に選択された状態になるのだ。つまり、最後にフォーカスを持っていたが選択されてはいなかったアイコンは、ファイルが新規作成された瞬間になぜか選択されていたことにされ、新規作成されたファイルに名前を付けるということが同時にそのファイルの名前を変更することになっていた。フォーカスを持っているが選択されていないとはどういう状態か。ファイルが1つでも選択されていると右クリックメニューはそのファイルのものになる。だからデスクトップにファイルを新規作成したいときは、デスクトップフォルダの右クリックメニューを表示するためにファイルの選択を解除しなければいけない。そのために Ctrl+Space を押して選択状態を切り替える。それを理解していない者がいる。■単純にフォーカスリングの位置だけが影響しているわけではないみたい。Ctrl を押しながら矢印キーとスペースキーで任意のアイコンの選択状態をオンにしてオフにすることを繰り返してからファイルを新規作成すると、一度オンにした(そのあとで選択解除された)複数のアイコンが新規ファイルと同時に選択されていたことにされる。一度というのがいつを区切りとしたカウントなのかまったく理解できないけど、なんらかの履歴が存在していて悪影響を及ぼしているように見える。■新規作成したファイルが既存のアイコンを押しのけて配置されることがあるのも根は同じだと思うな。右クリックを起点とした操作しか想定していないんだろう。マウスやタッチは対象に触らずには操作することができないし、操作には必ず点の座標が伴う。マウス操作しか知らないと触られた結果を暗黙の前提にすることがマウス操作を前提にしていると気がつくことができない。■Windows Vista はこうではなかった(7以降は知らない)。という風に先月まで使っていた Vista を擁護しようとしたけど、Vista のデスクトップもあほなところがあった。新規作成したファイルが左上から縦に配置される(既存のアイコンを押しのけたりはしない)一方、Shift キーを使った線形選択では Z 字に選択範囲が拡大するのだった。そうするとデスクトップ右上に配置された注目外のクラスタが知らず選択されてしまう。だったら新規作成されるファイルも Z 字に配置するのが良かったと思うんだよなあ。11 はこれ以下だって言ってますよ。ていうか今書いた現象は 11 でも確認できたから、純粋に劣化が上乗せされている。


2025年03月23日 (日) [AtCoder] 今日は AtCoder Regular Contest 195 (Div.2) があった。配点は 4-5-6-7-9。3問解ければいいなあという配点。■A 問題 Twice Subsequence。他の人の解答を見ると、前から作った列と後ろから作った列を比較しているものが多かった。自分はというと、前から部分列を作りながら、もうひとつ、異なる選択をした場合の列(のうち最善のもの)を同時に作っていた。提出 #64134048 (AC)。二分探索があるからたぶん効率が悪い。■B 問題 Uniform Sum。まず A 数列と B 数列から -1 を取り除く。-1 の数の合計が、好きな和を作れる要素の数になる。だから -1 が A/B 合わせて N 以上あるなら答えは必ず Yes になる。M=N-(-1 の数)>0 として、M というのは A 数列と B 数列を組み合わせて同じ数を M 個以上作れたら答えが Yes になるという数字。和を固定したら A 数列と B 数列を組み合わせていくつその和を作れるかは線形時間で数えられる。でもその和の候補が N^2 通りあるなら全体は N^3 であり、N≦2000 だから3乗は通らない。TLE×38TLE×12。通らないのはわかっていたけど終了時刻が迫っていたのです。終了後に A 数列と B 数列の組み合わせを全列挙する解答を考えた。全列挙は2乗なので許されている。列挙した和を集計して最も多く作れる和を選ぶだけ! 提出 #64144851 (AC)。22 行目の集計部分がちょーっと複雑で長いけどちょっとだけ! なんでわざわざ下手な数え方をして TLE を出していたのか不思議だね。あとサンプル3が親切に教えてくれるけど、和は A 数列の最大値と B 数列の最大値と同じかそれより大きくないといけないという条件があるので、フィルタリングを忘れない。■C 問題 Hamiltonian Pieces。赤い駒も青い駒も4を単位として輪っかが作れる。だから4で割った余りをどう組み合わせるか、16 通りの場合分けをがんばった。WA×23WA×13AC。■■■B 問題で和の集計について何をごまかしたかを書く。A 数列に2が2つ、B 数列に3が3つあるとき、直積で列挙した和には5が6個現れる。実際に作れるのは2と3の少ない方である2個だけ。これに対処するためにまずは2つの2を (2,2)、3つの3を (3,3) と集計したあとで直積を列挙した。得られる要素は ((2,2),(3,3)) であり、5が2個作れることがわかる。和として5になるものは他に ((1,x),(4,y)) などが考えられるけど、和を1つ選ぶとき、(2,2) と (1,x) が実はペアを変えただけの A 数列の同じ要素の再利用だったり、(3,3) と (4,y) が B 数列の同じ要素の再利用だったりすることはないので、問題は解決している。そういうことを 20 から 22 行目でやっていた(tally, product, group_by とか sum{ min } とかで)。


2025年03月22日 (土) [AtCoder] 今日はユニークビジョンプログラミングコンテスト2025 春(ABC398)があった。F はローリングハッシュもしくは z-algorithm を知っていますかというだけの問題。私は z-algorithm が理解できないので知りません。E 問題が難しくて解けなかった。制約が小さいからとにかく先読みして有利な手を選べばいいのかなと思ったけど、それも難しかった。そして終了後に Ruby の提出一覧を眺めていて驚いたことに、自分が C 問題で WA を出していた。えっ、再提出した覚えがないんですが。C 問題で WA を出していたことに気づかずに 300 点を失っていたのだった。いつも B 問題を提出するときに A の AC を、C 問題を提出するときに B の AC を確認するんだけど、D 問題を提出したあとの提出一覧に黄色い WA があることに気が付かないって、どんだけ D 問題で余裕を失っていたかってことだ(D に 30 分かけました。そしてたぶん E 問題を読まずにリロードしながらジャッジの進捗を注視していたと思う。自信がなかったから。1行下の異変に気が付かないって、どんだけ視野が狭くなっていたのやら)。だけどね、終了後に考えてみても WA×1 の原因がわからないんだから、ケアレスミスだとは言えない。ジャッジサーバーが一瞬だけ狂って判定ミスをしたんだと信じてる。今日は太陽風が強い日だった(大嘘)。■■■C 問題。朝ごはんを食べているときに気が付いてしまった。数値化をサボっていたために文字列の中から最大値を探していた。Windows Explorer はファイル名でソートするとき数値部分の桁数の違いを0埋めされているかのようにいいように解釈してくれるけど、普通は文字列の "100" と "9" を比較したら "100" が前に来る。よくそれで1つ以外 AC になったものだ。提出 #64130280 (AC)。差分は1行目のみ。■精進。E 問題。二部グラフだって他所で読んでしまった。提出 #64130692 (AC)。実装することに意味はない。問題の構造を見抜けなければいけない。


2025年03月21日 (金)

最終更新: 2025-04-10T19:57+0900

[BAD BOY] 自転車が9速から10速になった。

時系列

  1. シフトが気持ち良くない。アップもダウンも。
  2. 前回リアディレイラーを歪めてしまったときは9速の DEORE (シャドータイプ) がもう手に入らなくなっていて間に合わせのものに交換したけど、やっぱりアウターワイヤーの走行が直線的で総延長も短くなるシャドータイプが良い。
  3. 現行のパーツを調べた。
  4. MTB 系統なら CUES か DEORE がちょうど良さそう。
  5. CUES なら 9/10/11 速、DEORE なら 10/11 速のパーツがある。
  6. MTB 系の11速までは LINKGLIDE という名前の下にギアの枚数によらずいろいろ共通化されてるぽい。ただし、DEORE の10速には2種類あり LINKGLIDE でないものがあるし、SAINT の10速は LINKGLIDE ではない。
  7. 仮に CUES の9速にするとしてもチェーンを11速規格のものに交換する必要があるらしい。同じ9速でチェーンが交換になるのは CUES/LINKGLIDE がギアの枚数によらず11速のチェーンで共通化されているからだ。かつての互換性のない10速化11速化時代よりずっとリーズナブルな状況ではあるが、おかげで旧来の9速が消えた。
  8. ところで CUES のリアディレイラーはロー側の対応が 36T から 39T までと書かれている(9/10速の場合)。11速なら 48T から 50T までとか。
  9. よくわからないんだけど、たとえばリアディレイラーが 11T (トップ側) から 48T (ロー側) までに対応しているというなら、50T のギアに対してはディレイラーの移動量が足りなくて大きすぎるギアに横からぶつかってしまうのかなと思うし、逆にスプロケットのロー側最大が 28T ならギアが小さい分には距離が詰められなくて多少変速性能に影響するかもしれないけど問題なく使用できるんだろうなと判断する。だけどディレイラーのスペックでトップ側が 11T (最小) から 11T (最大)まで、ロー側が 36T (最小) から 39T (最大) まで対応と書かれていると、どう読んでいいのかわからない。39T 以下ならなんでもええんちゃうの? 36T より小さい 28T はあかんの?
  10. それで気がついたんだけど、MTB 系のスプロケットはどれもこれもワイドレシオなのだ。ロー側がとても大きい。自分が今使っているのが 11-28T (9速) なんだけど、同じ9速のスプロケットのラインアップが 11-36T、11-41T、11-46T となっている。ギアの枚数が同じでレンジが広いなら隣り合うギアの歯数差が大きいということで、つながりが悪くなる。
  11. どうせ全取っ替えなら10速、11速にしてギアの枚数が1枚2枚増えるのも選択肢に入るんだけど、増えたのが使いもしない 46T、50T みたいな大きすぎるギアなら、それはただの重しなんです。山なんか登らないし平坦な1号線沿いが主なのでレンジは 11-28T (歯数差 17) で十分に足りている。
  12. 幸いなことに今使っているホイールのフリーボディはありふれた HGスプラインM っぽいので、MTB 系下位だけでなくロード系の下位とも互換性がある。
  13. ディレイラーの対応幅とスプロケットのレンジに注目するなら Tiagra (10速) が良さそう。しかしリアディレイラーがシャドータイプではない。フラットバー対応のシフターがあるが、ギアポジションインジケーターがいらない。
  14. グラベルというカテゴリに GRX というシリーズがある。これは10/11/12 速に対応している。12速はロード規格なのでスプロケットが手持ちのホイールに付かない。10/11速が MTB 互換(HGスプラインM)。10速が手頃なお値段でシャドーRD+だ。ロー側対応が 32T から 36T で、28T でもまあまあ大丈夫だろう(結局ロー側最小は無視することにした)。フロントの変速はしないからキャパシティが過剰でケージが長すぎるけど目をつぶろう(今付いているものも同じくらい長いから)。しかしラピッドファイヤーのシフターがない。
  15. ロード系でフラットバーに対応したシフターは Tiagra のものしかないのだろうか。今使っている SLX のシフターにはフタが2種類付いていて、ギアポジションインジケーターがありかなしか選べたんだけど、Tiagra のシフターにはかならずインジケーターが付いているのだろうか。ハンドルがごちゃつくのも、ちゃちなパーツでごちゃつくのも嫌なんだ。
  16. たまたま見かけたダイアコンペ ENE サムシフター (6/7/8/9/10速対応) がアナログで面倒くさくないんじゃないか。

という経過をたどって4つのパーツが選ばれた。

  • シマノ リアディレイラー RD-RX400 10S ¥6596
  • シマノ カセットスプロケット CS-HG500 10S 12-28T ¥3300
  • シマノ チェーン CN-HG54 10S HG-X対応 ¥2364
  • ダイアコンペ ENE サムシフター SL/BK 右のみ ¥7766
  • (おまけ) アルミプーリー 13T 2個セット ¥1542

シフターは右用と書かれているけど、ハンドルの右側の上方に取り付けるつもりはなくて、左側の下方に取り付けた。そうするとラピッドファイヤーのときと同じ位置にレバーが来る。ただし左右は逆になる。左手は後ろブレーキのみ担当でシフトはなし、ブレーキとしても主力ではなくグリップも握らず遊びがちだったので、これからはリヤシフトを担当してもらう。レバーは6時の方向にあるときがトップで、ローはだいたい10時の位置。検索で上位に来るブログを読んで不安に思っていたのだけど、ワイヤーを巻き取りすぎてチェーンがスプロケから外れてしまうことはない。リアディレイラーに H/L と刻印された2つのネジがあり(以前はプラスねじだったと思ったけど、今回は星形の T8 だった)、移動限界を調整しておけばよい。3つ目のネジは B テンションアジャストボルトであり、ガイドプーリーをスプロケットに近づけてチェーンの横方向のガタが変速に及ぼす悪影響を小さくするものなので(という風に私は理解しています)、この機会に適度に近づけておく。シフトに話を戻すと、ローギア10時は親指で押すにはかなり遠いが届かなくはない(レバーの回転軸がハンドルバーより奥にあるので余計に遠い)。人差し指で手前に押すのにはちょうどいい。だが8時の位置で人差し指が届かなくなる。そこからのシフトアップが難しい。親指の背中で少し手前に押してやると親指の指先でトップまで操作できる。人差し指から親指へのリレーがスムーズではない。停止するときはだいたい3つか4つシフトダウンするので、発進するときはカチカチ、カチと3つシフトアップしていた。カチカチではなくなったのでちょっともたつく。でもまあ楽し。


シマノの日本語のページに情報がなかったから候補から漏れてしまったけど、リアディレイラーに11速の古い105(RD-R7000-SS)を使えばスプロケの値段が倍になる程度の差で一式を11速に揃えるチャンスだった。LINKGLIDE 互換の11速だから今のホイールに取り付けられるし今後のパーツ供給に不安もない。GRX と違いショートケージでコンパクトなものも選べる。Tiagra の状態を見ると LINKGLIDE でない10速は9速に続いて消える運命にあるように思えるのだよね。今現在一式新しく揃えるようなものではなかったのではないかと考えてしまう。


 @2025-04-06

BB とクランクセットを交換した。

  • シマノ ボトムブラケット BB-MT501 ¥2808
  • シマノ CUES フロントチェーンホイール FC-U6000-1 チェーンガード付き 175mm 40T ¥7330

昨年末から左の足下からギリギリと音がしていた。一時解消していたんだけど10速化したときに再発していた。原因はいろいろ考えられて、

  • クランクのゆるみ
  • ボトムブラケットのゆるみ
  • ペダルのゆるみ
  • ペダルのベアリング
  • チェーンが切れそう (自分でつないだ部分が上り坂で切れたことがある。予兆として前日から音があった)
  • チェーンとチェーンリングの噛み合いが悪い (チェーンが浮き上がり内側に倒れ込むようになる)

どれも違うようだったので消去法と前回交換したとき(2014年9月)に音が解消した経験からボトムブラケットが悪いと結論づけた。10 年使っている BB (シマノ BB-UN55 68mm/113mm) を交換するだけでもいいんだけど、それで音が解消しないと面倒だし、今後どのチェーンリングに交換するか悩みたくもなかったので(シマノの話だけど、PCD が同じミドルのリングでも穴の内側のでっぱりが干渉して付かないものとそうでないものがある)、クランクも含めて一番ありふれたセットに交換することにした。

クランクは 2007 年に自転車を購入したときのものそのままだからちょうど 18 年になる。チェーンリングはいつからかインナーを省いてアウターとミドルだけ付けていたけど、そのアウターもチェーンガードの固定台座としてのみ存在しておりミドル(36T)しか使っていなかった。シフターからもワイヤーは外してしまってただの脱落防止のチェーンガイドになっている。だから新しいクランクは最初からシングルにしたし、歯数は、今のスプロケットのトップ(12T)まで使い切ってしまっているので4多い 40T ということにした。スプロケのレンジがちょうどいいスピードから外れても困るので 42T にはしなかった。一番無難なのは2多い 38T だったけど、チェーンガードが欲しかったので 40T になったし、GRX ではなく CUES になった。クランク長は違和感が出ないように同じ 175mm のまま。長すぎる可能性はあるけどこれまでずっとこれなので。


2025年03月20日 (木) 一気に 80 くらいバージョンアップした Firefox (136.0.1) でポップアップブロックを有効にしていると、ちょいちょい自分がクリックして開こうとしたページがブロックされる。たぶんだけどタイミングが関係してる。ページを読みながら、次に読もうと思ったリンクの上でマウスボタンを押し下げ、読み終わったタイミングでボタンを放す。ブロックされる。そんなブロックは無効にするしかないねえ。


2025年03月15日 (土) [AtCoder] 今日はオムロンプログラミングコンテスト2025(ABC397)があった。■A 問題 Thermometer。2番目の条件を else にするとタイプ数が減る。■B 問題 Ticket Gate Log。WA を出しました。愚直に現在が奇数番目か偶数番目か、1文字足すか足さないか、判定をすれば良い。WA の原因は現在が何番目かを操作前の入力に基づいて判定してしまったこと。文字を足せば偶奇が変わるでしょ。■C 問題 Variety Split Easy。Hash で左右の要素をカウントする。種類数は Hash#size で知る。■D 問題 Cubes。解けなかった。5秒かかる。数が大きくなっていくと、x と y の差が1だとしても N より大きくなるので、これを上限にして x を線形探索、y を二分探索しようとしたが、これが TLE だった。N が 10 の 18 乗以下で、x の探索範囲は 10 の 6 乗以下になるかなと思ったんだけど、実際は 577 メガだった(irb で簡単に計算できる。でもコンテスト中はまず提出しちゃう)。次に x と y の差を線形探索し、x と y を二分探索しようとした。差の探索範囲は N の3乗根以下でいいので、今度こそ 10 の 6 乗のオーダーで探索できるんだけど、そこに二分探索の log が付くと5秒かかるのだった。ところで、Ruby だから気にしてないけど、x^3 と y^3 の差が最大で 60 ビットになるというとき、x (と y)を探索するのって難しいよね。x^3 と y^3 を 64 ビットの範囲に収める方法も、収めていいかもわからない。■E 問題 Path Decomposition of a Tree。WA をいっぱい出した。最初は子を組み合わせて K をいくつか作る DP をするのだと思った。そのうちに K は1個しか作れないと気がついた。終了後に、K を作る方法は2つ以下すべての子を足し合わせるしかないとわかった。K 未満の子が3つ以上あればそれでもう満足なパスは作れない。K 未満の子が2つあってその和が K-1 でないなら、もう満足なパスは作れない。それほどに長さ K のパスを作る条件は厳しい。終了までずっと大きさ K の部分木を作ろうとしていた。パスは一本道。パスは一本道。■F 問題 Variety Split Hard。C 問題が2分割だったのに対してこれは3分割。C 問題同様に2分割しながら、右側の範囲のベストな分割を遅延セグメント木で見つけられるのではないかと考えた(終了後にね。時間内は DE にかかりきりで 550 点問題を読む時間を惜しんだ)。たとえばある値 a がいくつかあって l..r の範囲に分布しているとする。l の右側から r-1 の右側で分割するのなら、分割の左右で a を種類数 1 としてカウントできる。結果は (TLE×13/AC×32) だったから、外してはいないと思う。■D も F も TLE を解消する方法がわからない。E が得点できなかったのは考察が甘く条件を絞りきれなかったせいであり完敗。不満の漏らしようがない。■F 問題。提出 #63857023 (AC / 1949 ms)。制限時間きわっきわで AC。クラスを剥がして演算を埋め込んだ(手動インライン化)。それとセグメント木の初期化をサボらずに O(N) でやった。サボると O(NlogN) になる。全体が O(NlogN) ならサボってもオーダーは変わらないんだけど、定数倍が TLE と AC の分かれ目ならサボってはいけない。残るは D 問題。Ruby で2桁ミリセックで解けるらしいので、純粋に数学力が足りていない。■■■X 拾い読み。「ABC397 E 、K 頂点を K-1 辺で結んだ直鎖を長さ K のパスと呼んでるの違和感あるな」という意見を見かけた。真意はわからないけど、それはパスはパスでも単純パスと呼ぶのではないかという疑問なのではないかと想像した。なんでそう思うかというと、自分もちらっと単純でない(交差のある)パスが答えになることがあるか考えてみて、NK 頂点を長さ K の N 本のパスに分解するのだから、それは単純パスに違いないなとすぐに納得したからだった。単純パスだと限定しているのは文章のその部分ではなく、その他の条件の帰結としてだと思うんだよね。単純パスのことを書いているのかどうかはわからないけど(X の閉鎖性のため前後の文脈を読むことができない)、違和感は自身で解消できるのではないか。■■■精進。D 問題。5秒を2秒以下に抑えた2つのポイント。1つ目は、1から Math.cbrt(N) の範囲で線形探索する x と y の差分だけど、N の偶奇を見れば対象を半分にできる。これで 2.5 秒になる。2つ目は、コンテスト中にはついに突き止められなかった二分探索の上限。x と y の上限を低く見積もりすぎて答えが見つからないということを繰り返していた。式をよく見よう。(y+d)**3-y**3 を展開して整理すれば dyy+ddy+ddd になる。d=1 のとき y が最小になり、これが N を超えないのだから、yy+y+1<=N の範囲で解を探すことになる。N のルートが上限だった。Ruby には上限を指定しない二分探索があるんだけど、これは遅い。上限を指定することで 2.5 秒が 1.7 秒になった。提出 #63960582 (AC / 1678 ms)。2桁ミリセックには遠く及ばないけどね、ちょっとした工夫で Ruby でも十分に間に合う制約でありました。Ruby での他の人の提出を見た。自分のが一番遅い。一番短い人の提出 #63901879 を見ると3乗根の範囲で線形探索をし、上限を指定しない二分探索をしているところは自分の5秒の解答と変わらない。それが 146 ms で済んでしまう理由は、5行目の早期の判定だと思う。線形探索範囲が半分になるどころではない。x と y の差分 d で N が割り切れないならそもそも二分探索を試す必要がない。それは xxx-yyy = (x-y)(xx+yx+yy) = d(xx+yx+yy) = N と因数分解すればわかる。この因数分解はコンテスト中にやっていたけど、xx+yx+yy を解の公式で解くというはおろか、x-y = d であり、N が d で割り切れるということもわかっていなかった。自分は、頭を使って問題を解こうとしていないな。手を動かしてとにかくやってみて運良く正しい答えが出るといいなあ、という態度で問題に当たっている。悲しいことにこれは怠惰故ではなく、頭の使い方を知らないということなのです。考えてるふりしかできない。だから下手の考え~って言われるのです。


2025年03月11日 (火) でかいのからちゃちいのまで AC アダプタが並んでるのを見て、邪魔やし共通化できひんのかなって思ったときに、USB が実質的な DC コンセントなんかなと初めて気がついた。PC と全く関係がないような卓上電気製品が USB から電源を取るというと、ジョークグッズか氾濫しすぎた USB の異常進化かと思っていたけど、どこにでも USB の口があるという以外にもメリットがあってああいう形態になっていたのかな。


2025年03月08日 (土) [AtCoder] 今日は AtCoder Beginner Contest 396 があった。自分のすべての提出。E を除いて F まで解いた。F は調子がいいときなら BIT を使うだけという感じで 15 分くらいで解いても不思議はないけども、今日は1時間かけた。E 問題はとっつきが悪く、方針が決まったあとでも具体的な実装に迷う難しさがあった。■A 問題 Triple Four。手を抜くつもりで正規表現でやったが罠があった。しかしその罠にはすでにかかったことがある! /(\d+)\s+\1\s+\1\s+/ というパターンを書いた。入力末尾の改行を保存しているので3番目が入力の末尾でもマッチするのでそこは罠ではない。罠というのは入力が "11 1 1" というケース。11 の末尾1桁だけを切り出してマッチしてはいけない。提出直前に気がついてテストしてパターンの先頭に \b を足した。\b は単語境界(\w と \s、\w と \W、\s と \S の間)にマッチするパターン。■B 問題 Card Pile。スタックが使えますかという問題。■C 問題 Buy Balls。かなり難しい。貪欲法でやろうとしたけど、どうやるべきか、本当に貪欲法でいいのか、すっきり答えが見通せなかった。黒より白の数が多くなってはいけない。だから基本的に黒を取ることにし、黒を取るときに同時に白を取るかどうかというオプションを考えることにした。それでいい? 白が先になくなる場合、黒が先になくなる場合、黒が負でも白と併せて正なら取るべきか、そのとき併せるべき白は何か、処理順によって判断が変わってくることはないか、考えるだに貪欲法で大丈夫か不安が募る。よーく考えて提出して AC。10 分弱かけた。■D 問題 Minimum XOR Path。制約で難しさを出すのが定番の D 問題で愚直 DFS でもない順列総当たり O(N!) が通るのは甘々です。といって前にも1回「甘々です」と書いているので、前例がないわけではない。■F 問題 Rotated Inversions。E よりとっつきが良かったので F 問題から考えた。k=0...M につれて転倒数の変化を数えれば良い。変化はある要素が 0 に落ちるタイミングで起こる。自分は最初左にあって大きい要素の数と、右にあって小さい要素の数を使って変化量を数えようとした。答えが合わないから、左にあって小さい要素と右にあって小さい要素を使って数えてみたり、左にあって大きい要素と小さい要素と右にあって小さい要素を使って数えてみたりして、最終的に左右にあって大きい要素と小さい要素の数を使って数えて答えが合った。途中で何度か考え直していたんだけど、なかなか全体像が見えなくて答えを出すのに4つの変数が必要だとわからなかった。4変数のどれも答えを出すのに必要なんだけど、どこまで考慮すれば十分かはそれほど明らかでなく、目についた不十分な変数の組み合わせで答えを出そうとしていた。■E 問題 Min of Restricted Sum。数学問題に見えて実はグラフ問題であり、やれば答えが出る。つながっている要素間ではある要素のあるビットの 0/1 が決まれば他のすべての要素の 0/1 が決まる。0 の数と 1 の数を見て 0 にするか 1 にするかを決めればいい。どうやるか。UnionFind と BFS でやったけど、制限時間いっぱいの 2995 ms かかっていてこれは遅いらしい。時間内に Ruby で通している人たちはそれぞれ 660 ms970 ms1303 ms しかかけていない。提出が早いほど早いのには残酷な格差を見て取ってしまう。■コンテスト成績証。6問解けてないしあまり早くもなかったけど水パフォ上位で +12。前回から AtCoder がデレてきている。


2025年03月07日 (金) [AtCoder] 精進。前々回の ABC394-F「Alkane」。問題は十分に理解できていたし、E 問題に手が付けられなかった分、E 問題に費やすべき時間も使ってじっくり落ち着いて実装をし、デバッグをしていたのだけど、22時13分の提出 #63052484 が (RE×1/WA×27/AC×31)、22時34分の提出 #63061106 が (WA×28/AC×32) で時間切れになっていた。それから約2週間放置していたのは、自分は何も考え漏らしも勘違いもしていないし、十分に考えを整理してデバッグして書き直しもしたので、あれが間違いならもう何もわからないというのが理由だった。■これが今日の提出 #63061106 (AC)。2週間ぶりに自分の提出を読み直してみたら、13 行目にこんなのがあった。cs.sort_by!(&:size) cs というのは数値配列で、数値を size プロパティに基づいてソートするというのは、ほぼ何もソートしていないのに等しい。だって Bignum でなければ 32 ビット整数なら4、64 ビット整数なら8に決まっているのが数値の size だから。この間違いは過去にもやったことがある。単純に .sort と書くべきところで .sort_by と書いてしまったときに、つい選んでしまって疑問を持ちにくいのが .sort_by(&:size) なのだと思う。しょーもない間違いで貴重な得点を失ったものだ。■解法について書く。テキトーに根を選んで DFS をした。再帰関数の戻り値はアルカンの構成要素になり得る C または H の数。たとえば子がないなら自分自身を H と数えて1を返す。アルカンを構成しうる子が4つ(以上)あるなら、自分自身を C として中心に据えてアルカンを完成させて答えを更新する。アルカンを構成しうる子が1つでもあってそれが単純な H でないなら、自分自身を H として加えてアルカンを完成させて答えを更新する。アルカンを構成しうる子が3つ(以上)あるなら、自分自身を C として中心に据えてアルカンを構成しうる子であるとして親に返す。子が7つも8つもあっても選べるのは最大で4つまでなのだから、できるだけ数が大きい子を選ばないといけない。そのためのソートだったのだけど、ソートできていなかったので WA が出ていた。「アルカンを構成しうる子」というワードについて。実はすべての子がアルカンを構成する(その子を H とみなす)。最初に実装を始めたときには明らかでなかったので思わず条件があるみたいに書いてしまっただけ。