我正在尝试 J,为了让事情顺利进行,我决定编写一个函数:
- 获取整数N;
- 生成一个遵循以下模式的表格:
(N = 4
的示例)
1
0 1
0 0 1
0 0 0 1
即每行中零的数量从 0
增加到 N - 1
。
但是,作为新手,我陷入了困境。我当前针对 N = 4
情况的费力(且不正确)的解决方案如下所示:
(4 # ,: 0 1) #~/"1 1 (1 ,.~/ i.4)
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
它的问题是双重的:
- 它不够通用,看起来有点难看(parens 和
"
用法); - 尾随零 - 据我了解,J 中的所有数组都是同构的,因此在我的情况下,每一行都应该装箱。
像这样:
┌───────┐
│1 │
├───────┤
│0 1 │
├───────┤
│0 0 1 │
├───────┤
│0 0 0 1│
└───────┘
或者我应该使用字符串(例如 '0 0 1'
),该字符串将用空格而不是零填充。
所以,我在这里恳请的是:
- 请为此任务提供一个惯用的 J 解决方案并进行解释;
- 批评我的尝试并指出如何完成它。
提前致谢!
最佳答案
就像 J 中的许多挑战一样,有时最好将注意力集中在结果上,并找到不同的方法来实现目标。在这种情况下,您最初的方法是创建一个单位矩阵。我会用
=/~@:i. 4
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
您已经正确识别了尾随 0 的问题以及 J 将用 0 填充以避免数组参差不齐的事实。装箱避免了这种填充,因为每一行都是独立的。
所以首先创建您的列表。我会使用 overtake 来获得额外的 0
4{.1
1 0 0 0
下一行使用 1:
返回 1 作为动词,并将超越从 1 到 4 框起来
(>:@:i. <@:{."0 1:) 4
+-+---+-----+-------+
|1|1 0|1 0 0|1 0 0 0|
+-+---+-----+-------+
由于我们希望将其反转然后制成字符串,因此我们将 ":@:|.@:
添加到该过程中。
(>:@:i. <@:":@:|.@:{."0 1:) 4
+-+---+-----+-------+
|1|0 1|0 0 1|0 0 0 1|
+-+---+-----+-------+
然后我们拆箱
>@:(>:@:i. <@:":@:|.@:{."0 1:) 4
1
0 1
0 0 1
0 0 0 1
我不确定这是每个人都会解决问题的方法,但它确实有效。
另一种解决方案,不使用装箱并使用二元 j。 (复杂)以及事实
1j4 # 1
1 0 0 0 0
(1 j. 4) # 1
1 0 0 0 0
(1 #~ 1 j. ]) 4
1 0 0 0 0
因此,我为 i 中的每个整数创建一个列表。 4
,然后将它们反转,变成字符串。由于它们现在是字符串,因此额外的填充是用空格完成的。
(1 ":@:|.@:#~ 1 j. ])"0@:i. 4
1
0 1
0 0 1
0 0 0 1
逐步说明这一点,希望能够更好地解释。
i.4
0 1 2 3
然后一次将其应用于 (1 ":@:|.@:#~ 1 j. ])
一个原子,因此使用 "0
分解括号内发生的事情。我首先选择正确的三个动词来形成 fork 。
( 1 j. ])"0@:i.4
1 1j1 1j2 1j3
现在,这实际上给了我
1 ":@:|.@:#~ 1 1j1 1j2 1j3
fork 的中尖成为作用于两个名词参数的动词。~
交换参数。所以它相当于
1 1j1 1j2 1j3 ":@:|.@:# 1
由于 @:
的工作方式与
": |. 1 1j1 1j2 1j3 # 1
我还没有显示这些组件的结果,因为在 fork 上使用“0
会改变发送到中齿并稍后组装的参数的方式。我希望有这里已经足够了,只要挥手解释就足够了
从默认到显式的跳跃可能是一个很大的过程,因此显式地写出相同的动词来看看它是否更有意义可能是一个更好的练习。
lowerTriangle =: 3 : 0
rightArg=. i. y
complexCopy=. 1 j. rightArg
1 (":@:|.@:#~)"0 complexCopy
)
lowerTriangle 4
1
0 1
0 0 1
0 0 0 1
lowerTriangle 5
1
0 1
0 0 1
0 0 0 1
0 0 0 0 1
看看当你“开始行动”时会发生什么?我想 J 的特点是,无论你从哪里开始,球都会沿着一个相当陡的斜坡下降。令人兴奋,是吗?
关于j - 按照 J 中指定的模式生成数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47609977/