Welcome back. At the end of the last section we saved our workspace. If you would like to continue to save your work as you go, please:
Day2
and change into that namespace.You are of course welcome to simply proceed through each section with a )CLEAR
workspace.
Dyalog provides a native IDE for Microsoft Windows, and the Remote IDE for macOS and Linux. As well as the text-editor-like APL session, these provide some additional tools and shortcuts to make working with Dyalog easier. Click here to learn about some of these.
We introduced stranding to show how it formed vectors before the application of dyadic functions, for example:
2 + 2 2 + 2
2 + 2 (2 + 2)
(2 + 2) 2 + 2
Stranding is a useful way to form arrays. Generally, arrays separated by spaces form vectors. Experiment with the examples below, and notice the difference between stranding a b
and catenation a,b
.
2 3⍴'DY' 'AL' 'OG'
'a' 'b' 'c'
'a' 'bc'
'a','b','c'
'a','bc'
mixed←3 3⍴1 2 3 'a' 'b' 'c' ⍝ Simple mixed-type array
mixed2←3 3⍴1 2 3 'abc' ⍝ Nested mixed-type array
Note that the prototypical element of a numeric array is the number zero 0
and of a character array is a space ' '
character (⎕UCS 32
).
bnm←2 3⍴⍬ ⍝ Blank numeric matrix
bcm←3 2⍴'' ⍝ Blank character matrix
(⎕UCS 32)=bcm
Below are some more examples to demonstrate the difference between catenation, first-axis catenation ⍪
and stranding.
3 1⍴mixed bnm bcm
⍪mixed bnm bcm
↑mixed bnm bcm
mixed,bcm
mixed⍪bcm
mixed⍪bnm
3 3⍴mixed,bcm
3 3⍴mixed bnm,bcm
A simple scalar is a rank-0 array which contains itself as its value.
'a'≡⊃'a' ⍝ The disclose of a simple scalar is itself
42≡⊂42 ⍝ As is the enclose
'abc'≡⊃'abc' ⍝ Disclose on a simple array picks the first element
'abc'≡⊂'abc' ⍝ Enclosing an array results in a nested scalar
When does (a b)≡a,b
?
When does (↑a b)≡a⍪b
?
Experiment with the following expressions to determine what the each ¨
and bind ∘
operators do in this context.
's',¨'ong' 'ink' 'and'
'lph',¨'ong' 'ink' 'and'
(1 2)(2 2)(3 1)⍴¨3 4 5
2 2∘⍴¨3 4 5
(⍴∘3 4 5)¨2 2
Sometimes we would like a function to accept one or more option or parameter arguments.
For example
'bob'{⍺∘≡¨⍵}'bob' 'dave' 'jim'
1 0 0
'bob'{⍺∘≡¨⍵}'bob'
0 0 0
Why does the second expression above return three values? This is remedied using the enclose-if-simple function (monadic ⊆
).
{'bob'∘≡¨⊆⍵}'bob'
1
We can define stranding as the Strand
function.
Strand←{(⊂⍺),⊆⍵} ⍝ A Stranding function
'bob'Strand'dave'Strand'jim'
┌───┬────┬───┐
│bob│dave│jim│
└───┴────┴───┘
Or as the function Strand2←{⍺⍵}
.
We are going to do some text processing on a dictionary of words.
If you have access to the internet, the following expressions will download a text file dictionary (917kB in size) and store it as a nested vector of character vectors named words
.
]Load HttpCommand
words ← (⎕UCS 10) {(⍺≠⍵)⊆⍵} (HttpCommand.Get'https://tinyurl.com/y7asendy').Data
If you have the file on your computer (maybe you were given it on a USB drive, for example) then you can load it into your workspace from disk using the following expressions.
(content encoding newline) ← ⎕NGET'/path/to/words.txt'
words ← (⎕UCS newline) (≠⊆⊢) content
Now answer the following questions about words
.
How many words have at least 3 'e'
s in them?
How many words have exactly two consecutive 'e'
s in them?
The first three such words are Aberdeen
Abderdeen's
and Aileen
.
What is the shortest word with two consecutive 'a'
s?
What words have three consecutive double letters? For example, mississippi
does not but misseetto
does. Misseetto is not a real word.
A palindrome is the same when reversed. For example, racecar is a palindrome but racecat is not.
How many palindromes are there in words
?
Which palindrome in words
is the longest?
Try the following dfns with various numeric arguments and consider the following:
{⍺←1 1 ⋄ ⍵=2:⍺ ⋄ (⍺,(+/¯2↑⍺))∇⍵-1}
Give the function an appropriate name.
When a function calls itself like this it is called recursion. APL tends to rely less on explicit iteration and recursion than most popular programming languages, but it is good to be able to do it when you need to.
If a function gets stuck in an infinite loop, use Action → Interrupt
in the menu. You can also use the key combination Ctrl+Break
to interrupt a running function.
Write the shortest dfn which causes infinite recursion.
Write the shortest dfn which causes infinite recursion unless its argument is 0
.
The factorial function multiplies integers up to ⍵
. Write the factorial function as a recursive dfn called Factorial
. Use the primitive !N
factorial function to check your solution.
Write an expression for the factorial function as a reduction (an expression which includes f/
for some function f
).
Dyalog’s grade-up ⍋
and grade-down ⍒
functions are able to sort any array. However, it is interesting and useful to look at other approaches to sorting.
Here is a function ‘NSort’ for sorting numeric lists.
NSort←{0=⍴⍵:⍬ ⋄ (U/⍵),∇(~U←⍵=⌊/⍵)/⍵}
Try NSort
with some numeric arguments. Here it is presented piece-by-piece. For each comment prompt ⍝
, write a brief description of what that part of the function does. The first one has been done for you.
NSort←{
0=⍴⍵:⍬ ⍝ Reached end of list, return empty numeric vector
⋄ ⍝
(U/⍵), ⍝
∇ ⍝
(~U←⍵=⌊/⍵) ⍝
/⍵ ⍝
}
Below is a function TSort
for sorting character matrices.
TSort←{⍺[((⍴⍵)[2])S ⍺⍳⍵]}
S←{⍺=0:⍵ ⋄ (⍺-1)S ⍵[⍋⍵[;⍺];]}
Examine TSort
and replace ⍺
below with an appropriate left argument to sort the character matrix WORDS
.
WORDS←↑'DOLPHIN' 'BRACKEN' 'SAUCER' 'MAGNET' 'FLOP'
⍺ TSort WORDS
BRACKEN
DOLPHIN
FLOP
MAGNET
SAUCER
What do the following expressions tell you about the ⍋
grade-up and ⍒
grade-down functions on high-rank arrays?
⍋4 2 2⍴∊1 2 3 4,¨?4⍴(⊂3⍴10)
⍒4 2 2⍴∊'ABCD',¨{⎕A[⍵]}¨?4⍴(⊂3⍴10)
⍤
instead of each ¨
. That is, write IotaEach
, SumEach
and ReshapeEach
as dfns which use the rank operator and do not use the each operator.
IotaEach 1 2 3 ⍝ ⍳¨1 2 3
┌─┬───┬─────┐
│1│1 2│1 2 3│
└─┴───┴─────┘
SumEach 2 3⍴ IotaEach ⍳6 ⍝ +/¨2 3⍴⍳¨⍳6
1 3 6
10 15 21
2 2 ReshapeEach (1 2) 3 4 ⍝ 2 2∘⍴¨(1 2) 3 4
┌───┬───┬───┐
│1 2│3 3│4 4│
│1 2│3 3│4 4│
└───┴───┴───┘
¨
will implicitly disclose its arguments. You might need to use enclose ⊂
and disclose ⊃
to achieve the desired effect.
Split k-cells
The split function (monadic ↓
) splits an array of rank ≥2 by rows, returning an array of shape ¯1↓⍴⍵
. Use enclose ⊂
with the rank operator ⍤
to create a function Split
which always splits an array into a nested vector of the major cells of ⍵
.
Split 3 2 2 3⍴⍳9
┌─────┬─────┬─────┐
│1 2 3│4 5 6│7 8 9│
│4 5 6│7 8 9│1 2 3│
│ │ │ │
│7 8 9│1 2 3│4 5 6│
│1 2 3│4 5 6│7 8 9│
└─────┴─────┴─────┘