修改数组的一行

Modifying one row of an array

我才刚刚开始学习J,有些事情我不知道该怎么做

假设我想打印一个包含 2 个符号的棋盘,例如

baba
abab
baba

为此,我假设您可以生成一个数组

baba
baba
baba

并反转第二行。

生成数组很简单:3 4 $ 'ba'。但是倒转第二排是我挣扎的地方。

我可以通过 |. 1 { 3 4 $ 'ba' 得到第二行的相反结果,但这只会给我第二行,而不是整个数组。我看不出如何使用 J 语法实际上可以保留顶行和底行并且仅将 |. 应用于中间行。

更一般地说,您如何 |. 每隔一行应用一次?

你问什么

要将 |. 应用到一行,请尝试以下方法:

   x =: 3 4 $ 'ba'
   (|. 1{x) 1} x
baba
abab
baba

隔行反转,不知道有没有比这更简单的:

   ,/ 1 (]`(|."1))\ i. 5 4
 0  1  2  3
 7  6  5  4
 8  9 10 11
15 14 13 12
16 17 18 19

这使用了 relatively obscure feature 的 dyad \ (Infix):

x m\ y applies successive verbs from the gerund m to the infixes of y, extending m cyclically as required.

这里,x是1,所以我们的"infixes"就是1×4的矩阵;我们循环遍历动名词 (] ` (|."1)) 以在什么都不做 (]) 和反转子矩阵的单行 (|."1) 之间交替。然后,我们用 ,/.

将生成的 5×1×4 数组展平回 5×4 矩阵

您可能想要什么

实现 "checkerboard" 的更简单方法如下:首先,在两个范围上使用 +/ 来创建 "addition table",如下所示:

   (i.3) +/ (i.4)
0 1 2 3
1 2 3 4
2 3 4 5

然后取所有这些值mod2,得到0s和1s的棋盘格图案:

   2 | (i.3) +/ (i.4)
0 1 0 1
1 0 1 0
0 1 0 1

然后使用 {:

从选择的字符串中索引
   (2 | (i.3) +/ (i.4)) { 'ba'
baba
abab
baba

方式一:修改}

用更改后的行替换第二行:

( 4 $ 'ab') (1 }) m =: 3 4 $ 'ba'

或者通常,在索引 i =: +:i.5:

处用模式 a =: 4 $ 'ab' 替换
a i } 10 4 $ 'ba'

方式 2:循环使用动名词和 cut ;.

您可以通过在动词前加上 ` 来循环应用动词。对于其他每一行(排名 "1),您想要什么也不做 ] 或反转 |.:

(]"1)`(|."1) ;.1 m

方式 3:使用不同的模式

您可以将您的模式视为 4 $ 'ba' 后跟它的反义词:

3 $ (,:|.) 4 $ 'ba'

顺便说一句,

具有偶数模式 ('ba') 的奇数维度 (3) 让您可以更简单 |: 4 3 $ 'ba'.

我尝试的方法不需要反转数组的行,而是通过以 J 友好的方式重构情况来工作。

我会在数组中添加一列,这样我就有奇数列 (5) 和偶数个元素 ('ba'),然后去掉每行中的最后一项。

   4 5$'ba'
babab
ababa
babab
ababa
   }:"1 (4 5$'ba')
baba
abab
baba
abab

好吧,你已经有了很多答案,但是其中 none 个是我第一个想到的,所以我会添加这个:

0 1 0 |."(0 1) 3 4$'ba'

这利用了将中间行旋转 1 看起来与翻转它一样的事实。您可以根据棋盘中的行数根据需要计算尽可能长的 0 和 1 列表来概括这一点。

正如鲍勃所说,这是在 "J friendly way" 中重新构建此特定问题的另一种方法。它没有 "modify one row" 但以不同的方式达到了预期的结果。

   |: 4 3 $ 'ba'  NB. transpose a 4x3 matrix
baba
abab
baba