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
