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