Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- NB. Project Euler #1 in J.
- +/I.+./0=3 5|"0 1 i.1e3
- NB. To break it down. J is evaluated from right to left, so the first thing that gets evaluated is...
- 1e3 NB. This is just another way of saying 1000
- NB. The verb i. gives us all the numbers from 0 up to the argument minus 1, so...
- i.1e3
- 0 1 2 3 4 5 6 7 NB. and so on
- NB. Now it starts to get interesting. The verb | gives us the so-called "residue", the remainder on dividing a non-negative number by a positive one. So, 2 | 5 gives us 1, because 5 is divisible by 2 twice with a remainder of 1. The quotation mark is one of the many conjunctions in J. It changes the so-called rank of the verb, which describes how it applies to arguments of a different shape (atom, list, matrix, etc.) A little too complex to go into here, but ...
- 3 5|"0 1 i.1e3
- NB. means that the individual members of the list 3 and 5 are applied to each of the numbers produced by i.1e3, producing a matrix of two lists, as follows:
- 0 1 2 0 1 2 0 1 2 NB. and so on
- 0 1 2 3 4 0 1 2 3 NB. and so on
- NB. The first list consists of the remainder of i.1e3 when divided by 3, the second the remainder when divided by 5. Now, we add ...
- 0 = 3 5|"0 1 i.1e3
- NB. This transforms our matrix such that for each entry that is equal to 0, 1 is output, otherwise 0. (J uses 0 and 1 for booleans.) Thus ...
- 1 0 0 1 0 0 1 0 0 NB. and so on
- 1 0 0 0 0 1 0 0 0 NB. and so on
- NB. Next, we add +./, which needs a bit of explanation. +. is logical or, so 1 +. 0 is 1, 0 +. 0 is 0, 1 +. 1 is 1, and so on. However, we want to apply it to these lists, so we can use the / adverb to do so. / applies its verb between each element of a list. Our matrix is actually a list of lists, so the first argument would be the top list, and the second argument the bottom one. Something like...
- 1 0 0 1 0 0 1 0 0
- +.
- 1 0 0 0 0 1 0 0 0
- NB. When +. is applied between two list, it's the same as applying it to each element in the list at the same position, so it's like ...
- 1 +. 1
- 0 +. 0
- 0 +. 0
- 1 +. 0
- NB. and so on
- NB. The first row in my pseudocode above is the first element in each list, the second is the second, etc. This collapses our list down to one:
- +./0 = 3 5 |"0 1 i.1e3
- NB. produces ...
- 1 0 0 1 0 1 1 0 0 1 1 NB. and so on
- NB. Now we have a single list. The number 1 means that the number is divisible by 3 or 5, 0 means it's divisible by neither. Now we add the verb I. back into the mix. Given a list of numbers 0 1 0 0 1, I. returns the corresponding 0-based natural number if the list contains a 1, otherwise it returns nothing. So I. 0 1 0 0 1 returns 1 4. Applying this to our list gets the list of numbers divisible by either 3 or 5:
- I.+./0 = 3 5|"0 1 i.1e3
- 0 3 5 6 9 10 12 15 18 20 21 NB. and so on
- NB. Now we just have to sum them, which we can do using the same / adverb we used above. +/ 2 3 5 is the same as 2 + 3 + 5, so ...
- +/I.+./0 = 3 5"0 1 i.1e3
- 233168
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement