(Unicode APL chars in this message! and a spoiler if you haven't yet
found the solution!)






I love showing off the APL (from the original book) solution for this
to people who have heard nothing of array-based languages:
V +.× ∊ ∨.= N ∘.| V
which finds the sum of the numbers in the vector V which are
multiples of any number in the vector N.
(You have to picture +.× as one above the other for full effect,
just as they are here: http://www.jsoftware.com/papers/APL.htm 
<http://www.jsoftware.com/papers/APL.htm>; the
epsilon has a bar above it as well, but I can't type that.)

Anyhow, the previous solution is easily translated into ISO APL:
V←⍳999
N←3 5
V+.×0∨.=N∘.|V

or into tacit J:
3 5 (] +/ . * 0 +./ . = |/) i.1000

If you're just beginning to learn J, you should know that while it
might have been elegant to write in APL, dot products like +./ . =
and +/ . * should be avoided in J, and be replaced by the faster and
easier-to-understand +./@:= and +/@:* (they are only interchangeable
if the left and right arguments are vectors however!).

If I "explicate" (render explicit) the previous tacit solution (and
remove the dot products), it gives:
V=: i.1000
N=: 3 5
+/ V * +./ 0 = N |/ V

The |/ makes a table of remainders from the divisions of all the num-
bers in V (along the rows) by all the numbers in N (vertically).
0 = … looks for 0-remainders, which correspond to multiples of
numbers in N in V. +./ ORs the lines together, so you get a vector
which contains a 1 iff the corresponding number in V is a multiple
of ANY number in N, and a 0 otherwise (*./ would correspond to
multiples of ALL the numbers in N). Multiply by V, you get a vector
of 0s and of multiples of any number in N. All that is needed then is
to take the sum +/ .
Try playing around with this a little: instead of multiplying by the
boolean vector that corresponds to the multiples (0 +./@:= |/) you
can use # (copy or compress if x is boolean). You can also check for
multiples by seeing if N = the GCD table of N and V ([ = +./) or by
checking if V = the rows of the LCM table (] ="1 *./) and try out
the rank conjunction.

Best regards,
Louis

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to