diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2021-06-20 22:29:48 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2021-06-21 11:01:28 -0400 |
| commit | 57b40621a807f089cbc08c51005b9f0b70377ba3 (patch) | |
| tree | ff782cf63caead009a0224f0f2a48432742a9da5 | |
| parent | f6caae0ac5d20e87f3453b1bc01967116f48d0dd (diff) | |
Add most of Scan documentation
| -rw-r--r-- | doc/README.md | 1 | ||||
| -rw-r--r-- | doc/primitive.md | 2 | ||||
| -rw-r--r-- | doc/scan.md | 118 | ||||
| -rw-r--r-- | docs/doc/index.html | 1 | ||||
| -rw-r--r-- | docs/doc/primitive.html | 2 | ||||
| -rw-r--r-- | docs/doc/scan.html | 144 |
6 files changed, 266 insertions, 2 deletions
diff --git a/doc/README.md b/doc/README.md index 41af9fcb..75edcdda 100644 --- a/doc/README.md +++ b/doc/README.md @@ -46,6 +46,7 @@ Primitives: - [Prefixes and Suffixes](prefixes.md) (`↑↓`) - [Range](range.md) (`↕`) - [Reverse and Rotate](reverse.md) (`⌽`) +- [Scan](scan.md) (`` ` ``) - [Self-comparison functions](selfcmp.md) (`⊐⊒∊⍷`) - [Shift functions](shift.md) (`»«`) - [Solo, Couple, and Merge](couple.md) (`≍>`) diff --git a/doc/primitive.md b/doc/primitive.md index 6ed52c23..7ce5e3d5 100644 --- a/doc/primitive.md +++ b/doc/primitive.md @@ -88,4 +88,4 @@ Other modifiers control array traversal and iteration. In three cases a simpler `⁼` | Undo | `⍟` | Repeat `´` | [Fold](fold.md) | `˝` | [Insert](fold.md) | -`` ` `` | Scan | +`` ` `` | [Scan](scan.md) | diff --git a/doc/scan.md b/doc/scan.md new file mode 100644 index 00000000..ab4b6669 --- /dev/null +++ b/doc/scan.md @@ -0,0 +1,118 @@ +*View this file with results and syntax highlighting [here](https://mlochbaum.github.io/BQN/doc/scan.html).* + +# Scan + +<!--GEN +f ← •BQN fn ← "⌈" ⋄ ft ← Highlight fn +xt ← Highlight∘•Repr¨ xv ← 2‿0‿0‿3‿5‿1 +zt ← Highlight∘•Repr¨ f` xv +d ← 56‿42 + +rc ← At "class=code|stroke-width=1.5|rx=12" +Ge ← "g"⊸At⊸Enc +g ← "fill=currentColor|stroke-linecap=round|text-anchor=middle|font-family=BQN,monospace" +cg ← "font-size=18px|text-anchor=end" +bg ← "class=bluegreen|stroke-width=3|style=fill:none|opacity=0.6" +lg ← "class=lilac|stroke-width=2" + +Text ← ("text" Attr "dy"‿"0.32em"∾ ·Pos d⊸×)⊸Enc +Path ← "path" Elt "d"≍○<⊢ +Line ← "line" Elt ("xy"≍⌜"12")≍˘○⥊ ·FmtNum d×⊢ + +Brak ← { + l ← 6‿15 + P ← ∾"M l l "∾¨ ·FmtNum∘⥊ ∾ + Path ∾ (((-⊸≍0.4)+0‿¯1⊏𝕨)((0‿¯1×l)+d×≍)⌜𝕩) P¨ ≍○<⟜⌽ -⌾⊑⊸≍l +} +VL ← ≍˜⊸≍⟜((≍⟜-0.3)⊸+) + +tx ← ↕≠xt ⋄ ty ← 0.75+4.7×↕2 +sy ← (2÷˜+´ty)+3×0.5-˜(↕÷-⟜1) ≠sx←1↓tx +dim ← ⟨2.5+≠tx,0.75+1⊑ty⟩ ⋄ sh ← ¯2.3‿0 + +((∾˜d)×((-∾+˜)1‿0.3)+sh∾dim) SVG g Ge ⟨ + "rect" Elt rc ∾ (Pos d×sh)∾"width"‿"height"≍˘FmtNum d×dim + lg Ge Line¨ ∾⟨ + ⟨tx ⊑⊸VL ty⟩ + ∾ sx {𝕨⊸VL¨⌽⌾(1⊸⊑)<˘ty≍˘𝕩}¨ sy + sx ((¯1‿¯0.14≍¯0.3‿¯0.07)+≍)¨ sy + ⟩ + cg Ge (¯1.1≍¨ty) Text¨ ≍○<⟜(ft∾(Highlight"`")∾⊢) "𝕩" + "font-size=21px" Ge (⍉tx≍⌜ty) Text¨ xt≍zt + "font-size=19px" Ge sx (≍ Text ft˙)¨ sy + bg Ge tx⊸Brak¨ ty +⟩ +--> + +The 1-modifier Scan (`` ` ``) moves along the first axis of the array `𝕩`, building up an array of results by applying `𝔽` repeatedly beginning with `𝕨` or `⊏𝕩`. It's related to the fold modifiers, and most closely resembles the [APL2-style reduction](fold.md#apl2-reduction) `¨˝`, but it traverses the array in forward rather than reverse index order, and includes all intermediate results of `𝔽` in its output instead of just the final one. + +BQN's Scan is ordered differently from Scan in APL. Both include one result for each non-empty prefix of `𝕩`. In BQN this is a left-to-right fold, so that each new result requires one application of `𝔽`. APL uses a right-to-left ordering, which matches with reduction, but requires starting over at the end for each new prefix, except in special cases. If needed, this definition can be obtained with a fold on each [prefix](prefixes.md) except the first (which is empty). In the particular case of `-⍀`, that nested solution isn't needed: negate odd-indexed elements and then apply `` +` ``. + +Scan also differs from Fold or Insert in that it never depends on `𝔽`'s identity element, because scanning over an empty array simply returns that array. + +## Examples + +The best-known use of Scan is the [prefix sum](https://en.wikipedia.org/wiki/Prefix_sum) of a list, in which each element of the result is the sum of that element and all the ones before it. With a [shift](shift.md) this can be modified to sum the previous elements only. + + +` 2‿4‿3‿1 + + +`»2‿4‿3‿1 # Exclusive prefix sum + +The pattern is generalized to any function `𝔽`. With an operand of `×`, it can find the first *n* factorials. With `⌈`, it returns the largest element so far. + + ×` 1+↕6 + + ⌈` ¯1‿¯2‿0‿4‿2‿1‿5‿¯2 + +If provided, `𝕨` gives a starting element for Scan (actually a starting *cell*, so a single element should be [enclosed](enclose.md)). Below it ensures that all results of `` ⌈` `` are at least `0`. In either valence, the shape of the result is always the same as the shape of `𝕩`. + + 0 ⌈` ¯1‿¯2‿0‿4‿2‿1‿5‿¯2 + +To see the structure of the computation, it can be helpful to use a symbolic operand `𝔽` that returns a string describing its own application. + + {"("∾𝕨∾")𝔽"∾𝕩}` "a"‿"b"‿"c"‿"d" + + (<"w") {"("∾𝕨∾")𝔽"∾𝕩}` "a"‿"b"‿"c"‿"d" + +The left argument in each result element is always the previous element, if there is one. Result elements are produced in index order and this element will be reused, rather than computing it again. This can be confirmed by adding a counter to `𝔽`, which shows here that scanning a 10-element list makes 9 calls (supplying an initial value would make it 10). + + c←0 + {c+↩1⋄𝕨+𝕩}` ↕10 + c + +Some other useful scans apply to boolean lists. The function `` ∨` `` tests whether this or any previous element is 1, so that the result starts at 0 but permanently switches to 1 as soon as the first 1 is found. Similarly, `` ∧` `` turns all instances of 1 after the first 0 to 0. + + ∨` 0‿0‿1‿0‿0‿1‿0‿1 + + ∧` 1‿1‿1‿0‿0‿1‿0‿1 + +A more complicated boolean scan, which depends on the left-to-right ordering, is `` <` ``. It turns off every other 1 in a group of them—can you see why? One use is to resolve questions regarding backslash escaping: the simple example below removes backslashes except those that are escaped by more backslashes. + + <` 0‿0‿1‿1‿1‿0‿0‿1‿1‿1‿1 + + {¬<`'\'=𝕩}⊸/ "ab\\\rs\\\\" + +### Reverse scan + +We've discussed how the scan moves forward along `𝕩`, so that each time `𝔽` takes an old result as `𝕨` and a new value as `𝕩`. This means that results correspond to prefixes and go left to right on each one. Since the most important scans have associative, commutative operands, the left-to-right ordering often doesn't make a difference. But sometimes a suffix rather than prefix scan is wanted. For these cases, Scan Under [Reverse](reverse.md) (`` `⌾⌽ ``) does the trick. + + ∨` 0‿0‿1‿0‿0‿1‿0 + + ∨`⌾⌽ 0‿0‿1‿0‿0‿1‿0 + +This function reverses the input, does the scan, and reverses the output. Perhaps not so easy to visualize, but a symbolic operand will again show what it's doing: + + {"("∾𝕨∾")𝔽"∾𝕩}`⌾⌽ "a"‿"b"‿"c"‿"d" + +The new value is still the right argument to `𝔽`, even though with the reversal it's to the left of any values previously seen. If `𝔽` isn't commutative, and this is the wrong order, then `` 𝔽˜` `` will switch it around. + + {"("∾𝕨∾")𝔽"∾𝕩}˜`⌾⌽ "a"‿"b"‿"c"‿"d" + + +### Higher ranks + +Scan moves along the [leading axis](leading.md) of `𝕩`. Results are produced in index order. + + ⊢ a ← ¯2‿0.25‿'a'‿∞ ∾ 3‿4⥊¯1‿0‿1 + + +` a diff --git a/docs/doc/index.html b/docs/doc/index.html index 6d0a3dad..9e75330b 100644 --- a/docs/doc/index.html +++ b/docs/doc/index.html @@ -52,6 +52,7 @@ <li><a href="prefixes.html">Prefixes and Suffixes</a> (<code><span class='Function'>↑↓</span></code>)</li> <li><a href="range.html">Range</a> (<code><span class='Function'>↕</span></code>)</li> <li><a href="reverse.html">Reverse and Rotate</a> (<code><span class='Function'>⌽</span></code>)</li> +<li><a href="scan.html">Scan</a> (<code><span class='Modifier'>`</span></code>)</li> <li><a href="selfcmp.html">Self-comparison functions</a> (<code><span class='Function'>⊐⊒∊⍷</span></code>)</li> <li><a href="shift.html">Shift functions</a> (<code><span class='Function'>»«</span></code>)</li> <li><a href="couple.html">Solo, Couple, and Merge</a> (<code><span class='Function'>≍></span></code>)</li> diff --git a/docs/doc/primitive.html b/docs/doc/primitive.html index 79792f24..e7601d2c 100644 --- a/docs/doc/primitive.html +++ b/docs/doc/primitive.html @@ -524,7 +524,7 @@ </tr> <tr> <td><code><span class='Modifier'>`</span></code></td> -<td>Scan</td> +<td><a href="scan.html">Scan</a></td> <td></td> <td></td> </tr> diff --git a/docs/doc/scan.html b/docs/doc/scan.html new file mode 100644 index 00000000..64deae85 --- /dev/null +++ b/docs/doc/scan.html @@ -0,0 +1,144 @@ +<head> + <link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/> + <link href="../style.css" rel="stylesheet"/> + <title>BQN: Scan</title> +</head> +<div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a> / <a href="../index.html">main</a> / <a href="index.html">doc</a></div> +<h1 id="scan">Scan</h1> +<svg viewBox='-184.8 -12.6 588 285.6'> + <g fill='currentColor' stroke-linecap='round' text-anchor='middle' font-family='BQN,monospace'> + <rect class='code' stroke-width='1.5' rx='12' x='-128.8' y='0' width='476' height='260.4'/> + <g class='lilac' stroke-width='2'> + <line x1='0' x2='0' y1='44.1' y2='216.3'/> + <line x1='56' x2='56' y1='44.1' y2='54.6'/> + <line x1='56' x2='56' y1='79.8' y2='216.3'/> + <line x1='112' x2='112' y1='44.1' y2='86.1'/> + <line x1='112' x2='112' y1='111.3' y2='216.3'/> + <line x1='168' x2='168' y1='44.1' y2='117.6'/> + <line x1='168' x2='168' y1='142.8' y2='216.3'/> + <line x1='224' x2='224' y1='44.1' y2='149.1'/> + <line x1='224' x2='224' y1='174.3' y2='216.3'/> + <line x1='280' x2='280' y1='44.1' y2='180.6'/> + <line x1='280' x2='280' y1='205.8' y2='216.3'/> + <line x1='0' x2='48.16' y1='54.6' y2='64.26'/> + <line x1='56' x2='104.16' y1='86.1' y2='95.76'/> + <line x1='112' x2='160.16' y1='117.6' y2='127.26'/> + <line x1='168' x2='216.16' y1='149.1' y2='158.76'/> + <line x1='224' x2='272.16' y1='180.6' y2='190.26'/> + </g> + <g font-size='18px' text-anchor='end'> + <text dy='0.32em' x='-61.6' y='31.5'>𝕩</text> + <text dy='0.32em' x='-61.6' y='228.9'><tspan class='Function'>⌈</tspan><tspan class='Modifier'>`</tspan>𝕩</text> + </g> + <g font-size='21px'> + <text dy='0.32em' x='0' y='31.5'><tspan class='Number'>2</tspan></text> + <text dy='0.32em' x='56' y='31.5'><tspan class='Number'>0</tspan></text> + <text dy='0.32em' x='112' y='31.5'><tspan class='Number'>0</tspan></text> + <text dy='0.32em' x='168' y='31.5'><tspan class='Number'>3</tspan></text> + <text dy='0.32em' x='224' y='31.5'><tspan class='Number'>5</tspan></text> + <text dy='0.32em' x='280' y='31.5'><tspan class='Number'>1</tspan></text> + <text dy='0.32em' x='0' y='228.9'><tspan class='Number'>2</tspan></text> + <text dy='0.32em' x='56' y='228.9'><tspan class='Number'>2</tspan></text> + <text dy='0.32em' x='112' y='228.9'><tspan class='Number'>2</tspan></text> + <text dy='0.32em' x='168' y='228.9'><tspan class='Number'>3</tspan></text> + <text dy='0.32em' x='224' y='228.9'><tspan class='Number'>5</tspan></text> + <text dy='0.32em' x='280' y='228.9'><tspan class='Number'>5</tspan></text> + </g> + <g font-size='19px'> + <text dy='0.32em' x='56' y='67.2'><tspan class='Function'>⌈</tspan></text> + <text dy='0.32em' x='112' y='98.7'><tspan class='Function'>⌈</tspan></text> + <text dy='0.32em' x='168' y='130.2'><tspan class='Function'>⌈</tspan></text> + <text dy='0.32em' x='224' y='161.7'><tspan class='Function'>⌈</tspan></text> + <text dy='0.32em' x='280' y='193.2'><tspan class='Function'>⌈</tspan></text> + </g> + <g class='bluegreen' stroke-width='3' style='fill:none' opacity='0.6'> + <path d='M-22.4 16.5l-6 15l6 15M302.4 16.5l6 15l-6 15'/> + <path d='M-22.4 213.9l-6 15l6 15M302.4 213.9l6 15l-6 15'/> + </g> + </g> +</svg> + +<p>The 1-modifier Scan (<code><span class='Modifier'>`</span></code>) moves along the first axis of the array <code><span class='Value'>𝕩</span></code>, building up an array of results by applying <code><span class='Function'>𝔽</span></code> repeatedly beginning with <code><span class='Value'>𝕨</span></code> or <code><span class='Function'>⊏</span><span class='Value'>𝕩</span></code>. It's related to the fold modifiers, and most closely resembles the <a href="fold.html#apl2-reduction">APL2-style reduction</a> <code><span class='Modifier'>¨˝</span></code>, but it traverses the array in forward rather than reverse index order, and includes all intermediate results of <code><span class='Function'>𝔽</span></code> in its output instead of just the final one.</p> +<p>BQN's Scan is ordered differently from Scan in APL. Both include one result for each non-empty prefix of <code><span class='Value'>𝕩</span></code>. In BQN this is a left-to-right fold, so that each new result requires one application of <code><span class='Function'>𝔽</span></code>. APL uses a right-to-left ordering, which matches with reduction, but requires starting over at the end for each new prefix, except in special cases. If needed, this definition can be obtained with a fold on each <a href="prefixes.html">prefix</a> except the first (which is empty). In the particular case of <code><span class='Function'>-</span><span class='Value'>⍀</span></code>, that nested solution isn't needed: negate odd-indexed elements and then apply <code><span class='Function'>+</span><span class='Modifier'>`</span></code>.</p> +<p>Scan also differs from Fold or Insert in that it never depends on <code><span class='Function'>𝔽</span></code>'s identity element, because scanning over an empty array simply returns that array.</p> +<h2 id="examples">Examples</h2> +<p>The best-known use of Scan is the <a href="https://en.wikipedia.org/wiki/Prefix_sum">prefix sum</a> of a list, in which each element of the result is the sum of that element and all the ones before it. With a <a href="shift.html">shift</a> this can be modified to sum the previous elements only.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=K2AgMuKAvzTigL8z4oC/MQoKK2DCuzLigL804oC/M+KAvzEgICMgRXhjbHVzaXZlIHByZWZpeCBzdW0=">↗️</a><pre> <span class='Function'>+</span><span class='Modifier'>`</span> <span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span> +⟨ 2 6 9 10 ⟩ + + <span class='Function'>+</span><span class='Modifier'>`</span><span class='Function'>»</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>1</span> <span class='Comment'># Exclusive prefix sum +</span>⟨ 0 2 6 9 ⟩ +</pre> +<p>The pattern is generalized to any function <code><span class='Function'>𝔽</span></code>. With an operand of <code><span class='Function'>×</span></code>, it can find the first <em>n</em> factorials. With <code><span class='Function'>⌈</span></code>, it returns the largest element so far.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=w5dgIDEr4oaVNgoK4oyIYCDCrzHigL/CrzLigL8w4oC/NOKAvzLigL8x4oC/NeKAv8KvMg==">↗️</a><pre> <span class='Function'>×</span><span class='Modifier'>`</span> <span class='Number'>1</span><span class='Function'>+↕</span><span class='Number'>6</span> +⟨ 1 2 6 24 120 720 ⟩ + + <span class='Function'>⌈</span><span class='Modifier'>`</span> <span class='Number'>¯1</span><span class='Ligature'>‿</span><span class='Number'>¯2</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>¯2</span> +⟨ ¯1 ¯1 0 4 4 4 5 5 ⟩ +</pre> +<p>If provided, <code><span class='Value'>𝕨</span></code> gives a starting element for Scan (actually a starting <em>cell</em>, so a single element should be <a href="enclose.html">enclosed</a>). Below it ensures that all results of <code><span class='Function'>⌈</span><span class='Modifier'>`</span></code> are at least <code><span class='Number'>0</span></code>. In either valence, the shape of the result is always the same as the shape of <code><span class='Value'>𝕩</span></code>.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=MCDijIhgIMKvMeKAv8KvMuKAvzDigL804oC/MuKAvzHigL814oC/wq8y">↗️</a><pre> <span class='Number'>0</span> <span class='Function'>⌈</span><span class='Modifier'>`</span> <span class='Number'>¯1</span><span class='Ligature'>‿</span><span class='Number'>¯2</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Ligature'>‿</span><span class='Number'>2</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>5</span><span class='Ligature'>‿</span><span class='Number'>¯2</span> +⟨ 0 0 0 4 4 4 5 5 ⟩ +</pre> +<p>To see the structure of the computation, it can be helpful to use a symbolic operand <code><span class='Function'>𝔽</span></code> that returns a string describing its own application.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eyIoIuKIvvCdlajiiL4iKfCdlL0i4oi+8J2VqX1gICJhIuKAvyJiIuKAvyJjIuKAvyJkIgoKKDwidyIpIHsiKCLiiL7wnZWo4oi+IinwnZS9IuKIvvCdlal9YCAiYSLigL8iYiLigL8iYyLigL8iZCI=">↗️</a><pre> <span class='Brace'>{</span><span class='String'>"("</span><span class='Function'>∾</span><span class='Value'>𝕨</span><span class='Function'>∾</span><span class='String'>")𝔽"</span><span class='Function'>∾</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier'>`</span> <span class='String'>"a"</span><span class='Ligature'>‿</span><span class='String'>"b"</span><span class='Ligature'>‿</span><span class='String'>"c"</span><span class='Ligature'>‿</span><span class='String'>"d"</span> +⟨ "a" "(a)𝔽b" "((a)𝔽b)𝔽c" "(((a)𝔽b)𝔽c)𝔽d" ⟩ + + <span class='Paren'>(</span><span class='Function'><</span><span class='String'>"w"</span><span class='Paren'>)</span> <span class='Brace'>{</span><span class='String'>"("</span><span class='Function'>∾</span><span class='Value'>𝕨</span><span class='Function'>∾</span><span class='String'>")𝔽"</span><span class='Function'>∾</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier'>`</span> <span class='String'>"a"</span><span class='Ligature'>‿</span><span class='String'>"b"</span><span class='Ligature'>‿</span><span class='String'>"c"</span><span class='Ligature'>‿</span><span class='String'>"d"</span> +⟨ "(w)𝔽a" "((w)𝔽a)𝔽b" "(((w)𝔽a)𝔽b)𝔽c" "((((w)𝔽a)𝔽b)𝔽c)𝔽d" ⟩ +</pre> +<p>The left argument in each result element is always the previous element, if there is one. Result elements are produced in index order and this element will be reused, rather than computing it again. This can be confirmed by adding a counter to <code><span class='Function'>𝔽</span></code>, which shows here that scanning a 10-element list makes 9 calls (supplying an initial value would make it 10).</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=Y+KGkDAKe2Mr4oapMeKLhPCdlagr8J2VqX1gIOKGlTEwCmM=">↗️</a><pre> <span class='Value'>c</span><span class='Gets'>←</span><span class='Number'>0</span> + <span class='Brace'>{</span><span class='Value'>c</span><span class='Function'>+</span><span class='Gets'>↩</span><span class='Number'>1</span><span class='Separator'>⋄</span><span class='Value'>𝕨</span><span class='Function'>+</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier'>`</span> <span class='Function'>↕</span><span class='Number'>10</span> +⟨ 0 1 3 6 10 15 21 28 36 45 ⟩ + <span class='Value'>c</span> +9 +</pre> +<p>Some other useful scans apply to boolean lists. The function <code><span class='Function'>∨</span><span class='Modifier'>`</span></code> tests whether this or any previous element is 1, so that the result starts at 0 but permanently switches to 1 as soon as the first 1 is found. Similarly, <code><span class='Function'>∧</span><span class='Modifier'>`</span></code> turns all instances of 1 after the first 0 to 0.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oioYCAw4oC/MOKAvzHigL8w4oC/MOKAvzHigL8w4oC/MQoK4oinYCAx4oC/MeKAvzHigL8w4oC/MOKAvzHigL8w4oC/MQ==">↗️</a><pre> <span class='Function'>∨</span><span class='Modifier'>`</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span> +⟨ 0 0 1 1 1 1 1 1 ⟩ + + <span class='Function'>∧</span><span class='Modifier'>`</span> <span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span> +⟨ 1 1 1 0 0 0 0 0 ⟩ +</pre> +<p>A more complicated boolean scan, which depends on the left-to-right ordering, is <code><span class='Function'><</span><span class='Modifier'>`</span></code>. It turns off every other 1 in a group of them—can you see why? One use is to resolve questions regarding backslash escaping: the simple example below removes backslashes except those that are escaped by more backslashes.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=PGAgMOKAvzDigL8x4oC/MeKAvzHigL8w4oC/MOKAvzHigL8x4oC/MeKAvzEKCnvCrDxgJ1wnPfCdlal94oq4LyAiYWJcXFxyc1xcXFwi">↗️</a><pre> <span class='Function'><</span><span class='Modifier'>`</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>1</span> +⟨ 0 0 1 0 1 0 0 1 0 1 0 ⟩ + + <span class='Brace'>{</span><span class='Function'>¬<</span><span class='Modifier'>`</span><span class='String'>'\'</span><span class='Function'>=</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier2'>⊸</span><span class='Function'>/</span> <span class='String'>"ab\\\rs\\\\"</span> +"ab\rs\\" +</pre> +<h3 id="reverse-scan">Reverse scan</h3> +<p>We've discussed how the scan moves forward along <code><span class='Value'>𝕩</span></code>, so that each time <code><span class='Function'>𝔽</span></code> takes an old result as <code><span class='Value'>𝕨</span></code> and a new value as <code><span class='Value'>𝕩</span></code>. This means that results correspond to prefixes and go left to right on each one. Since the most important scans have associative, commutative operands, the left-to-right ordering often doesn't make a difference. But sometimes a suffix rather than prefix scan is wanted. For these cases, Scan Under <a href="reverse.html">Reverse</a> (<code><span class='Modifier'>`</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</span></code>) does the trick.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oioYCAgIDDigL8w4oC/MeKAvzDigL8w4oC/MeKAvzAKCuKIqGDijL7ijL0gMOKAvzDigL8x4oC/MOKAvzDigL8x4oC/MA==">↗️</a><pre> <span class='Function'>∨</span><span class='Modifier'>`</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span> +⟨ 0 0 1 1 1 1 1 ⟩ + + <span class='Function'>∨</span><span class='Modifier'>`</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</span> <span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span><span class='Ligature'>‿</span><span class='Number'>0</span> +⟨ 1 1 1 1 1 1 0 ⟩ +</pre> +<p>This function reverses the input, does the scan, and reverses the output. Perhaps not so easy to visualize, but a symbolic operand will again show what it's doing:</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eyIoIuKIvvCdlajiiL4iKfCdlL0i4oi+8J2VqX1g4oy+4oy9ICJhIuKAvyJiIuKAvyJjIuKAvyJkIg==">↗️</a><pre> <span class='Brace'>{</span><span class='String'>"("</span><span class='Function'>∾</span><span class='Value'>𝕨</span><span class='Function'>∾</span><span class='String'>")𝔽"</span><span class='Function'>∾</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier'>`</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</span> <span class='String'>"a"</span><span class='Ligature'>‿</span><span class='String'>"b"</span><span class='Ligature'>‿</span><span class='String'>"c"</span><span class='Ligature'>‿</span><span class='String'>"d"</span> +⟨ "(((d)𝔽c)𝔽b)𝔽a" "((d)𝔽c)𝔽b" "(d)𝔽c" "d" ⟩ +</pre> +<p>The new value is still the right argument to <code><span class='Function'>𝔽</span></code>, even though with the reversal it's to the left of any values previously seen. If <code><span class='Function'>𝔽</span></code> isn't commutative, and this is the wrong order, then <code><span class='Function'>𝔽</span><span class='Modifier'>˜`</span></code> will switch it around.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=eyIoIuKIvvCdlajiiL4iKfCdlL0i4oi+8J2VqX3LnGDijL7ijL0gImEi4oC/ImIi4oC/ImMi4oC/ImQi">↗️</a><pre> <span class='Brace'>{</span><span class='String'>"("</span><span class='Function'>∾</span><span class='Value'>𝕨</span><span class='Function'>∾</span><span class='String'>")𝔽"</span><span class='Function'>∾</span><span class='Value'>𝕩</span><span class='Brace'>}</span><span class='Modifier'>˜`</span><span class='Modifier2'>⌾</span><span class='Function'>⌽</span> <span class='String'>"a"</span><span class='Ligature'>‿</span><span class='String'>"b"</span><span class='Ligature'>‿</span><span class='String'>"c"</span><span class='Ligature'>‿</span><span class='String'>"d"</span> +⟨ "(a)𝔽(b)𝔽(c)𝔽d" "(b)𝔽(c)𝔽d" "(c)𝔽d" "d" ⟩ +</pre> +<h3 id="higher-ranks">Higher ranks</h3> +<p>Scan moves along the <a href="leading.html">leading axis</a> of <code><span class='Value'>𝕩</span></code>. Results are produced in index order.</p> +<a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=4oqiIGEg4oaQIMKvMuKAvzAuMjXigL8nYSfigL/iiJ4g4oi+IDPigL804qWKwq8x4oC/MOKAvzEKCitgIGE=">↗️</a><pre> <span class='Function'>⊢</span> <span class='Value'>a</span> <span class='Gets'>←</span> <span class='Number'>¯2</span><span class='Ligature'>‿</span><span class='Number'>0.25</span><span class='Ligature'>‿</span><span class='String'>'a'</span><span class='Ligature'>‿</span><span class='Number'>∞</span> <span class='Function'>∾</span> <span class='Number'>3</span><span class='Ligature'>‿</span><span class='Number'>4</span><span class='Function'>⥊</span><span class='Number'>¯1</span><span class='Ligature'>‿</span><span class='Number'>0</span><span class='Ligature'>‿</span><span class='Number'>1</span> +┌─ +╵ ¯2 0.25 'a' ∞ + ¯1 0 1 ¯1 + 0 1 ¯1 0 + 1 ¯1 0 1 + ┘ + + <span class='Function'>+</span><span class='Modifier'>`</span> <span class='Value'>a</span> +┌─ +╵ ¯2 0.25 'a' ∞ + ¯3 0.25 'b' ∞ + ¯3 1.25 'a' ∞ + ¯2 0.25 'a' ∞ + ┘ +</pre> |
