An old folk riddle:
As I was going to St Ives
I met a man with seven wives
Every wife had seven sacks
Every sack had seven cats
Every cat had seven kits
Kits, cats, sacks, wives –
How many were going to St Ives?
One – no calculation required – everyone else was coming from St Ives! From which we see the riddle is older than the railways.
So, what if the narrator met the polygamist on a train? Let’s suppose the polygamist is to be counted too. We start with him. And his wives.
In a scalar language we can loop 5 times, multiplying by 7 each time an initial seed of 1, and adding it to an accumulator.
count = 1; // me for(i=0;i<5;i++) { count+= 7**i; } printf(count);
An array solution starts by listing the travellers.
1 7 ⍝ a man with 7 wives 1 7 +/1 7 ⍝ count them 8 +/1 7 49 ⍝ 7 wives had 7 sacks 57
Hang on. There’s a pattern here.
7*0 1 2 ⍝ 7 raised to consecutive powers 1 7 49 +/7*0 1 2 57
The APL *
means raise to a power. (For multiplication, we use the multiply sign ×
– how crazy is that?)
+/7*0 1 2 3 4 ⍝ wives, sacks, cats, kits 2801 +/7*⍳5 ⍝ ie first 5 integers 2801 1++/7*⍳5 ⍝ and me 2802
But for vectors u
and v
and functions f
and g
, f/u g v
is a degenerate case of u f.g v
, which leads the way to expressions that work for arrays with more dimensions, so we could equally write:
1+7+.*⍳5 2802
(Crowded train, I’d say.)
Works in q as well, where the syntax requires parens around the reduction:
q)1+(+/)7 xexp til 5 2802f q)
You can experiment with the APL expressions in this post at TryAPL.org.
St Ives, by the way, is a charming seaside town in Cornwall. More power to it.
Thinking about performance, an expression like
1++/(×\5/7)÷7
removes the floating point games that exponentiation will impose.
LikeLike
Assuming ÷ introduces floating point, on reflection, leads me to use
+/1,×\5/7
LikeLike