문제

I'm trying to implement A006751 in J. It's pretty easy to do in Haskell, something like:

concat . map (\g -> concat [show $ length g, [g !! 0]]) . group . show

(Obviously that's not complete, but it's the basic heart of it. I spent about 10 seconds on that, so treat it accordingly.) I can implement any of this fairly easily in J, but the part that eludes me is a good, idiomatic J algorithm that corresponds to Haskell's group function. I can write a clumsy one, but it doesn't feel like good J.

Can anyone implement Haskell's group in good J?

도움이 되었습니까?

해결책

Groups are usually done with the /. adverb.

   1 1 2 1 </. 'abcd'
┌───┬─┐
│abd│c│
└───┴─┘

As you can see, it's not sequential. Just make your key sequential like so (essentially determining if an item is different from the next, and do a running sum of the resulting 0's and 1's):

   neq =. 13 : '0, (}. y) ~: (}: y)'
   seqkey =. 13 : '+/\neq y'
   (seqkey 1 1 2 1) </. 'abcd'
┌──┬─┬─┐
│ab│c│d│
└──┴─┴─┘

What I need then is a function which counts the items (#), and tells me what they are ({. to just pick the first). I got some inspiration from nubcount:

   diffseqcount =. 13 : ',(seqkey y) (#,{.)/. y'
   diffseqcount 2
1 2
   diffseqcount 1 2
1 1 1 2
   diffseqcount 1 1 1 2
3 1 1 2

If you want the nth result, just use power:

   diffseqcount(^:10) 2  NB. 10th result
1 3 2 1 1 3 2 1 3 2 2 1 1 3 3 1 1 2 1 3 2 1 2 3 2 2 2 1 1 2

다른 팁

I agree that /. ( Key ) is the best general method for applying verbs to groups in J. An alternative in this case, where we need to group consecutive numbers that are the same, is dyadic ;. (Cut):

   1 1 0 0 1 0 1 <(;.1) 3 1 1 1 2 2 3
┌─┬─────┬───┬─┐
│3│1 1 1│2 2│3│
└─┴─────┴───┴─┘

We can form the frets to use as the left argument as follows:

   1 , 2 ~:/\ 3 1 1 1 2 2 3   NB. inserts ~: in the running sets of 2 numbers 
1 1 0 0 1 0 1

Putting the two together:

   (] <;.1~ 1 , 2 ~:/\ ]) 3 1 1 1 2 2 3
┌─┬─────┬───┬─┐
│3│1 1 1│2 2│3│
└─┴─────┴───┴─┘

Using the same mechanism as suggested previously:

   ,@(] (# , {.);.1~ 1 , 2 ~:/\ ]) 3 1 1 1 2 2 3
1 3 3 1 2 2 1 3

If you are looking for a nice J implementation of the look-and-say sequence then I'd suggest the one on Rosetta Code:

   las=: ,@((# , {.);.1~ 1 , 2 ~:/\ ])&.(10x&#.inv)@]^:(1+i.@[)
   5 las 1           NB. left arg is sequence length, right arg is starting number
11 21 1211 111221 312211
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top