https://github.com/abrudz/stencil
Thin cover for Dyalog APL's ⌺
https://github.com/abrudz/stencil
apl cellular-automata cellular-automaton code-golf codegolf dyalog-apl dyalog-library dyalogapl game-of-life gameoflife moore-neighborhoods neighbourhood stencil tio
Last synced: 2 months ago
JSON representation
Thin cover for Dyalog APL's ⌺
- Host: GitHub
- URL: https://github.com/abrudz/stencil
- Owner: abrudz
- License: mit
- Created: 2017-11-24T10:04:50.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2018-06-20T17:48:54.000Z (almost 7 years ago)
- Last Synced: 2025-02-10T15:30:36.536Z (4 months ago)
- Topics: apl, cellular-automata, cellular-automaton, code-golf, codegolf, dyalog-apl, dyalog-library, dyalogapl, game-of-life, gameoflife, moore-neighborhoods, neighbourhood, stencil, tio
- Language: APL
- Size: 21.5 KB
- Stars: 9
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Stencil
## Introduction
Stencil is a thin cover for [Dyalog APL](https://www.dyalog.com/)'s ⌺ [Stencil operator](http://help.dyalog.com/16.0/Content/Language/Primitive%20Operators/Stencil.htm) and is intended as golfing language and an easy interface for common tasks involving `⌺`. Stencil code can in fact easily be rewritten as normal Dyalog APL code.Feel free to contact me, [Adám](https://stackexchange.com/users/3114363/ad%C3%A1m), in Stack Exchange's [APL chat room](https://chat.stackexchange.com/rooms/52405/apl) to learn more about Stencil and Dyalog APL.
## In-APL Usage
Execute `2⎕FIX'file://path/Stencil.dyalog` to load the operator.
The syntax is `result←opts (code Stencil specs) input`, but `opts` is optional.
For the specifics of [`opts`](https://github.com/abrudz/Stencil/blob/master/README.md#command-line-options), [`code`](https://github.com/abrudz/Stencil/blob/master/README.md#code), and [`specs`](https://github.com/abrudz/Stencil/blob/master/README.md#arguments), see the linked guidance for the corresponding TIO fields.
Input is an array specifying the initial state.
| `opts` | `result` |
| :---: | --- |
| none | final state or last state before going to a previously encountered state |
| `∊` | vector of states |
| `≢` | scalar non-negative integer |
| `≡` | 0-by-0 numeric matrix |
| number | a state |If code is a function, then identifiers may be both single- and multi-letter, and spaces are needed to separate them, i.e. `me` is *not* equivalent to `m e`, and `⎕IO` is *not* set to `0` either. However, the predefined values listed [`below`](https://github.com/abrudz/Stencil/blob/master/README.md#code) *are* available.
## TIO User guide
[Try It Online](https://tio.run/#home) is a code testing website for many programming languages, both practical and recreational ones, made by Stack Exchange user [Dennis](https://codegolf.stackexchange.com/users/12012). The following describes the relevant fields when using [Stencil on TIO](https://tio.run/#stencil).
### Command-line options
This may be any one of the following options:| opt | Effect |
| :---: | --- |
| none | return final state or last state before going to a previously encountered state |
| `∊` | return list of states from input to final state or last state before going to a previously encountered state |
| `≢` | return the number of states in the above |
| `≡` | output states until stable, or forever if cyclic |
| number | return the state after that many states |combined with any of the following options:
| opt | Effect |
| :---: | --- |
| `P` | `┌───┐` Plane:
`│ │` left and right disconnected
`└───┘` lower and upper disconnected |
| `C` | `┌───┐` Cylinder:
`↑ ↑` left and right joined
`└───┘` lower and upper disconnected |
| `T` | `┌─→─┐` Torus:
`↑ ↑` left and right joined
`└─→─┘` lower and upper joined |
| `M` | `┌─→─┐` Möbius strip:
`│ │` left and right disconnected
`└─←─┘` lower and upper twist-joined |
| `K` | `┌─→─┐` Klein bottle:
`↑ ↑` left and right joined
`└─←─┘` lower and upper twist-joined |
| `R` | `┌─→─┐` Real projective plane:
`↑ ↓` left and right twist-joined
`└─←─┘` lower and upper twist-joined |
| `I` | `┌ ┐` Infinite:
` ` left and right expand and shrink as needed
`└ ┘` lower and upper expand and shrink as needed |### Code
This describes what shall be returned for each neighbourhood. It may be a function, or one or more character vectors.If a single character vector, then this forms the body (i.e. without outer curly braces) of a dfn left operand to
`⌺`. For more information about the `⌺` operator, see [its documentation](http://help.dyalog.com/16.0/Content/Language/Primitive%20Operators/Stencil.htm).If two character vectors, then the first will be used as a dfn snippet (
⍵
is appended to its right) to post-process the result(s).If three or more character vectors, then the last will additionally be used as a dfn snippet (
⍵
is appended to its right) to pre-process the input(s).Stencil provides some shortcuts not available to with the original `⌺`. All identifiers are expected to be single-letter, and no spaces are needed to separate them, i.e. `me` is equivalent to `m e`. The following values are pre-defined:
Note that all code runs with `⎕IO←0` (0-based **I**ndex **O**rigin).
Examples:
`3 5` will use 3-row, 5-column neighbourhoods
`⍪3 3` will use neighbourhoods of size 3 in every dimension, and step size
| name | Description |
| :---: | ------- |
| `⍵` | multi-dimensional Moore neighbourhood with self |
| `M` | vector of Moore neighbourhood with self |
| `m` | count of non-empty cells in the above |
| `E` | vector of moorE neighbourhood without self |
| `e` | count of non-empty cells in the above |
| `V` | vector of Von neumann neighbourhood with self |
| `v` | count of non-empty cells in the above |
| `N` | vector of von neumanN neighbourhood without self |
| `n` | count of non-empty cells in the above |
| `S` | scalar self |
| `s` | Boolean (1 or 0) for whether above is non-empty |
| `P` | vector of Booleans for each dimension whether it has been padded or not |
| `p` | number of dimensions which have been padded |
| `⍺` | vector of amounts of padding for each dimension |
| `W` | original input |
| `w` | flattened original input |
| `Y` | preprocessed input |
| `y` | flattened preprocessed input |In the above table, *Moore neighbordhood* means the entire n×m neighbourhood, while *von Neumann neighbourhood* means cells orthogonal to the self.
### Input
Each line is an APL expression for an initial state. Each will be processed separately.
### Arguments
This allows specifying the neighbourhood and step size. The arguments will be joined with spaces and executed as an APL expression to be used as right operand for `⌺`. Stencil provides two shortcuts not available to with original `⌺`. If a single size is given, it will be used for every dimension. If no size is given, size 3 will be used in every dimension.Examples:
`3 5` will use 3-row, 5-column neighbourhoods
`⍪5 3` will use neighbourhoods of size 5 in every dimension with a step size of 3 in every dimension
## Examples
### Hello, World!
Code: `S`
Input `Hello, World!`
Every character will be replaced by it**S**elf.
### Game of Life
Code: `3∊me`
A cell will be alive in the next genration if there are 3 live cells either counting itself or not.
To get just the next generation, add the command-line option `1`.
To list all generations, add the command-line options `∊`.
To calculate the period of a cyclic pattern (an [oscillator](https://en.wikipedia.org/wiki/Oscillator_(cellular_automaton)) or a [spaceship](https://en.wikipedia.org/wiki/Spaceship_(cellular_automaton)), add the command-line options `≢I`
To check whether a patter is a [still life](https://en.wikipedia.org/wiki/Still_life_(cellular_automaton)), add the command-line options `≢I` and let code be `1=` `3∊me`.
### Primality checker
Command-line option: `1`
Code: `~S∊1,∘.×⍨2+⍳S`
Input has one or more lists of integers. For each such **S**elf, it generates the integers from 0 to **S**elf-1 (`⍳S`), adds 2 (`2+`), giving from 2 to Self+1, creates a multiplication table (`∘.×⍨`), prepends a column of ones (`1,`), and asks whether the **S**elf is a member thereof (`S∊`), and then negates that (`~`).