3 ms·
"Well," I said to myself as I read this article, "this wouldn't work if you had to iterate through multiple arrays simultaneously." Then I was enlightened as I
by ahelwer 15y ago
"Well," I said to myself as I read this article, "this wouldn't work if you had to iterate through multiple arrays simultaneously." Then I was enlightened as I realized the intended purpose of the zip function.
This followed by disappointment, as I was unable to experience a similar enlightenment for cases that did not have completely embarrassing data parallelism. For instance, given arrays A, B, and C, we want to set A[i] = B[i-1] + C[i+1] (with special cases at boundaries). How would you do this with the map/filter/fold primitive recursion patterns?
Edit: Upon thinking of it more, would slices do the trick? So, in Python:
A = [0,0,0,0,0]
B = [1,2,3,4,5]
C = [6,7,8,9,10]
A[1:-1] = map(sum, zip(B[:-2], C[2:]))
Is there a better way to do this? I would say it is much less easy to read than A[i] = B[i-1] + C[i+1]. I would probably have to add a comment to the effect of "this is what this line is doing", which goes against the self-documenting argument.
- Someone 15y agoSay, you gave you two papers each with a column of numbers and an empty one for the result, and ask me to process them in the manner given. I would place them side by side, move B down a line, C up a line, then add them row by row. The lining up is a matter of prepending the lists with some border values; then, use map to do the add. Finally, discard the edge cases.
- ahelwer 15y agoThat is a good analogy, thank you. It does seem to produce code that is more difficult to understand, however.
- thestoicattack 15y agoPerhaps you want the Haskell zipWith function? It takes two lists and, instead of zipping them together -- i.e., applying the tuple constructor (,) -- it lets you apply an arbitrary function. I think from your python, you want the first element of A to be 0? (Python is not my best language.) Thus in Haskell, a = 0 : zipWith (+) b c
- lsb 15y agoYes. You can say a = zipWith (+) (0 : b) (tail c ++ [0]) and that would make a[i] = b[i-1] (where b[-1] is 0) + c[i+1] (EDIT: where the last element of c is 0 (thanks tkahn6!)). Also, interestingly, if you have lazy evaluation, you can use a zip to produce the fibonacci numbers: just zip the list up with itself. fibs = 0 : 1 : zipWith (+) fibs (tail fibs) so you cons 0 to 1 to the zip, and the zip is combining 0 with 1, and then 1 with 1, and then 1 with 2. fibs[0] = 0 fibs[1] = 1 fibs[i, i>=2] = fibs[i-2] + fibs[i-1] and this looks like the math behind it.
- deleted 15y ago[deleted]
- tkahn6 15y agoI'm not sure your solution computes what you want. A[2] = B[2-1] + C[2+1] A[2] = B[1] + C[3] A[2] = 2 + 9 A[2] = 11 Your solution gives 12 for A[2]. f xs ys = zipWith (+) (0:xs) $ tail $ ys ++ [0] f [1..5] [6..10] == [7,9,11,13,4] I assume you want B[-1] and C[5] to yield 0 in this case.
- gd1 15y agoIn Q/KDB: /1 million random floats between 0 and 10 a:1000000?10.0; b:1000000?10.0; c:1000000?10.0; sum each flip (a;prev b;next c) /To do it in parallel sum peach flip (a;prev b;next c) Sometimes it is like living in a world where people refuse to use sheet music/clefs/bars and instead they read and write music by listing the notes, their frequencies and how long to play them for. And you can't tell them otherwise. People who recoil at APL because there are a few unusual symbols involved will gladly play a guitar and deal with all sorts of arcane symbols. If we really wanted to do a good job we'd go beyond ASCII.
- gruseom 15y agoHey, stick around and comment more. The HN APL/J/K/Q mafia needs all the help we can get :)