I love small challenges as a way to learn a language. I spotted this one in the #rstats hashtag on Mastodon
“square each digit of an integer (return integer), eg 9113 becomes 81119”
and I just had to try it in APL.
First, extract each of the digits using format
{⍎¨⍕⍵}9113
9 1 1 3
then square each digit, using the commute operator to make 2*x
into x*2
(*
is power)
{2*⍨⍎¨⍕⍵}9113
81 1 1 9
The next bit took me a bit of trying, but I got there (please do let me know if there’s an easier way)… extract each digit as a character
{⍕¨2*⍨⍎¨⍕⍵}9113
┌──┬─┬─┬─┐
│81│1│1│9│
└──┴─┴─┴─┘
then catenate-reduce
{,/⍕¨2*⍨⍎¨⍕⍵}9113
┌─────┐
│81119│
└─────┘
and finally enlist down to a scalar and parse as a number again
{⍎∊,/⍕¨(2*⍨⍎¨⍕⍵)}9113
81119
Wrapping it into a named defun, it’s not all that bad
squaredigits←{⍎∊,/⍕¨(2*⍨⍎¨⍕⍵)}
squaredigits 9113
81119
Is it as nice as the Julia solution?
parse(Int, join(reverse(digits(num)).^2))
or, as mentioned in a reply
using Chain
@chain num digits reverse _.^2 join parse(Int, _)
No - I think in this case Julia does a much nicer job; easier to reason and interpret but that comes from having nice wrappers for things like digits
(which returns them in reverse order, requiring the reverse
). I could absolutely do that in APL, I’ve just been trying to do it entirely with primitives, but nice wrappers are nice…
digits←⍎¨⍕
digits 9113
9 1 1 3
same for join
join←⍎∘∊(,/⍕¨)
join 81 1 1 9
81119
and heck, square
square←{2*⍨⍵}
square 9
81
or, since I no longer need the arguments in that order, simply
square←{⍵*2}
square 9
81
so then the APL solution, via composing these three functions, becomes simply
squaredigits←join∘square∘digits
squaredigits 9113
81119
Now THAT’s readable!
And yes, it’s still a number
1+squaredigits 9113
81120
Want to see how it works? APL prints out the AST for a function like this
squaredigits
∘
┌┴┐
∘ ¨
┌─┴──┐
┌─┴──┐ {⍵*2}
∘ ┌─┴─┐
┌ / ¨
∊ ┌─┘ ┌─┘
,
I’m not nearly done loving what APL can do.