简体   繁体   English

在J中抽象盒装数组结构

[英]Abstracting boxed array structures in J

I've been working on a J function for a while, that's supposed to scan a list and put consecutive copies of an element into separate, concatenated boxes. 我一直在研究一个J函数,它应该扫描一个列表并将一个元素的连续副本放入单独的连接框中。 My efforts have taken me as far as the function 就功能而言,我的努力占据了我的位置

(<;. 2) ((2&(~:/\\)),1:)

which tests successive list entries for inequality, returns a list of boolean values, and cuts the list into boxes that end each time the number 1 appears. 它测试不等式的连续列表条目,返回一个布尔值列表,并将列表切割成每次出现数字1时结束的框。 Here's an example application: 这是一个示例应用程序:

   (<;. 2) ((2&(~:/\)),1:) 1 2 3 3 3 4 1 1 1
+-+-+-----+-+-----+
|1|1|0 0 1|1|0 0 1|
+-+-+-----+-+-----+

The task would be finished if I could then replace all those booleans with their corresponding values in the input argument. 如果我可以用输入参数中的相应值替换所有那些布尔值,那么任务就完成了。 I've been looking for some kind of mystery function that would let me do something like 我一直在寻找某种神秘功能,可以让我做类似的事情

   final =: mysteryfunction @ (<;. 2) ((2&(~:/\)),1:)

   final 1 2 3 3 3 4 1 1 1    
+-+-+-----+-+-----+
|1|2|3 3 3|4|1 1 1|
+-+-+-----+-+-----+

In an ideal situation, there would be some way to abstractly represent the nesting pattern generated by (<;. 2) ((2&(~:/\\)),1:) and apply it to the original input list. 在理想情况下,可以通过某种方式抽象地表示由(<;. 2) ((2&(~:/\\)),1:)生成的嵌套模式(<;. 2) ((2&(~:/\\)),1:)并将其应用于原始输入列表。 (ie "This boxed array over here has the first element boxed at depth one, the second element boxed at depth one, the third, fourth, and fifth elements boxed together at depth one,..., so take that unboxed list over there and box it up the same way.") I tried fooling around with ;. (即“这个盒装数组在这里有第一个元素,深度为1,第二个元素在深度为1,第三,第四和第五个元素在深度1处加在一起,......,所以请将那个未装箱的列表放在那里然后用同样的方式把它装箱。“)我试着愚弄;. , S: , L: , L. and &. S:L:L.&. to produce that behavior, but I haven't had much luck. 产生这种行为,但我没有太多运气。 Is there some kind of operator or principle I'm missing that could make this happen? 是否有某种操作员或原则我错过了可以实现这一点? It wouldn't surprise me if I were overthinking the whole issue, but I'm running out of ideas. 如果我过度思考整个问题,我不会感到惊讶,但我的想法已经不多了。

EDIT: 编辑:

At the moment, the only working solution I have is this one: 目前,我唯一有效的解决方案是:

isduplicate =: ((2&(~:/\)),1:)

testfun =: 3 : 0
numduplicates =. #S:0 ((<;.2) isduplicate y)
distinctboxes =. <"0 (isduplicate#]) y
numduplicates # each distinctboxes
)

It's a two-step process of generating the run-length encoding of the list and then undoing the encoding without getting rid of the boxes. 这是一个两步过程,用于生成列表的行程编码,然后在不删除框的情况下撤消编码。 Since I'm originally doing this with the aim of solving the 99 problems in tandem using J and Haskell, it feels like begging the question if I solve problem 9 by first solving problem 12. 因为我最初这样做的目的是使用J和Haskell一起解决99个问题 ,所以如果我通过首先解决问题12来解决问题9,感觉就像在乞求问题。

You're almost there. 你快到了。 Add a ~ and place the parentheses differently, and that's it: 添加一个~并以不同的方式放置括号,就是这样:

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

A quick explanation/illustration: 快速解释/说明:

   s =: 1 2 3 3 3 4 1 1 1

   f =: 2&(~:/\) , 1:
   f s
1 1 0 0 1 1 0 0 1

   g =: <;.2

   (f s) g s
┌─┬─┬─────┬─┬─────┐
│1│2│3 3 3│4│1 1 1│
└─┴─┴─────┴─┴─────┘

Now that final (fs) gs , sometimes referred to as a "left hook", can be written (g~ f) s (the adverb ~ is called "passive" in J, the Haskell counterpart would be flip ). 现在最后的(fs) gs ,有时被称为“左钩”,可以写成(g~ f) s (副词~在J中称为“被动”,Haskell对应物将被flip )。 Alternatively you could also tacitly write this as the fork (fg ]) s . 或者你也可以默认将它写为fork (fg ]) s

Chapter 9 of "Learning J" discusses this topic extensively, if you want to find out more. 如果您想了解更多信息,“学习J”的第9章将广泛讨论该主题。

Update : I previously used a grouping-based (</.~ (+/\\&(1,(2&(~:/\\))))) , but your original cut-based approach is more elegant (and shorter) than this. 更新 :我之前使用过基于分组的(</.~ (+/\\&(1,(2&(~:/\\))))) ,但是你原来的基于剪切的方法比更优雅(和更短)这个。 As this is really about the left hook, I updated to use your approach directly. 由于这是关于左钩拳,我更新直接使用您的方法。

I think you're overthinking it. 我认为你是在思考它。 Does it need to be completely tacit? 它需要完全默契吗? Here's something I just threw together: 这是我刚刚聚集在一起的东西:

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

Obviously it just assigns the input list to s then drops it into the ;. 显然它只是将输入列表分配给s然后将其放入;. expression. 表达。 If it needs to be completely tacit, I'm sure you can massage it to ravel the input list to to the boolean list, then use something like {. < ;.2 {: 如果它需要完全默认,我相信你可以按下它来将输入列表调到布尔列表,然后使用像{. < ;.2 {: {. < ;.2 {: to get the output. {. < ;.2 {:获取输出。

This version of the function I had in mind is better, but still not tacit enough to be perfect. 我想到的这个版本的功能更好,但仍然没有足够的默契完美。 (At least it doesn't beg the question for another problem down the road, at any rate.) Once I figure out how to represent the logic of that while loop as a tacit expression, I'll be all set. (无论如何,至少它不会在未来的问题上提出另一个问题。)一旦我弄清楚如何将while循环的逻辑表示为默认表达式,我将全部设定。

NB. boxmerge takes a boxed argument and razes the first two
NB. elements together into a new box.
boxmerge =: [:}.]1}~[:<[:;2&{.

NB. conseq checks to see whether the first two boxes of a boxed
NB. array contain the same distinct element. (By assumption, each
NB. box contains only one distinct element.) The name is an
NB. abbreviation of the question, "consecutive boxes equal?"
conseq =: [:=/[:~.&.>2&{.

partfun =: ]`(boxmerge)@.conseq ^:_

listpack =: 3 : 0
mylist =. y
listbin =. >a:
while. (mylist -: (>a:)) = 0 do.
 newlist =. partfun mylist
 listbin =. listbin,{. newlist
 mylist =. }. newlist
end.
listbin
)

The idea behind the while loop is to apply partfun to a list, ravel its head onto a different list, behead the original list, and continue doing that until the original list has been completely emptied. while循环背后的想法是将partfun应用于列表,将其partfun放在不同的列表上,将原始列表partfun为原始列表,然后继续执行此操作直到原始列表完全清空为止。 I feel like there really should be a way to represent that logic with tacit expressions. 我觉得应该有一种方法用默认表达来表示逻辑。 (In fact, I think I've even seen it in the online documentation.) I just can't think of the appropriate sequence of ^: 's, $: 's and @. (事实上​​,我认为我甚至已经在在线文档中看到过它。)我想不出^: 's, $: 's和@.的适当顺序@. 's I need to put the final nail in the coffin. 我需要把最后的钉子放在棺材里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM