3

我正在尝试在 J 中实现A006751。在 Haskell 中很容易做到,例如:

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

(显然这还不完整,但它是它的基本核心。我花了大约 10 秒的时间,所以相应地对待它。)我可以在 J 中相当容易地实现任何这些,但我无法理解的部分是一个很好的、惯用的部分对应于 Haskellgroup函数的 J 算法。我可以写一个笨拙的,但感觉不像好J。

group任何人都可以在良好的 J 中实现 Haskell吗?

4

2 回答 2

4

组通常用/.副词完成。

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

如您所见,它不是顺序的。只需像这样使您的密钥连续(基本上确定一个项目是否与下一个项目不同,并对结果 0 和 1 进行运行总和):

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

然后我需要一个函数来计算项目(#),并告诉我它们是什么({. 只选择第一个)。我从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

如果你想要第 n 个结果,只需使用 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
于 2012-03-05T15:11:16.547 回答
3

我同意/.( Key ) 是将动词应用于 J 中的组的最佳通用方法。在这种情况下,我们需要对相同的连续数字进行分组的另一种方法是二元法;.(Cut):

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

我们可以形成品格用作左参数,如下所示:

   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

将两者放在一起:

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

使用与之前建议的相同机制:

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

如果您正在寻找外观和说序列的一个很好的 J 实现,那么我建议您使用 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
于 2012-03-06T11:30:32.147 回答