1 min read

APL Hacking: Project Euler (#21)

Problem #21:

∇R←PETWENTYONE;X;Y;Z
⍝ Compute the sum of amicable numbers under 10000.
R←+/(∨/X^⍉X)/Y⊣X←(~Z)^Y∘.=Y+.×(0=Y∘.|Y)≠Z←Y∘.=Y⊣Y←⍳10000
∇


Ah, back to the nice one liners. I like this one because it made me think a lot about what was actually more or less efficient in my code. Initially I had an operation to compute that was way too memory intensive. But thinking about the problem a little bit helped me to rewrite things with an inner product instead, and that improved performance dramatically. I still thought that the products would have been the most intensive part of this expression, but tracing things out actually leads to +/(∨/X^⍉X)/Y as being the most intensive part. Imagine that! I would have thought the transposition and boolean operators on boolean matrices would have been quite fast, but they are actually more than half the time compared to the rest of the computation.