4.3 関数グリフの出現頻度

https://dzaima.github.io/paste/#0PdK5TsNAEAbgfp9iqBFiT69XAp6FB6GhCbYTB8KhBAQKVwQSlIggcRROmbfwk/DvjCDVavztXBsXdaRNws9Y76hv7vM56JL60XU@2mSor1vlvNbUPYu0lvo5f/ZlwqUHloWj9Y1y2hcIfbDURf58zDIi/eiHZUD6wy9liwLJm0mOUUoRhe6YOtwaVUxtoO5FWV8a6t4Yli5QXz0JRKKhQJ37XChrDGIV16GY0NJMZG7q/E@uL5WJMdFqKs552hCmUbnh3guUaYdwmGtLmE60lw8ultR9isIq2qUyAdn6@pZdEXOWb5EedU@YBojhADQgVs2E5mEGZ/@0ktohdzsDtZHW1yJtou6VYYFNTYfyFKg0rpXx2tIuu4CZ@8FEIDLWj7JeRK@OlHEh0LbAEq1X/KIO9Q5kRLTTnILhEXeE@UT7jHzeMP8/8Oy4egWWtz64EJhHmb4LRVttzeH8li0y2tzMohFq827nf3S15KjBWOPmFw%23BQN

のデータを元に関数の出現頻度表を作成しよう。

    s ← "3707 +    1243 ⊢    508 ⌜    291 ≍
    3400 ¨    1222 ⟜    489 ⊣    263 ˝
    3046 ⊸    1069 ⊏    473 ⌾    258 ⁼
    2661 ⊑     997 ≡    439 ⌈    225 «
    2481 ´     835 ∧    438 ⋈    201 ≥
    2118 ∾     793 ˘    436 ⊔    201 ˙
    1779 ×     734 !    430 ⌊    165 ⍋
    1763 -     709 >    378 »    162 ⍷
    1579 ≠     670 ⌽    374 ⊐    159 ⋆
    1554 ∘     635 ↓    374 ∊    156 ⊘
    1527 ˜     629 ¬    367 ○    120 ⎉
    1402 =     593 ↑    364 ≤     93 ⚇
    1355 /     582 ∨    356 |     75 ⊒
    1346 <     549 `    341 ≢     48 √
    1301 ↕     535 ◶    340 ⍉     39 ⍒
    1264 ⥊     525 ⍟    340 ÷     17 ⎊"
    s ' '⊸∾ ↩                     # 先頭に空白文字を追加し例外を消す
    s1 ← ' '¨⌾((s=@+10)⊸/)s # 改行を空白化
    s2 ← ∘‿2⥊1↓¨(" "⊸≢)¨⊸/1↓(+`' '⊸=)⊸⊔s1 # 空白文字列を区切りとしてグループ化
    s3 ← {num‿glyph : <⟨•Type •BQN glyph,•BQN num,glyph⟩}˘s2 # 整形
    s4 ← ∨¨(1⊸↓)¨¨3‿∘⥊3↓⊑¨⊸⊔s3    # 不要な部分を消して整列
    >>⊏s4                         # 関数のみ表示
┌─
╵ 3707 "+"
  2661 "⊑"
  2118 "∾"
  1779 "×"
  1763 "-"
  1579 "≠"
  1402 "="
  1355 "/"
  1346 "<"
  1301 "↕"
  1264 "⥊"
  1243 "⊢"
  1069 "⊏"
  997  "≡"
  835  "∧"
  734  "!"
  709  ">"
  670  "⌽"
  635  "↓"
  629  "¬"
  593  "↑"
  582  "∨"
  489  "⊣"
  439  "⌈"
  438  "⋈"
  436  "⊔"
  430  "⌊"
  378  "»"
  374  "⊐"
  374  "∊"
  364  "≤"
  356  "|"
  341  "≢"
  340  "⍉"
  340  "÷"
  291  "≍"
  225  "«"
  201  "≥"
  165  "⍋"
  162  "⍷"
  159  "⋆"
  75   "⊒"
  48   "√"
  39   "⍒"
           ┘

よりよいプログラムへの道

    s ' '⊸∾ ↩                     # 先頭に空白文字を追加し例外を消す
    s1 ← ' '¨⌾((s=@+10)⊸/)s # 改行を空白化
    s2 ← ∘‿2⥊1↓¨(" "⊸≢)¨⊸/1↓(+`' '⊸=)⊸⊔s1 # 空白文字列を区切りとしてグループ化
    s
⟨ 1 0 2 3 0 0 4 5 6 0 7 0 8 0⟩
    m ← (0⊸=)s
⟨ 0 1 0 0 1 1 0 0 0 1 0 1 0 0⟩
    g ← +´(0⊸=)s
⟨ 0 1 1 1 2 3 3 3 3 4 4 5 5 5⟩
    g⊔s
⟨ ⟨1⟩ ⟨0 2 3⟩ ⟨0⟩ ⟨0 4 5 6⟩ ⟨0 7⟩ ⟨0 8⟩ ⟨0⟩⟩

ここで

  1. 各グループが削除したい0で始まっている
  2. 0だけのグループができている。この要素は排除しなければならない。
  3. 最初の要素だけ0で始まっていない

という問題が起きている。 1から考えよう。gから0の位置を強制的に0にすればよい。0の位置はmで求められる。

    m
⟨ 0 1 0 0 1 1 0 0 0 1 0 1 0 0⟩
    ¬m
⟨ 1 0 1 1 0 0 1 1 1 0 1 0 1 1⟩
    +´(0⊸=)s
⟨ 0 1 1 1 2 3 3 3 3 4 4 5 5 5⟩
    g ← (¬m)×+´(0⊸=)s
⟨ 0 1 0 0 2 0 3 3 3 0 4 0 5 5⟩
    g⊔s
⟨ ⟨1 0 0 0 0 0 0⟩ ⟨2 3⟩ ⟨4 5 6⟩ ⟨7⟩ ⟨8⟩⟩

⟨1 0 0 0 0 0 0⟩というリストは0に対して与えられた添字と最初のグループに与えられた添字がどちらも0であることから作られている。0に対しては¯1の添字を与えることができればの結果から自動的に省かれる。そこで添字の「操作」を行って望ましいgを作ろう。

    ¬m
⟨ 1 0 1 1 0 0 1 1 1 0 1 0 1 1⟩
    1++´(0⊸=)s
⟨ 1 2 2 2 3 4 4 4 4 5 5 6 6 6⟩
    (¬m)×1++´(0⊸=)s
⟨ 1 0 2 2 0 0 4 4 4 0 5 0 6 6⟩
    g ← ¯1+(¬m)×1++´(0⊸=)s
⟨ 0 ¯1 1 1 ¯1 ¯1 3 3 3 ¯1 4 ¯1 5 5⟩
    g⊔s
⟨ ⟨1⟩ ⟨2 3⟩ ⟨4 5 6⟩ ⟨7⟩ ⟨8⟩⟩
    Partition ← {w 𝕊 x : x⊔˜-¬({+`1∾<´˘2↕𝕩}׬)x∊w}

open it online