Modifying one line of an array

I just started learning J and there is something I don’t know how to work correctly

Suppose I want to print a 2 character checkerboard like

baba
abab
baba

      

To do this, I assumed that you can simply create an array

baba
baba
baba

      

and flip the second line.

Creating an array of very simple 3 4 $ 'ba'

. But reversing the second line is where I am struggling.

I can get a back reference to the second line executing |. 1 { 3 4 $ 'ba'

, but that only gives me the second line, not the whole array. I can't see how to use the J syntax, I can actually keep the top and bottom line and only apply |.

to the middle line.

More generally, how would you apply to |.

just every other line?

+3


source to share


5 answers


What did you ask

To apply |.

to a single line, try something like:

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

      

To undo all other lines, I don't know if there is something simpler:

   ,/ 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

      

This makes use of a relatively obscure feature in the dyad \ (Infix)

:

x m\ y

applies sequential gerund verbs m

to infixes y

, expanding cyclically m

as needed.

Here x

is 1, so our infix is ​​just 1 Γ— 4 matrices; we loop the gerund ( ] ` (|."1)

) to alternate doing nothing ( ]

) and changing one row of the submatrix ( |."1

). We then flatten the resulting 5 Γ— 1 Γ— 4 array back to a 5 Γ— 4 matrix with ,/

.



Instead, you might want

An easier way to achieve a "checkerboard" is as follows: first, use +/

on two ranges to create a "padding table", for example:

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

      

Then take all of these mod 2 values ​​to get a checkerboard pattern of 0s and 1s:

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

      

Then index from the select string with {

:

   (2 | (i.3) +/ (i.4)) { 'ba'
baba
abab
baba

      

+4


source


Method 1: change }

Replace the second line with the modified line:

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

      

or in general, replace with a pattern a =: 4 $ 'ab'

for indices i =: +:i.5

:

a i } 10 4 $ 'ba'

      

Path 2: Gerund Cycling and Cutting ;.

You can cycle verbs by binding them to `. For every other line (rank "1

) you want to either do nothing ]

or reverse |.

:



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

      

Method 3: using a different template

You can see your template as 4 $ 'ba'

, followed by its inverse:

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

      

By the way,

odd sized (3) even patterned ('ba') lets you simplify |: 4 3 $ 'ba'

.

+4


source


Well, you already have many answers, but none of them were the first that popped into my head, so I'll add the following:

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

      

This takes advantage of the fact that rotating the middle row by 1 looks the same as flipping. You can generalize this by calculating the longest list of 0s and 1s as needed based on the number of lines in your chessboard.

+4


source


The approach I would try would not require reversing the rows of the array, but it works by rephrasing the situation in a friendly way.

I would add a column to the array to have columns of an odd number (5) with an even number of elements ('ba'), then remove the last element in each row.

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

      

+3


source


Here's another way to reformulate this particular problem in "friendship," as Bob said. It does not "change one line", but achieves the desired result in a different way.

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

      

+2


source







All Articles