How to refactor this in J?

Tag: refactoring , project-euler , j , tacit-programming Author: Mumu123321 Date: 2009-09-26

Here is a different approach for the Project Euler #1 solution:

+/~.(3*i.>.1000%3),5*i.>.1000%5

How to refactor it?

Did you check project euler forum for problem #1? projecteuler.net/index.php?section=forum&id=1
I got this code from there. But the forum is locked.

Best Answer

[:+/@~.@,3 5([*i.@>.@%~)]

usage example:

f =: [:+/@~.@,3 5([*i.@>.@%~)]
f 1000

or

+/~.,3 5([*i.@>.@%~)1000


%~                        = 4 : 'y % x'
i.@>.@%~                  = 4 : 'i. >. y % x'
[*i.@>.@%~                = 4 : 'x * i. >. y % x'
3 5([*i.@>.@%~)]          = 3 : '3 5 * i. >. y % 3 5'
[:+/@~.@,3 5([*i.@>.@%~)] = 3 : '+/ ~. , 3 5 * i. >. y % 3 5'

comments:

this is legible for you? I am still trying to figure out each step of the refactoring...
thanks for the last edit, that was clarifying

Other Answer1

+/(#~ ( (0= 3| ]) +. (0 = 5 |]) )) 1+i.999

0 = ( 3 | ]) uses (twice) the trick of verb train (fork) with n u v (discussed at the end of http://www.jsoftware.com/help/learning/09.htm)

A different way of writing it:

+/(#~ ( ((0&=) @ (3&|)) +. ((0&=) @ (5&|)))) 1+i.999

Other Answer2

Here is another approach, using a simple, generic verb

multiplesbelow =: 4 : 'I. 0 = x | i.y'
+/ ~. ,3 5 multiplesbelow"0 [ 1000

comments:

Nice! How about multiplesBelow =: 4 : '(#~ +./(0 = x | ])"0) i. y'? Then you can say +/ 3 5 multiplesBelow 1000.