Reputation: 23150
Writing my first J program to solver Euler problem #1 (find the sum of all natural numbers below 1000 that are multiples of 3 or 5), I got the following solution:
+/(+./0=3 5|/n)#n=.i.1000
However, I pretty sure there is a clever way of doing it, without using a variable. I tried to rewrite it using a fork, but I don't see how I could replace the expression between () as a verb applied to 3 5
and i.1000
. Could anybody help me?
Upvotes: 0
Views: 223
Reputation: 3140
To parameterize both values, and thus generalize to a dyadic verb, we'll need to pass each of the parameters through to the places where they're needed. We can focus on the sole point where 3 5
is actually needed by starting with this fork:
3 5 ([ |/ i.@]) 1000
In the overall program we need the integers list in two places. The name (n
) gave us an easy way to use that list in both places. To quickly get the whole program in place, in writing this I initially calculated the list twice:
3 5 ([: +/ i.@] # [:+./ 0= [ |/ i.@]) 1000
This succeeds at phrasing your whole program as a dyadic verb, but there are disadvantages to having i.
appear twice. We can extract it to occur only once by making it the right tine of a fork. The center of that fork is a new, inner, verb.
3 5 ([: +/ [ (] # [:+./ 0= [ |/ ]) i.@]) 1000
NB. ___________________ new "inner" verb, parenthesized
This inner verb needs to receive the 3 5
as an argument so I pass through the left argument of the outermost verb as the left argument to this inner verb. This means Left ([
) in the inner verb has the same value it had in the previous version, when it referred to the outermost argument. Within this new verb Right (]
) refers to the list of integers, occurring in the two places that i.@]
appeared before.
Postscript: As you showed in your comment, [ |/ ]
simplifies to |/
Upvotes: 3