/ 最近 .rdf 追記 設定 本棚

脳log[2022-10-16~]



2022年10月16日 (日) [AtCoder] 今日は ARC151 があった。終了3分前にノルマの2完達成。自分のすべての提出。1完も珍しくないのですごく嬉しい。開始9分1完(早解き)と終了3分前2完(遅解き)のパフォーマンス差がないに等しいとしても、とても嬉しい(昨日書いた通り>20221015)。■A 問題「Equal Hamming Distances」。ハミング距離って初めて知った(たぶん聞いたことはあるけど興味がない)。定義をよく読む。i 文字目の不一致を数えた数らしい。S,T から等ハミング距離にあって辞書順最小の文字列を作る問題。先頭から見ていって、S[i]/T[i] が一致しているなら 0/1 どちらを選んでも(ハミング距離が増えるにしても増えないにしても) S,T 双方からのハミング距離は変わらないので 0 を選ぶ。S[i]/T[i] が異なるときはどうするか。一方を選べば他方からのハミング距離(だけ)が増えるのでバランスを取らなければいけない。そこで不可能(-1)を出力するケースが理解できた。S,T の不一致が奇数文字のときはバランスが取れないので不可。偶数のとき、その半分の回数だけ S[i] を選び、同じく半分の回数だけ T[i] を選ぶと S,T 双方からのハミング距離が等しくなる。もちろんできるだけ S[i]/T[i] のうち 0 の方を選ぶ。■B 問題「A < AP」。解説のように対称性に気付けるわけがないので、先頭から見ていって見ている文字で初めて A<AP になるケースを数える方針で考えた。そのために4つの場合分けを長らく、1時間以上考えていた。4つというのは、A[i] と A[P[i]] のそれぞれが初出の場合と既出の場合(k<i として A[P[k]] としてすでに参照されているかどうか)。既出の要素というのは A[k]=A[P[k]] という拘束条件があって独立して M 通りの値を割り当てられるわけではないので、それをまず知る必要があると思ったのだ。A[i] と A[P[i]] がどちらも未出の場合は簡単で M*(M-1)/2 通りの割り当てパターンがあり、その他の未出の要素それぞれにも M 通りの割り当てがある。しかし既出の要素の扱いに困った。値が連動する既出の要素は……。まず、既出の要素であってもほぼ自由に M 通りの値を割り当てられるということがわからなかった。k<i となる k において A[k]=A[P[k]] という拘束条件があり、A[P[k]] = A[i] であることも A[P[k]] = A[P[i]] であることもあるけど、A[i] と A[P[i]] に関わらない限り連動するその値は M 通りから好きに選べるとわかっていなかった。なにか拘束条件が連鎖して階段状の大小関係があると思っていた。既出の要素でもほぼ未出の要素と同じように M 通りから選べるとわかったときに答えの計算方法がわかり、既出要素のグループを見出して UnionFind を持ち出すところまで時間はかからなかった。B 問題は難しい問題なのではなくて、隅々まで理解するのに時間がかかる読み手に問題があった。まあ、そこが難しさなんだけど。


2022年10月15日 (土) [AtCoder] 今日はパナソニックグループプログラミングコンテスト2022(AtCoder Beginner Contest 273)があった。コンテスト成績証 - AtCoder自分のすべての提出。F 問題に黄色の壁があったからなのかなんなのか、2度目の黄パフォは棚ぼた以外のなにものでもなかったな。AC までにかかった時間が A=1分半、B=3分、C=8分(うち問題文が理解できるまで5回以上読み直すのに体感10分)、D=14分、E=8分なのだから、単に解ける問題を早く解いただけ。せめて時間があるときは壁を越えたい(早解き遅解きでパフォーマンスに報いがないとしても)。■いいパフォーマンスだったので気分良く振り返っていこう。■A 問題「A Recursive Function」。他の人の提出にある factorial という関数名を見て、階乗を求める関数だったと気がついた。N が 1 ギガとかでもなければ定義の通りに実装するだけです。Hash のデフォルトプロックを使って実装した。再帰関数と比べると…… 1.(今回は不要だったけどフィボナッチ数を求める場合などに)自動でメモ化される。2.再帰の停止条件が関数の外に書けてすっきりする。3.(デメリット)呼び出しが遅い。■B 問題「Broken Rounding」。他の人の提出で知ったんだけど、Ruby の Integer は高機能な round メソッドを持っていてそれが使える。そういうメソッドは小数にしか期待していないので知らなかったな。K 回割って K 回掛けて答えを出した。■C 問題「(K+1)-th Largest Number」。問題文が理解できないしサンプルの解説が理解できないし何を出力するのかもわからなかった。嫌がらせなの? 5回以上読み直したし2回は飛ばして D 問題へ行こうとした。問題の輪郭がやっと見えてきても大きい数が K 個なのか K 種類なのかという罠があり、ほんと嫌がらせなの? ひとたび理解できれば Array#tally で得られる数字がほぼ答えだし、足りない 0 を補えばそれが答え。それだけのことをよくも難しく文章にしたと思う。■D 問題「LRUD Instructions」。グリッド問題は制約を一番に見る。すべてのマスをなぞれるのかどうか。今回はできない。壁の数(の上限)がおなじみ 20 万個だから、グリッドはメモリ上に実体を確保せず仮想的な存在にしておき、壁の位置を扱いやすく蓄えてそれを処理対象にする。行ごと列ごとにソート列として持っておいて二分探索をする。変数名について。他の(複数の)人の提出を見ると、ある行にある壁の座標(列番号)列を蓄えるのに R や R の付く名前を使っていた(列に対しては C が付く名前)。こういうデータとアクセス方法になる。R[r1] = [c1,c2,c3] Ruby の AC 提出を順番に見ていったけど、独特な例外を除いてほぼそういう、自分と逆の命名なのがおもしろいなと思った。どう読むんだろう。walls_of_row[r1] という感じで、添字の r1 が変数名の row を修飾すると読むのだろうか。それは良い。でもそれを縮めたときに何を残すのか。R[r1] や row[r1] にすると、「行 r1 (のデータ)」しか読み取れない。すべてがワーキングメモリに収まる競プロではそれで十分ではある。しかし……。自分が C[r1] = [c1,c2,c2] という名前を付ける気持ちは、C(olumns) of r1 = c1,c2,c3 というもの。利用するときは cs = C[r1] という形で名前が揃う。名前を揃えるのが「間違ったコードは間違って見えるようにする」原則に沿うと思うからそうしている。行に対して列以外の別次元の情報が1種類か2種類付け加わったときにどうするかを考えてみてもいいと思う。■E 問題「Notebook」。4つの操作を読んでデータがどういう形に育つかを考える。必要なのは末尾の1字。ただし ADD の履歴が必要。DELETE & ADD により分岐して先が分かれる。ノートはポインタ。ノートの存在によりすべての履歴が最後まで参照できなければいけない(データを使い捨てにできない)。自分は逆向きのリンクリストだと思ったけど、Git のデータ構造を連想した人はさすが。2009 年出版で今ではもう古い部分もあるかもだけど根幹は変わらないだろう、『入門 Git』(著:濱野 純(Junio C Hamano))にそういうことも書いてある。Git は名前の変更を追跡していないヒューリスティクスでやっているということは書いてなかったかな。その疑問にはっきり答えてくれたのは GitHub ブログ「コミットはスナップショットであり差分ではない」。コミットがスナップショットなら名前の変更(スナップショット間の関係)のありかが気になるというもの。きちんと答えてくれていた。■F 問題「Hammer 2」は DP かなと思ったけど頭のいいことが思いつかないのでプライオリティキューで素直にシミュレーションをした(そもそも頭の良さは思いつきの良さではないという説)。結果は (TLE×28/AC×74)。まあそうでしょう。後日>20221019■解説放送「パナソニックグループプログラミングコンテスト2022(AtCoder Beginner Contest 273) - YouTube」で E 問題に関連して木構造の Undo/Redo の話題が出ていた。それは TATEditor のことか。履歴の見せ方が難しいだろうなあとは思う。


2022年10月14日 (金) [AtCoder] 精進。日曜にあった ARC150-B「Make Divisible」(水 diff)。何か所かで (B+Y)=(A+X)*M の X と M のどちらかを全探索すればいいと読んだ。当日は X だけを全探索する TLE 解を書いていた>提出 #35546704。M を探索すればいいというけれど、いつ M を探索すべきなのか、M の範囲をどこに限れるのか、M を決め打ってから X と Y を求めるプロセスは、どれもよくわからない。■提出 #35646915 (AC / 276 Byte / 108 ms)。M の範囲は Y が B を超えないように選んだつもり。X と Y の求め方については、A*M が B 以上の時は X=0 として Y=B-A*M。A*M が B 未満の時は不足分を X*M で補って B を超えた分が Y とした。答え合わせをしながらたどりついたのであって、ヒントがあってさえよくわからなかった。


2022年10月13日 (木) [AtCoder] 精進。第三回 PAST 過去問-N「入れ替えと並び替え」。どこかのブログで転倒している位置を管理することでソート全体を QlogQ で抑えられると読んだ。愚直にソートすると QNlogN になるところ。■提出 #35609961 (AC / 777 Byte / 1174 ms)。Ruby に平衡二分探索木はないし BIT でやったら TLE 間違いなしだったので配列を酷使する運任せの解答。ローカルでは5秒越えのケースもあったけどジャッジサーバーは速かった。


2022年10月12日 (水) 何日か前の新聞で TOPIX に関連する不可解な記述があった。「株式市場では近年、指数に連動した投資手法が拡大。金融機関では個人投資家ら向けに、TOPIX の値動きに連動するように幅広い株式に投資する上場投資信託(ETF)などが売られている。ETF を通して、国際的には緩い基準で選ばれた企業にも資金が入ることになり、投資家からは「企業努力に関わらず投資してもらえるのはいかがなものか」「株価形成にゆがみが出かねない」との指摘が出ていた。」 不可解なのは投資家のコメント。発言者の姿が見えない。最初のコメントからは、努力をしていない企業が投資を受けるのはけしからん、という主張が窺えるけど、自分はそれが無批判に受け入れるべき真理だとは思えないし(「じゃあトップ1社が総取りすべきですか?」「あなた自身の投資先は誰から見ても妥当なものですか? そもそも妥当さの基準とは?」)、だから他人の投資行動を批判するその投資家の姿と立ち位置が見たくなるが見えない。2番目のコメントはナイーブすぎると思う。歪みのない株価の形成要因ってなんですか。IR 情報ですか。それだけですか。日銀と年金はどうですか。戦争はどちらですか。誰かが選ぶ主要 500 銘柄はいいけど、誰かが選ばずにまとめただけの 2168 銘柄はダメなんですか。(株価を歪める力が低すぎるという意味で)ダメかもしれないけどそれを心配するのは東証であって投資家のあなたではないのではありませんか。指標にする場合でもしない場合でも、自分にとって都合がいいだけの TOPIX が欲しいという主張と違いますか。そういう主張を載せる朝日新聞は誰の代弁者をしているんですか。自分は金融にあるのは利害の調整だけであり「べき論」があるとは思ってないから、投資家の口を借りていながら人間不在で書かれた記事のこの部分は、利害を隠したおためごかしの垂れ流しにしか見えなかった。TOPIX の変更に関係づけて日本経済の利害を書いてくれ。いちプレイヤーはどうでもいい。そこにしか興味がない。


2022年10月11日 (火) [AtCoder] 精進。日曜にあった ARC150-C「Path and Subsequence」(青 diff)。答えを見ました。「「各頂点にたどり着いた時、最も悪くてBの何番目までを部分列として持った状態になっているか」を始点から各頂点までの距離としてダイクストラ法をする」■当日は愚直 TLE 解を書いていた>提出 #35545127。TLE を解消するには状態をまとめなければいけないと考えたのだけど、単純パスであることを保証するためにパスを記録することが避けられないとも考えていた。たとえば B 数列に要素が 1,2,1,2 と連続する部分があり、グラフ上の隣接する2頂点に対応する A 数列の値が 1 と 2 であるときに、2頂点を何度も往復することで B 数列上を 1,2,1,2 と進むことは単純パスではないために許されない。当日考えていたのはここまで。ここで2×2の状態を考えてみよう。単純ではないパスを通る不正を行って N にたどり着き、その時点で B 数列を最後までたどっている場合と B 数列を余らせている場合。不正を行わず単純パスで N にたどり着き、その時点で B 数列を最後までたどっている場合と余らせている場合。この問題を解くにあたり見つけたいのは、B 数列を余らせた状態で N にたどり着く単純パスの存在。それが存在すれば答えは No だし、見つからなければ答えは Yes。あってはならないのは、B 数列を余らせた状態で N にたどり着く単純パスが存在しないのに、同じ頂点を何度か通る不正を行った非単純パスでは B 数列を余らせた状態で N にたどり着けるという事態。ちょっと考えればわかるけど、同じ頂点を何度か通って N に至る非単純パスは寄り道を省いて単純パスに書き換えられる。寄り道をすることで生じる違いは、B 数列を余分に先に進められること。B 数列を不正で先に進めても間違いは生じない。というわけでパスを記録する代わりに B 数列上をどこまで進んだかで頂点の状態を表すことができ、その最小値を代表にすることができる。■提出 #35571487 (AC / 397 ms)。道具はすでに持っているので実装はできる。シンタックスエラーのようなすぐわかるミスを除けばバグなしで上から下まで書き下している。足りないのは考える頭。これは道具が足りていないよりも厳しい状況。■■■A 問題「Continuous 1」(緑 diff) は場合分けでやった。2WA と 2RE のち AC。尺取りの方が間違えにくいらしいけど、解法を選ぶ贅沢は与えられていない。場合分けとはこう……。文字列を 0 で切って 1? だけからなる文字列について考える。長さ K 未満の文字列が 1 を含んでいたら 0 通りだから No。長さ K 以上の複数の文字列が 1 を含んでいたら 0 通りだから No。1 を含む文字列が 0 個のとき、? からなる長さが K より大きな文字列が存在してはならず、長さが K の文字列が1つだけ存在するときに限り答えは Yes。1 を含む長さ K 以上の文字列が 1 個だけあるとき、それの長さが K なら答えは Yes。K より大きいときは 1 の左右端の位置を調べてその幅が K より大きければ No。K ならば Yes。K 未満で左右に ? が存在していれば No。さもなければ Yes。これで全部。複数考えられる場合と1つも考えられない場合をどちらも除外しなければいけないのだけど、意識の切り替えがうまくいかないときに間違えると思う。■地獄の場合分けといえば ABC160-D「Line++」(緑 diff) を思い出す。他に解法がいくつもあって全然場合分け地獄に入り込む理由がないんだけど、時間内に AC にたどりつけない人間が解法を選べるわけもなく>20200701p01


2022年10月10日 (月) 暑くなってきたな、で扇風機を出すのはいいけども、寒くなってきたな、で片付けるのは間違いなんです。暑い日がなくなってきたな、で片付けないと。なので判定に2、3週間を要します(まだ出てる)。


2022年10月08日 (土) [AtCoder] 精進。今日あった ABC272-E「Add and Mex」(水 diff)。時間中には TLE 解しか作れなかった>提出 #35502733。それを作るのに1時間近くかかっていたこともあって、それ以上詰めることができなかった。改善の目途は TLE が出た直後には立っていて、さっきの提出の 9 行目と 10 行目、操作回数と A の初期値の差が A の添字の倍数ではないときにループをスキップする処理が無駄で、添字と同じだけのインターバルを空けてループの処理対象にすれば条件判断もスキップもいらない。■提出 #35510000 (AC / 421 Byte / 726 ms)。解答の筋道がなかなか立たなくて時間を無駄にした。2、3の要素を組み合わせるにあたり計算量的に間に合うやり方がなかなか見つからなかった。最終的には、答えるべき「A に含まれない最小の非負整数」を 0 からカウントアップしていって、その数字が答えになる操作回数を逆に求めた。それを効率的にやる。


2022年10月03日 (月) [AtCoder] 精進1。第11回 PAST-H「2つのナップサック」。ブログを読んでデータの持ち方を教えてもらわないと解けなかった。ほんとうに、ほんのちょっとの応用力もない。■提出 #35384069 (TLE×2 / 2138 ms)。138 ms だけオーバーした。■提出 #35384125 (AC / 1045 ms)。デフォルト値を -1.0/0 から -10**12 に変えただけで劇的に改善した。意味的には無限大にしたいし遅いのを知りつつそう書いてきたんだけど、TLE になるほど遅くなるなら制約の範囲外の整数値を使うしかないなあ。■■■精進2。第11回 PAST-I「お片付け」。これも同ブログでデータの持ち方を教えてもらった。自分で書いた TLE 解では文字列化した盤面全体をキーにしていた。だけど記録すべき特徴というのはすぬけくんの位置と荷物の位置という2つの数値だけなんだな。なんでわからないんだろう。■提出 #35384851 (AC / 1950 ms)。制限時間4秒なのでまあまあ。


2022年10月02日 (日) [AtCoder] 今日は ARC149。B 問題「Two LIS Sum」(緑 diff) のみの1完だったのでそれについて書く。並び順が連動する A、B 2つの順列を好きに並べ替えて A の LIS と B の LIS の長さの和を最大化する問題。最初はソートの問題かなと思った。左下から右上に向かって点(A,B)を並べて、双方にとっていい感じに点を選んでいくのかなと。サンプルが合わせられないので次は DP かなと思った。ある点を選んだとして、次に選んで LIS を増加させられる点は第Ⅰ象限にあたる位置にしかないので。これも実は最初の解法と違いがなくサンプルが合わせられなかったので、次は先に A の LIS を最大化(N に等しい)したあとで B を最大化する方法を考えた。どうやって双方のバランスを取るかを考えているうちに、常にあちらを立てればこちらが立たずが成り立つことに気がついた。つまり、A のソート列を壊して(LIS(A)を1減らして)増やせる B の LIS もまた1が上限なのだから、手を入れる意味がない。A または B をソートした後で他方の LIS をすれば答えが出る。■提出 #35352966 (AC / 180 Byte / 501 ms)。今日はこれで終わり。解説を見たらすること自体は簡単なので、ネタバレ前に通せて良かった。■時間内には解けなかった A 問題についてはね……。XXXXXXX が M の倍数であるとはどういうことか、X、XX、XXX……と累積的に求めていった余りが0になることだ、ということがそもそもわからなかった。余りが0なら倍数だということがわからなかった。わからないはずがないと思うんだけど、M が素数か合成数かでなんか違いがあるのかなーとかぼんやりしたことを考えていた。そういう日もある(そういう日そうでない日の割合、つきつめて、そうでない日の存在については何も述べていない)。


2022年10月01日 (土) [AtCoder] 今日は京セラプログラミングコンテスト2022(AtCoder Beginner Contest 271) があった。結果は ABDE の4完。C 問題「Manga」の WA×1 が謎すぎる>提出 #35280504。解説を読んでも解決しない。他の人の AC 提出とランダム入力を組み合わせて答えを突き合わせても一向に不一致が検出されない。ひょっとして全 X 巻の X+1 巻目を読んだつもりになってやしないかと制約を確かめたりもしたけど、そういう落とし穴はなかった。ほんと謎。まだわからん。■違いが検出されないのは比較してなかったからだった! 直すと比較的簡単に違いが見つかったのだけど、たとえば入力が N=10; A=3,4,4,5,6,7,8,9,9,10 のとき、自分の答えが 7 で、AC 提出の2つが 8 を返している。あー!!! ほとんど同じ構成だけど事前に重複している本を処理していた tinsep19 さんの提出 #35285896 が処方箋だった。最初に見たときは自分も同じことをしてると思ったけど、同じではなかったのだな。■提出 #35324229 (AC / 224 Byte / 228 ms)。すがすがしいほどの完敗だよ。ローカルで小さいケースをいくつも作ってデバッグしていたんだけど(成果なし)、答えを用意する人間が間違っていてはどうにもならない。プログラムは完全に意図通りに動作していたが答えを間違えていた。どうでもいいことだけど提出したスクリプトの変数 read は過去分詞なので【réd】と読みます。どうでもいいね。■勇気づけられるツイート。「アライグマ「ABC271だったのだ! C問題は最初の方の巻から順に「読みたい巻なら読む。もう読んだ巻なら売る。読みたい巻より先なら、一番後ろの巻から2冊売って読みたい巻を買う」を繰り返せばいいのだ!」 フェネック「それだとA=(2,2,3,4)のときにWAだねー」 https://t.co/Jh41vbHFqP https://t.co/MLXPSXt5tm」 ちなみにこれに「じゃあ答えを二分探索するのだ!」というツイートが続く。この流れも想定の範疇にあった。別の解法なら落とし穴を踏まないのではないか二分探索ではどうかと考えていた。でもそういうときに意地になっちゃうんだよね。最初の解法を修正することに拘ってプランBが選べない。そういう性質だと知っているし開き直って受け入れている。■■■精進。今日の ABC271-F「XOR on Grid Path」(ぎりぎり青 diff)。半分全列挙の問題が半分全列挙だと教えられる前に解けたためしがない。強いて言えば制約の数字に特徴が現れるが、手掛かりがなさすぎる。■提出 #35327661 (AC / 477 Byte / 472 ms)。最初から半分全列挙だとわかっていればやることはほとんど愚直解法なので。やっぱり TLE だよね、というのを確認していたものを手直ししただけ。■TLE 回避のために半分全列挙でない問題を半分全列挙みたいに解いたことがあるけど、無駄すぎる>20220726。点数とパフォーマンスにつなげたい。


2022年09月29日 (木) [正規表現] 「正規表現:曖昧なパターンはエンジンによって動作が変わる(教訓) - Qiita」■これは ECMAScript の仕様がタコなんだよね。undefined(マッチなし)と空文字列(ゼロ幅マッチ)を同一視した結果。「@2013-11-09 ECMAScript(3rd&5th ed.)の、Rubyとは異なる、残念正規表現仕様


2022年09月28日 (水) 十三機兵防衛圏クリアした! すっごくえっちだった!■■■わき腹や太ももをひとなでするだけでもケレン味たっぷりでいやらしいのだ。東雲諒子さんが断トツ残念でかわいそうな人。なかなかハッピーエンドが見えないけど郷登クンは無限の愛情をもって保護監視下に置いてほしい。それで十分かはわからないけど、それ以外では想像できない。1985 年というセレクトがずるい。HI-C、ピクニックという小道具がずるい。スケバンのユキは名前がそのまますぎ。ピッタリだけど。年代固定というあたりで時間移動⇔空間移動は予想できる。技術を生み出した未来がすでに遠い過去とはわからなかった。第二世代機を生かすのが難しい。待ち時間が長すぎて敵に近寄れないし攻めるにも守るにも攻撃機会を逸しがち。汎用性があって耐久性が1番だというけど、ダメージを食らうとランクが下がるので耐久性は長所ではないし、汎用性に関しては第一世代が“万能”すぎて霞む。テレポートフィールドとの連携が必須。それでも戦局に置いていかれがち。第四世代は支援に徹すると敵撃破による回復がないために EP が枯渇しがち。そして意外に E.M.P. 兵装を持っていない。戦闘は STRONG でもサクサク S ランクを取って進んでいけるのだけどラストステージの1つ前で S ランクを取るのが難しかった。ターミナルに陣取っていても極太レーザーを食らうのに、いつでもタイミング良くターンが回ってきて回避したりシールドを張ったりできるわけではないので。何回かやって全員2桁ダメージに抑えたときに S ランクを取った。最終ステージが熱かった。だんだん消耗戦の様相を呈してきて、EP が尽きる HP が尽きそう次々回復にまわって戦える機体が減っていく、まだ終わらないのかもう限界だというまさにその時に決着がついた。時間とは違う指標で終了を決めたのかと疑ったレベル。鞍部家のテレビが若干謎の存在だった。インタラクトできるから必ず消していたけど(うるさいいらない騒音源。『家族八景』を読むといいよ。調べたら 1970 年あたりの連載らしい。さらに古いなあ)、なぜ消せるのか、なぜそれで問題ないのか。他に選べなくなるまで鞍部十郎のシナリオをプロローグのまま放置してたんだけど、そのおかげで柴くんの特異さが際立っていた(そういえばこんなキャラいたなあ。でも他の人のシナリオでは見なかったなあ)。果たして……。関ヶ原と冬坂のノーヘル二人乗りに現実感がなくて、検索したら 1985 年にはもうヘルメットの義務化がほぼ完了してたみたいなので、昔はシートベルトいらないヘルメットいらない免許いらないという話ではないと思う。過渡期だったかもしれず実態が必ず規則を反映していたかはわからないけど。過熱状態の説明が作中に一切ないのはどうかと思った(なかったよね?)。