0

I'm learning J and starting with something basic; adding the multiples of 3 and 5 below 100. I got it with this code:

(+/((((i.100)|~ 3) = 0) # (i.100)),((((i.100)|~ 5) = 0) # (i.100)))-(((i.100|~15)=0) # (i.100))

but it seems like there should be an easier way. Is there any way to make this code cleaner? Thanks.

Descartes
  • 503
  • 2
  • 7
  • 22
  • possible duplicate of [How to refactor this in J?](http://stackoverflow.com/questions/1555807/how-to-refactor-this-in-j) – MPelletier Oct 17 '11 at 13:21

1 Answers1

1

Note that your current code gives a length error but I have suggested an edit to your question to make it work. For now I'll also include the working code below.

(+/((((i.100)|~ 3) = 0) # (i.100)),((((i.100)|~ 5) = 0) # (i.100))) - (+/(((i.100)|~15)=0) # (i.100))

The same algorithm can be written more simply (less parentheses anyway) by simply altering the order of operations (J evaluates "sentences" from right to left).

   (+/ ((0 = 3|i.100) # i.100) , ((0 = 5|i.100) # i.100)) - +/(0 = 15|i.100)#i.100
2318

Rather than subtracting the sum of the multiples of 15 from the original sum to avoid double counting number that are multiples of both 3 and 5, you could use ~. (Nub) to remove any duplicates from your list of multiples of 3 and multiples of 5 before summing them.

   +/ ~. ((0 = 3|i.100) # i.100) , (0 = 5|i.100) # i.100
2318

For a more Jish approach to this problem see the answer to this stackoverflow question.

Community
  • 1
  • 1
Tikkanz
  • 2,398
  • 15
  • 21
  • ah yes thanks.. I had a couple transcription errors when copying from my notepad. I'll fix them. but thanks – Descartes Oct 17 '11 at 23:45
  • Of course, you can also get the multiples of n below 100 by `(n*i.>.100%n)`. So: `+/~.(3*i.>.100%3),(5*i.>.100%5)` – Eelvex Nov 29 '11 at 17:46