Alex Gian wrote:
> I'm looking for a verb "explode" which
> will return a string comprising the digits
> of a positive integer.
I wrote:
> 10&#.^:_1
Alex Gian wrote:
> so a few hints rather than a full,
> exhaustive solution would be appreciated.
Sorry, I didn't see you'd asked for hints.
The phrase 10&#.^:_1 is very well-known in J, and is one of its treasures
(see [1] from earlier today). Let's break the phrase down down:
#. Evaluate digits y in base x
10& Base x is 10 (so eval digits y in base 10)
^:_1 Invert function; explode numbers y into digits in
base 10
This will give you as many digits as needed to fully explode the (largest)
number. In the case of an array (non-scalar) y, the shape of the result
will be ($y), x ndr y where x ndr y is the number of digits required to
represent the largest value in y in base x [2].
If you want to fix the number of digits (say you wanted ensure an 4-digit
array, even if all the values in y happened to be less than 10,000), then
instead of #.^:_1 you'd use #: , as in (4#10)&#: [3].
A careful reading of the definitions of #. and #: will repay the effort (and
you'll find out why we don't need explicit for loops).
-Dan
[1] #. is a Jem:
http://www.jsoftware.com/pipermail/programming/2010-August/020072.html
[2] The number of digits required to represent the largest value in y in
base x :
10&#. b. _1
($&10@>:@(10&(<....@^.))@(1&>.)@(>./)@:|@, #: ]) :.(10&#.)
ndr =: 10&$: : (>:@<....@^. (1&>.)@(>./)@:|@, )
ndr 1000
4
10 #.^:_1 ] 1000
1 0 0 0
16 ndr 1000
3
16 #.^:_1 ] 1000
3 14 8
'0123456789abcdef' {~ 16 #.^:_1 ] 1000
3e8
16b3e8
1000
[3] With either a fixed or calculated number of digits, the question
arises: what happens to values that have fewer digits than that?
Nouns are always rectangular in J, so of course the resulting array can't
have "rows" (1-cells) with differing numbers of columns. The "short"
numbers must be padded with extra digits.
Normally, J pads data on the right, and numeric data with 0s (try >1 2;3 4 5
6 7). In fact, if #.^:_1 Or #: had rank 0, they would be required to pad
their results this way.
But padding with zeros on the right is destructive when breaking up digits.
When we need to pad a list of digits, we do so with zeros on the /left/, as
in
121
+ 007
-----
128
to maintain the value's identity. Which explains why #: isn't rank 0 (you
might expect a derived verb like 10&#.^:_1 to have unbounded rank, but #: is
an arithmetical operation, and is logically "scalar", like + - * % | ^ %:
etc, but try #:b.0 ).
As I said, these are treasures in J, and like all treasures, these are
beautifully built.
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm