diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2021-06-13 17:28:27 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2021-06-13 18:08:23 -0400 |
| commit | 7b64aec0c6c534d60b5b34195bee7a6aaf11713a (patch) | |
| tree | 19d776cbbb9772d56e88086222520141524b6db0 /doc | |
| parent | 5780ba1477d9b53fe4f9ec1135694fd95e7dca11 (diff) | |
Add documentation for Range
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/README.md | 1 | ||||
| -rw-r--r-- | doc/primitive.md | 2 | ||||
| -rw-r--r-- | doc/range.md | 91 |
3 files changed, 93 insertions, 1 deletions
diff --git a/doc/README.md b/doc/README.md index 9e3f3e3a..4183bcd6 100644 --- a/doc/README.md +++ b/doc/README.md @@ -43,6 +43,7 @@ Primitives: - [Mapping](map.md) (`¨⌜`) - [Ordering functions](order.md) (`∧∨⍋⍒`) - [Prefixes and Suffixes](prefixes.md) (`↑↓`) +- [Range](range.md) (`↕`) - [Reverse and Rotate](reverse.md) (`⌽`) - [Self-comparison functions](selfcmp.md) (`⊐⊒∊⍷`) - [Shift functions](shift.md) (`»«`) diff --git a/doc/primitive.md b/doc/primitive.md index ff40f843..2197d99e 100644 --- a/doc/primitive.md +++ b/doc/primitive.md @@ -41,7 +41,7 @@ Functions that have significant differences from APL functions are marked with a | `≍` | [Solo](couple.md)* | [Couple](couple.md)* | `↑` | [Prefixes](prefixes.md)* | [Take](https://aplwiki.com/wiki/Take) | `↓` | [Suffixes](prefixes.md)* | [Drop](https://aplwiki.com/wiki/Drop) -| `↕` | [Range](https://aplwiki.com/wiki/Index_Generator) | [Windows](windows.md)* +| `↕` | [Range](range.md) | [Windows](windows.md)* | `»` | [Nudge](shift.md)* | [Shift Before](shift.md)* | `«` | [Nudge Back](shift.md)* | [Shift After](shift.md)* | `⌽` | [Reverse](reverse.md) | [Rotate](reverse.md#rotate) diff --git a/doc/range.md b/doc/range.md new file mode 100644 index 00000000..846abdc5 --- /dev/null +++ b/doc/range.md @@ -0,0 +1,91 @@ +*View this file with results and syntax highlighting [here](https://mlochbaum.github.io/BQN/doc/range.html).* + +# Range + +Range (`↕`) is a monadic function that creates arrays of [indices](indices.md) (like APL's famous [iota](https://aplwiki.com/wiki/Index_Generator) function). Each element in the result is its own index. + + ↕ 6 + + ↕ 2‿3 + +It's really two different functions packed together: if `𝕩` is a natural number—a length—then it returns a list of numeric indices, but if it's a list of numbers, then it returns an array of list indices. This means the result always has [depth](depth.md) one more than the argument. + +The two kinds of index correspond to BQN's two selection functions: Select (`⊏`) works with indices along an axis, which are numbers, and Pick (`⊑`) works with element indices, which are lists. The examples below would fail if we swapped these around. Each result from Range is a length-6 list, but their elements are different. + + ↕6 + + (↕6) ⊏ "select" + + ↕⟨6⟩ + + (↕⟨6⟩) ⊑ " pick " + +They also correspond to Length (`≠`) and Shape (`≢`): for an array `a`, `↕≠a` gives the indices of major cells, while `↕≢a` gives the indices of all elements. + + a ← 4‿2⥊@ + + ↕ ≠ a + + ↕ ≢ a + +## Number range + +Calling `↕` on an atom, which must be a natural number, is the more common case. This gives us the list of natural numbers less than `𝕩` (and starting at `0`, the first natural number as BQN defines it). You can also get the first `b` integers starting at `a` with `a+↕b`, or the natural numbers from `a` to `b` with `a↓↕b`. + + ↕4 + + 5 + ↕4 + + 2 ↓ ↕4 + +The result of `↕𝕩` is a list of length `𝕩`, but doesn't include `𝕩` itself. That's just how counting starting at 0 works. It does mean we can create a length-0 list easily: + + ↕ 0 + +Like all other results of `↕` on a number, `↕0` has a fill of 0. + + 4 ↑ ↕0 + + 4 ↑ ↕3 + +Adding a character to a range produces a character range, with space as the fill. + + 'b' + ↕8 + + »⍟3 'b'+↕8 + +One interesting use of Range is to find, at each position in a boolean list, the most recent index that has a 1. To do this, first get the array of indices for `b`, `↕≠b`. Then multiply `b`, reducing indices where a `0` is found to 0. + + ⊢ b ← 0‿1‿1‿0‿0‿0‿1‿0 + + b ≍ ↕≠b + + b × ↕≠b + +Now at any given position the index of the last 1, if there is any, is the maximum of all the adjusted indices so far. That's a scan `` ⌈` ``. + + ⌈` b × ↕≠b + + (⌈` ⊢ × ↕∘≠) b # As a tacit function + +Where there aren't any previous 1s, this returns an index of 0, which is the same as the result where there is a 1 at index 0. If it's important to distinguish these possibilities, the indices can be increased by one, so that the result is 0 if there are no 1s, and 1 for a 1 at the start. To bring it back into alignment with the argument, either this result can be decreased by 1 or an initial element can be added to the argument. + + ⌈` b × 1 + ↕≠b + +## List range + +When the argument is a list of numbers, the result is an array of lists. + + ↕ 2‿3‿4 + +This array, which contains all possible choices of one natural number less than each element of `𝕩`, can also be produced using Range on numbers only, along with [Table](map.md#table) (`⌜`). + + (<⟨⟩) ∾⌜´ ↕¨ 2‿3‿4 + +The initial element for the [fold](fold.md) above is the result of `↕⟨⟩`, which contains the one possible list of no natural numbers. + + ↕ ⟨⟩ + +The result of Range can also be thought of as representing all possible numbers in a mixed-base system: for example, the argument `2‿3‿4` indicates three-digit numbers where the lowest digit works in base 4, the next in base 3, and the highest in base 2. Of course, fixed bases are used more often than mixed ones. Here are all the 3-digit binary numbers: + + ↕ 3⥊2 |
