5.2. 1-modifiers
4⊑•type∘•BQN∘⋈¨⊸⊔∧"+-×÷⋆√⌊⌈∧∨¬|≤<>≥=≠≡≢⊣⊢⥊∾≍⋈↑↓↕«»⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔!˙˜∘○⊸⟜⌾⊘◶⎊⎉˘⚇¨⌜⍟⁼´˝`"
"`¨´˘˙˜˝⁼⌜"
Undo '⁼
'の話は書いておきたい。
Fold '´
'
Fold '´
' は以下のように展開される。
F´ a‿b‿c‿d‿e → a F b F c F d F e
BQNは右から関数評価を行うことを思い出せば、これは右からのscanである事がわかる。
リストの先頭からのscanではないので、そうしたければF´⌽
というフレーズが必要になる。
この延長で初期値𝕨
が与えられた場合は以下のように展開される。
𝕨 F´ a‿b‿c‿d‿e → a F b F c F d F e F 𝕨
𝕨 F´⌽ a‿b‿c‿d‿e → e F d F c F b F a F 𝕨
F
の引数の一つをアキュムレーターだとすると直感に反してそれは右引数𝕩
に対応するので注意すること。
10{item F sum : item+10×sum}´⌽3‿5‿7 # 10を初期値とするアキュムレーターsumは左引数
10357
10{𝕨+10×𝕩}´⌽3‿5‿7 # 簡略版:アキュムレーターは𝕩
10357
uncurryとの関係
右引数がlength=2のリストに対するFoldを改めて書き下すと以下のようになる。
F´ a‿b → a F b
F
を二要素からなる1つの「タプル」を受け取る1引数関数だとすると
F´
は2引数関数である。
従って´
はuncurryの操作そのものである1。
ちなみに逆変換curry
は以下の通り∘⋈
なのだろう。
𝕨 F∘⋈ 𝕩 → F(𝕨⋈𝕩)
BQNのドキュメントにはこの関係について明記されてないのだが、興味を持った人が最初に見るであろうA quick start to BQNの最初の変数定義式(L5)にこの変換が出てくる。言われなくても気づけるものなのだろうか。
Cells '˘
'
配列の要素に対するmapではなく配列のmajor cellに対してmapを行う。 配列がrank=nの場合、major cellはrank=n-1の配列に相当し、配列はあたかもmajor cellのリストと見なされる。
返値は配列になるので同じshapeを持つ事が要求される。
The Cells modifier
˘
applies a function to major cells of its argument, much like Each applies to elements. Each result from 𝔽 becomes a major cell of the result, which means they must all have the same shape.
m ← 3‿3⥊↕9
┌─
╵ 0 1 2
3 4 5
6 7 8
┘
-∘¬¨m # 各要素に対するdecrement
┌─
╵ ¯1 0 1
2 3 4
5 6 7
┘
-∘¬˘m # major cellに対するdecrementだがrank多相により各要素に対するdecrementに帰着
┌─
╵ ¯1 0 1
2 3 4
5 6 7
┘
+´˘m # mにおいてはmajor cellは数値のリストに対応するのでfold可能
⟨ 3 12 21 ⟩
(↕+´)˘m # しかし長さが違うリストを返そうとするとエラー
Error: ˘: Incompatible result shapes (encountered shapes ⟨3⟩ and ⟨12⟩)
at (↕+´)˘m
^^^^^^
(¯3↑·↕+´)˘m # shapeが同じなら問題ない
┌─
╵ 0 1 2
9 10 11
18 19 20
┘
条件分岐
else節を持たない1方向分岐は引数𝕩
に対して𝔽
を𝕘
回繰り返し適用するRepeat '⍟
' で実装できる。
多方向分岐はリスト𝕘
の𝕗
番目の関数を𝕩
に対して適用するChoose '◶
' で実装できる。
他には条件分岐のblockが使える。
•_timed (CBQN)
実行時間を測るならこれか)profile
。
In BQN matrix, someone uses the F0
to compute the largest group of 1s.
#!/usr/bin/env cbqn
F0 ⇐ (0⌈´(-˜˝˘∘‿2⥊0⊸(/∾≠∾˜)))
F1 ⇐ {F s: ⊑0‿0{((⊑𝕩)⊸⌈⋈𝕨⊸×)𝕨+1⊑𝕩}´s}
F2 ⇐ {⌈´-˜´˘∘‿2⥊/≠´˘2↕0∾𝕩}
# F2 ⇐ {⌈´-˜´˘∘‿2⥊/≠´˘2↕0∾𝕩∾⟨0⟩}
seq ⇐ (100×1000×1000) •rand.Range 2
•Show "F0"⊸⋈ 10 F0•_timed seq
•Show "F1"⊸⋈ 2 F1•_timed seq
•Show "F2"⊸⋈ 10 F2•_timed seq
function | time by •_timed |
---|---|
F0 | 0.0916479 |
F1 | 5.9444225 |
F2 | 0.3276033 |
1-modifier glyphの出現頻度
4.3での計算を基にした1-modifiersの出現頻度は以下の通り。
•Show>>1⊏s4
┌─
╎ 3400 "¨"
2481 "´"
1527 "˜"
793 "˘"
549 "`"
508 "⌜"
263 "˝"
258 "⁼"
201 "˙"
┘