我一直在研究一个 J 函数,它应该扫描一个列表并将一个元素的连续副本放入单独的连接框中。我的努力已经把我带到了功能
(<;. 2) ((2&(~:/\)),1:)
它测试连续列表条目的不等式,返回布尔值列表,并将列表切割成每次出现数字 1 时结束的框。这是一个示例应用程序:
(<;. 2) ((2&(~:/\)),1:) 1 2 3 3 3 4 1 1 1
+-+-+-----+-+-----+
|1|1|0 0 1|1|0 0 1|
+-+-+-----+-+-----+
如果我可以用输入参数中的相应值替换所有这些布尔值,那么任务就完成了。我一直在寻找某种神秘的功能,可以让我做类似的事情
final =: mysteryfunction @ (<;. 2) ((2&(~:/\)),1:)
final 1 2 3 3 3 4 1 1 1
+-+-+-----+-+-----+
|1|2|3 3 3|4|1 1 1|
+-+-+-----+-+-----+
在理想情况下,将有某种方法可以抽象地表示由生成的嵌套模式(<;. 2) ((2&(~:/\)),1:)
并将其应用于原始输入列表。(即“这里的装箱数组的第一个元素在深度一装箱,第二个元素在深度一装箱,第三、第四和第五个元素在深度一装箱......,所以把那个未装箱的列表放在那里并以相同的方式将其装箱。”)我尝试使用;.
, S:
, L:
,L.
和&.
产生这种行为,但我没有太多运气。是否有某种我缺少的运算符或原则可以使这种情况发生?如果我过度思考整个问题,我不会感到惊讶,但我已经没有想法了。
编辑:
目前,我唯一可行的解决方案是这个:
isduplicate =: ((2&(~:/\)),1:)
testfun =: 3 : 0
numduplicates =. #S:0 ((<;.2) isduplicate y)
distinctboxes =. <"0 (isduplicate#]) y
numduplicates # each distinctboxes
)
这是一个两步过程,生成列表的游程编码,然后撤消编码而不删除框。由于我最初这样做的目的是使用 J 和 Haskell 一起解决99 个问题,所以如果我通过首先解决问题 12 来解决问题 9,感觉就像在乞求这个问题。