Search code examples
j

How to apply an operation to all members of a collection using each element


I would like to apply an operation to each element of a collection, for each element of the collection. I'm looking for something that operates similar to the following:

result = []
for i in X:
  for j != i in X:
    if j % i == 0 (or whatever condition here)
      result += j

I can figure out the part of applying an operation to each element in the collection, but how do I make it use each element in the collection operate against the iterand?

So, for example, if I have 2 3 5 8 How would I get something like 4; ; ;?


Solution

  • I'm guessing you are you trying to solve the problem for Part 2 of Day 3 on adventofcode? If not then I may have interpreted your question incorrectly.

    The key is to think whole-array-at-a-time, not item-at-a-time so let's ignore the for i in X:

       ]jnei=: ~:/~ 2 3 5 8                NB. for j != i in X:
    0 1 1 1
    1 0 1 1
    1 1 0 1
    1 1 1 0
    
       ]dividesExactly=: 0 = |~/~ 2 3 5 8  NB. if j % i == 0
    1 0 0 0
    0 1 0 0
    0 0 1 0
    1 0 0 1
    
       mask=: jnei *. dividesExactly       NB. both conditions
    0 0 0 0
    0 0 0 0
    0 0 0 0
    1 0 0 0
    
       %/~ 2 3 5 8                         NB. divisions to choose from
      1 0.666667 0.4  0.25
    1.5        1 0.6 0.375
    2.5  1.66667   1 0.625
    4  2.66667 1.6     1
    
       mask * %/~ 2 3 5 8                  NB. evenly divided, off-diagonals
    0 0 0 0
    0 0 0 0
    0 0 0 0
    4 0 0 0
    
       +/ , mask * %/~ 2 3 5 9             NB. ravel and sum to return 4
    4
    

    I would likely code this as follows:

       +/ , (%/~ * ~:/~ *. 0 = |~/~) 2 3 5 8
    4