How to refactor this in J?
j, refactoring, tacit-programming
Solution
It isn't necessary to "handle zero" because adding zero won't change the answer so you can just use `i.` to generate your list of numbers below 1000, for example:
i. 10
0 1 2 3 4 5 6 7 8 9
J works best with arrays so you should be able to ask for the residue (`|`) of 3 and 5 at the same time, you can use rank (`"`) to control how the arguments are fed to residue:
3 5 |"0 1 i. 10
0 1 2 0 1 2 0 1 2 0
0 1 2 3 4 0 1 2 3 4
The `|"0 1` says to feed the left argument to `|` an-item-at-a-time while feeding the right arguments a-line-at-a-time. Because the right argument only consists of one line, it is fed repeatedly to each of the left argument items.
Now we can do the `0=` to the whole array:
0 = 3 5 |"0 1 i. 10
1 0 0 1 0 0 1 0 0 1
1 0 0 0 0 1 0 0 0 0
Insert an OR condition between the two items (lines) of the array:
+./ 0 = 3 5 |"0 1 i. 10
1 0 0 1 0 1 1 0 0 1
Get the index of each 1 in the list/vector:
I. +./ 0 = 3 5 |"0 1 i. 10
0 3 5 6 9
And sum:
+/ I. +./ 0 = 3 5 |"0 1 i. 10
23
You can make this an explicit function/verb fairly easily:
euler1=: verb define
+/ I. +./ 0 = 3 5 |"0 1 i. y
)
Or once you get the hang of tacit J you could define:
euler1=: +/@I.@(+./)@(0 = 3 5 |"0 1 i.)
Problem
My newbie solution to Project Euler #1 ``` +/((0=3|1+i.1000-1) +. (0=5|1+i.1000-1)) * (1+i.1000-1) ``` I know that this can be refactored, and transformed into a function, i don't know how to do it, and I would have to read all the labs to learn it.