Why APL? Why not? Just learn the good thing about APL and throw away the bad thing.
Concate a string with a vector
s ← 'str'
v ← 1 2 3
s,¨v
s 1 t 2 r 3
(⊂s),¨v
str 1 str 2 str 3
(⊂s),¨⍕¨v
str1 str2 str3
(⊂s)∘,∘⍕¨v
str 1 str 2 str 3
s∘,∘⍕¨v
str1 str2 str3
APL flatten a matrix or an array
m2 ← 2 3 4 ⍴ ⍳ 20
m2
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
1 2 3 4
⍝ flatten a matrix
∊m2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4
⍝ use ravel operator to flatten a matrix
,m2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4
APL from right to left
APL is evaluated from Right to Left if there is not brackets. Arithmetic operator has no precedence.
4 × 2 + 3
20
4 × (2 + 3)
20
Yep, it is NOT 11,
Find three consecutive repeating numbers in a vector
Input: a vector: v = [1 2 2 2 4]
Output: true if there is three consecutive repeating numbers in the vector
v ← 1 2 2 2 4
v
┌→────────┐
│1 2 2 2 4│
└~────────┘
There is three two 2 2 2 in the $v$
My First solution
repeat3 ←{+/∧/2=/3(↑,/)⍵}
repeat3 1 2 2 2 4
1
repeat3 1 1 2 2 3 2
0
My second solution, two characters shorter without no bracket
{+/^/2=/↑3,/⍵} 1 1 1 2
1
/
2f 86
From RIDE, the symbol is like Reduce or Fold or N-wise Reduce
Reduce
+/ 1 2 3 4
10
N-wise Reduce, or Rolling or Sliding window
2,/ 1 2 3 4
1 2 2 3 3 4
3,/ 1 2 3 4 5
1 2 3 2 3 4 3 4 5
3(,/)1 2 3 4
1 2 3 2 3 4
Replicate or Compress
2 2 ¯2 3 / 6 7 9 5
┌→────────────────┐
│6 6 7 7 0 0 9 9 9│
└~────────────────┘
2 2 ¯2 3 / 6 7 9 9
↓ ↓ ↓ ↓
6 6 7 7 0 0 9 9 9
2 2 ¯2 3/4 5 6 7
┌→────────────────┐
│4 4 5 5 0 0 7 7 7│
└~────────────────┘
2 3 4 5/ 9 8 7 1
┌→──────────────────────────┐
│9 9 8 8 8 7 7 7 7 1 1 1 1 1│
└~──────────────────────────┘
2 3 0 4 / 1 2 3 4
┌→────────────────┐
│1 1 2 2 2 4 4 4 4│
└~────────────────┘
2 3 0 4 / 1 2 3 4
↓ ↓ ↓ ↓
1 1 2 2 2 ∅ 4 4 4
↑
2191 8593
Mix ↑
I have no idea what does it mean "Mix" here
Mix - from the dictionary, combine or put together to form one substance or mass.
↑ (1 2 3) (3 4 5) (1)
1 2 3
3 4 5
1 0 0
We can combine N-wise Reduce and Mix to generate a matrix as following
↑3(,/)1 2 2 2 3
1 2 2
2 2 2
2 2 3
Check whether three numbers are the same
2=/ 1 1 2
1 0
2=/ 1 1 1
1 1
Once we have the bit mask we can use OR to check and Reduce.
^/ 2=/ 1 1 2
0
^/ 2=/ 1 1 1
1
We just found some similar pattern with following code, window sliding
= and , both are Dyalic function, 2 or 3 here could be 2-wise or 3-wise Reduce
2(=/) 1 1 2
1 0
3(,/) 1 2 3 4
1 2 3 2 3 4
Decimal to Binary in APL
Given a decimal and Convert it to binary.
Ex. 8 → 1 0 0 0
9 → 1 0 0 1
bin3 ← {⍵ = 0 : 0 ⋄ 1↓{⍵ = 0 : 0 ⋄ q ← ⌊⍵÷2 ⋄ r ← 2|⍵ ⋄ (∇ q), r} ⍵}
bin3¨ ⍳ 10
┌→──────────────────────────────────────────────────────────────────────────────┐
│ ┌→┐ ┌→──┐ ┌→──┐ ┌→────┐ ┌→────┐ ┌→────┐ ┌→────┐ ┌→──────┐ ┌→──────┐ ┌→──────┐ │
│ │1│ │1 0│ │1 1│ │1 0 0│ │1 0 1│ │1 1 0│ │1 1 1│ │1 0 0 0│ │1 0 0 1│ │1 0 1 0│ │
│ └~┘ └~──┘ └~──┘ └~────┘ └~────┘ └~────┘ └~────┘ └~──────┘ └~──────┘ └~──────┘ │
└∊──────────────────────────────────────────────────────────────────────────────┘
APL does not support large number
Ex. The code will fail. APL gives wrong answer.
bin3 1082246073363339
┌→──────────────────────────────────────────────────────────────────────────────────────────────────┐
│1 1 1 1 0 1 1 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 1 1 0 0 1 0 1 0 1 1 1 0 0 1 0 0 0 0│
└~──────────────────────────────────────────────────────────────────────────────────────────────────┘
APL random number between 0 and 1
v1 ← 10 ⍴ ? 0 0 ⍝ 10 random number between 0 and 1
APL outer product
v ← 4 ⍴ 10?10
v
1 3 10 4
v ∘.× v
1 3 10 4
3 9 30 12
10 30 100 40
4 12 40 16
Combine Outer product with user defined function
f ← {⍺,⍵}
1 f 2
1 2
v ∘.f v
1 1 1 3 1 10 1 4
3 1 3 3 3 10 3 4
10 1 10 3 10 10 10 4
4 1 4 3 4 10 4 4
Multiply Matrix and Vector
m
0 1
¯1 1
v
2
0
⍴v
2 1
m +.× v
0
¯2
Function for line intersection in APL
Find the intersection of two lines:
line 1: $p_0 = (0, 0) \quad p_1 = (1, 1)$
line 2: $q_0 = (2, 0) \quad q_1 = (2, 1)$
vector: $\overrightarrow{p_0 p_1} = v_p = p_1 - p_0 = \begin{bmatrix}
1 \\
1
\end{bmatrix}
$
vector: $\overrightarrow{q_0 q_1} = v_q = q_1 - q_0 = \begin{bmatrix}
0 \\
1
\end{bmatrix}
$
line equation: $ f(s) = p_0 + s v_p $
line equation: $ f(t) = q_0 + t v_q $
$f(s) = f(t)$
$p_0 - q_0 = s (-v_p) + t v_q $
$p_0 - q_0 = \begin{bmatrix}
-v_p & v_q
\end{bmatrix}
\begin{bmatrix}
s \\
t
\end{bmatrix} \\
\begin{bmatrix}
-2 \\
0
\end{bmatrix} =
\begin{bmatrix}
-1 & 0 \\
-1 & 1
\end{bmatrix}
\begin{bmatrix}
s \\
t
\end{bmatrix} \\
\begin{bmatrix}
s \\
t
\end{bmatrix} =
\begin{bmatrix}
2 \\
2
\end{bmatrix}
$
f ← { p0 ← 1 ↑ ⍺ ⋄ p1 ← 1 ↓ ⍺ ⋄ v0 ← p1 - p0 ⋄ q0 ← 1 ↑ ⍵ ⋄ q1 ← 1 ↓ ⍵ ⋄ v1 ← q1 - q0 ⋄ w0 ← ∊p0 - q0 ⋄ m ← ⍉2 2 ⍴ ∊ (-v0) , v1 ⋄ (⌹m) +.× w0}
p ← (0 0) (1 1)
q ← (2 0) (2 1)
p f q
2 2
⍝ s = 2, t = 2
Sort function in APL
v ← 1 3 1 4 3 3 0 4 7
x ← ⍋ v
v[x]
0 1 1 3 3 3 4 4 7
Enclose or Box ⊃, wrap stuff or boxed stuff
⊃
2283 8835
1 2 3 + 1 2 3
┌→────┐
│2 4 6│
└~────┘
1 2 3 + ⊂ 1 2 3
┌→────────────────────────┐
│ ┌→────┐ ┌→────┐ ┌→────┐ │
│ │2 3 4│ │3 4 5│ │4 5 6│ │
│ └~────┘ └~────┘ └~────┘ │
└∊────────────────────────┘
Simulate array index
v ← 1 2 3
v[2]
2
2⊃¨⊂ 1 2 3
2
tails of a vector
tails ← {⌽(0,⍵)↑¨⊂⍵}
tails ⍳4
┌→────────────────────────────────┐
│ ┌→──────┐ ┌→────┐ ┌→──┐ ┌→┐ ┌⊖┐ │
│ │1 2 3 4│ │1 2 3│ │1 2│ │1│ │0│ │
│ └~──────┘ └~────┘ └~──┘ └~┘ └~┘ │
└∊────────────────────────────────┘
Split a vector into two parts: head and remainer
sp ← {(1↑⍵) (1↓⍵)}
sp ⍳4
┌→────────────┐
│ ┌→┐ ┌→────┐ │
│ │1│ │2 3 4│ │
│ └~┘ └~────┘ │
└∊────────────┘
Split String with ⊢
p ← {⍵⊆⍨ ⍺ ≠⍵}
'/' p 'Hello/World'
Hello World
# Have no idea how does it work.
'/' (≠⊆⊢) 'Hello/World'
Hello World
Flip the first bit from 1 to 0 in a bit vector
Given bit vector, flip the first 1
0 1 0 1 0 1 0 0 1 0
↑
+ -> 1 => 0
w ← 0 1 0 1 0 1 0 0 1 0
u ← (<\) w
u
0 1 0 0 0 0 0 0 0 0
u (<) w
0 0 0 1 0 1 0 0 1 0
⍝ Final Solution
(<\<⊢) w
0 0 0 1 0 1 0 0 1 0
Fill a bit vector with 1s between 1 and 1 and flip the last odd 1
Given bit vector
0 0 1 0 0 1 0 1 0
↑ ↑ ↑
| | + -> Flip it
0 0 1 1 1 1 0 0 0
0 0 1 0 0 1 0 1 0 1 0
↑ ↑ ↑ ↑
0 0 1 1 1 1 0 1 1 1 0
+ -> Flip the last one to zero
|
+ -> Fill ones |
| |
| | + Check parity
↓ ↓ ↓
fill ←{f←{(≠\∨⊢)⍵} ⋄ g←{⌽(<\<⊢)⌽⍵} ⋄ 1=⍨2|+/⍵:f g ⍵ ⋄ f ⍵}
fill ←{f←{(≠\∨⊢)⍵} ⋄ g←{⌽(<\<⊢)⌽⍵} ⋄ ≠/⍵:f g ⍵ ⋄ f ⍵}
↑
+ -> Check parity
fill 0 1 0 0 1 0 0 1 0 1 0
0 1 1 1 1 0 0 1 1 1 0
Just realize ≠ is Just an XOR
⍝ Check parity of bit vector with ≠
≠/ 0 1
1
≠/ 0 1 0 1
0
⍝ XOR Table
⍝ 0 ≠ 0 => 0
⍝ 1 ≠ 1 => 0
⍝ 0 ≠ 1 => 1
# In Haskell
foldl1(\a b -> a /= b ? 1 $ 0) [1, 0, 1] # => 0
foldl1(\a b -> a /= b ? 1 $ 0) [1, 0, 1, 1] # => 1
⍝ XOR Table
∘.{⍺ 'XOR' ⍵ '=' (⍺≠⍵)}⍨ 0 1
0 XOR 0 = 0 0 XOR 1 = 1
1 XOR 0 = 1 1 XOR 1 = 0
∘.{⍺ '≠' ⍵ '=' (⍺≠⍵)}⍨ 0 1
0 ≠ 0 = 0 0 ≠ 1 = 1
1 ≠ 0 = 1 1 ≠ 1 = 0
The power of outer product in APL
∘.{⍺'x'⍵'='(⍺×⍵)}⍨⍳5
┌─────────┬──────────┬──────────┬──────────┬──────────┐
│1 x 1 = 1│1 x 2 = 2 │1 x 3 = 3 │1 x 4 = 4 │1 x 5 = 5 │
├─────────┼──────────┼──────────┼──────────┼──────────┤
│2 x 1 = 2│2 x 2 = 4 │2 x 3 = 6 │2 x 4 = 8 │2 x 5 = 10│
├─────────┼──────────┼──────────┼──────────┼──────────┤
│3 x 1 = 3│3 x 2 = 6 │3 x 3 = 9 │3 x 4 = 12│3 x 5 = 15│
├─────────┼──────────┼──────────┼──────────┼──────────┤
│4 x 1 = 4│4 x 2 = 8 │4 x 3 = 12│4 x 4 = 16│4 x 5 = 20│
├─────────┼──────────┼──────────┼──────────┼──────────┤
│5 x 1 = 5│5 x 2 = 10│5 x 3 = 15│5 x 4 = 20│5 x 5 = 25│
└─────────┴──────────┴──────────┴──────────┴──────────┘
Rank Operator or Atop
⍤