Explanation
f=:3 :'...' declares a (monadic) verb (function). The input to the verb is represented by y within the verb definition.
p:i._1&p:y The p: verb is the multi purpose primes verb, and it's used in two different ways here: _1&p:y returns the number of primes less than y then p:i. generates every one of them. Using 10 as input:
p:i._1&p:10 2 3 5 7
(~:/**/)~ generates the table I spoke of earlier. */ generates a multiplication table, ~:/ generates a not-equal table (to eliminate the squares) and both of these are multiplied together. Using our previous output as input:
*/~2 3 5 7 4 6 10 14 6 9 15 21 10 15 25 35 14 21 35 49 ~:/~2 3 5 7 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 (~:/**/)~2 3 5 7 0 6 10 14 6 0 15 21 10 15 0 35 14 21 35 0
}.~., now we turn the numbers into one list , get the unique values ~. and remove the 0 at the start }.
}.~.,(~:/**/)~2 3 5 7 6 10 14 15 21 35
-.y< There isn't a less than or equal that I know of in J so I've used not -. greater than < for comparison with the original input:
-.10<6 10 14 15 21 35 1 1 0 0 0 0
+/ and then sum that to get the answer.
+/1 1 0 0 0 0 2