Thanks a lot for that Ric.

I actually managed to get as far as this:
 digits =. 10&#.inv
 fp1 =. +!
 spsum =. +/ @ |: @ fp1 @ digits
 special =. = spsum
 (#~ special)i.100000

which gave me 85837 correctly
also,
 (#~ special)i.1000000
41086 408297
gives the correct larger number in very acceptable time, the lower
number is incorrect because of the leading-zero prob already mentioned.

I really hate what I had to do with the transpose to get the sum,
though, so I'll be studying your example rigorously.  Seems to eliminate
all these probs.


 

On Sun, 2010-08-29 at 00:56 +1200, Sherlock, Ric wrote:
> > From: Alex Gian
> > Sent: Sunday, 29 August 2010 00:23
> > 
> > Oops, before we go any further, I've stumbled on a real gotcha
> > e.g.
> > 
> > digits 1974 123
> >   1 9 7 4
> >   0 1 2 3
> > 
> > now, when I apply (+!) to that lot, it is also applied to the leading
> > zero of 0123 - which, of course, leads to a wrong result when summed.
> > AAARGH!
> 
> Firstly I tend to build these up bit by bit, making sure I'm getting what I 
> want as I go. I often end up with a long one-liner that does the job. If I 
> want to reuse it, or publish it then I might go to the next step and break it 
> up into component verbs to make it more immediately readable.
> 
> You want to finish doing digits and (+!) on each number individually before 
> moving on to the next number for the reason you've shown above. As Bill 
> suggested earlier, the solution is apply digits at rank 0.
>    <@(10&#.inv) 1974 123
> +-------+
> |1 9 7 4|
> |0 1 2 3|
> +-------+
>       <@(10&#.inv"0) 1974 123
> +-------+-----+
> |1 9 7 4|1 2 3|
> +-------+-----+
> 
> By default (10&#.inv) will work on the whole right argument at once. You can 
> check the ranks of the verb as follows:
>    (10&#.inv) b. 0
> _ _ _
>    
> You want to modify that to feed each item in the right argument to the verb 
> separately -  hence the "0.
> 
> Box ( < ) as used above is nice for illustrating how this is working but you 
> want to use (+!) so:
>    (+!)@(10&#.inv"0) 1974 123
> 2 362889 5047 28
> 2      4    9  0
> 
> At ( @ ) causes the verb to its left to be fed the results of the verb to its 
> right each time the verb to the right is "run". In other words the rank zero 
> is applied to the (+!) too. We could now sum the number individually too:
>    +/@(+!)@(10&#.inv"0) 1974 123
> 367966 15
> 
> Athough this will give the correct answers, it isn't optimal because it isn't 
> necessary to sum the numbers individually, we will get the same answer if we 
> wait until all the (+!)@digits"0 operations have completed and then sum the 
> resulting array and J generally performs better when operating on large 
> rather than small arrays. We can signal that we want to wait by using the 
> modified form of At ( @: ). IOW the following is likely to be faster:
>    +/@:(+!)@(10&#.inv"0) 1974 123
> 367966 15
> 
> Now let's add the next step - check if the resulting values equal the 
> original numbers:
>    (] = +/@:(+!)@(10&#.inv"0)) 1974 123
> 0 0
> 
> And only filter the ones that do:
>    (#~ ] = +/@:(+!)@(10&#.inv"0)) 1974 123
> 
> Of course for those numbers the result is empty, but if we check all the 
> numbers up to 100000 we do get one candidate:
>    (#~ ] = +/@:(+!)@(10&#.inv"0)) >: i.1e5
> 85837
> 
> HTH
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm


----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to