Motivation
I have been working on the Dyalog APL quicksort implementation. The following programming puzzle arose in the process of doing the QA for this work.
⍵
is a simple array. Write a function sorted
, without using ⍋
or ⍒
, such that sorted ⍵
is 1 if ⍵
is sorted in ascending order and 0 otherwise.The point about not using grade is that this is supposed to be an independent check that grade is correct (remains correct) after the new work.
Real Vectors
The simplest case is when ⍵
is a numeric vector. If furthermore ⍵
are not complex numbers (a case addressed later), then
∧/ 2≤/⍵
each item being less than or equal to the next one, checks that ⍵
is sorted. Since ⍋
uses exact comparisons, here we must set ⎕ct←⎕dct←0
. Morever, in order that decimal floating-point numbers (DECFs) be compared correctly, here ⎕fr←1287
.
Real Arrays
More generally, when ⍵
is a non-complex numeric matrix, we must check that each row precedes or is equal to the next row. If c
and d
are consecutive rows, then corresponding items are compared and at the first item where they differ, c[i]
must be less than d[i]
.
~ 0 ∊ (2>⌿⍪⍵) ⍲ < 2≠⌿⍪⍵
The expression incorporates two refinements:
- If
⍵
is not a matrix, first apply⍪⍵
. - Instead of checking
c[i]
is less thand[i]
, check thatc[i]
is not greater thand[i]
. This finesses the case wherec≡d
and there is no first item where they differ; that is, the case where<2≠⌿⍪⍵
is all 0s for that row.
<
on a boolean vector has 0s after the first 1, (and is all 0 if there are no 1s). Therefore, <2≠⌿⍪⍵
finds the first item (if any) where one cell differs from the next cell, and that item must not be greater than the corresponding item in the next cell.
For example:
x←?97 3⍴10
{~ 0 ∊ (2>⌿⍪⍵) ⍲ < 2≠⌿⍪⍵} x
0
{~ 0 ∊ (2>⌿⍪⍵) ⍲ < 2≠⌿⍪⍵} x[⍋x;]
1
(Muse: since x
above are random numbers, there is a possibility that it is sorted and the first test above can be 1. But: if each elementary particle in the visible universe were a computer and every nanosecond each of them creates a random matrix and tests it for sortedness as above, running from the beginning of the time to the end of our lives, it is still a very safe bet that no 1 would result.)
For integer arrays, there is an alternative of using the signs of the arithmetic difference between successive cells:
{~ 0 ∊ 1≠t×<