Skip to main content
added 6 characters in body
Source Link
Luis Mendo
  • 105.3k
  • 9
  • 135
  • 372
tt     % Take the input implicitly and push two more copies
&n     % Get its size as two (equal) numbers: N, N
:qt    % Push range [0  1 ... N-1] twice. This represents the original x values
&+     % Matrix of all pairwise additions. This represents x+y
&y     % Push a copy of N onto the top of the stack
\      % Modulo. This is the new y coordinate, say: y_new
t      % Push another copy
b+     % Bubble up the remaining copy of [0 1 ... N-1] and add. This is 2*x+y
&y     % Push a copy of N onto the top of the stack
\      % Modulo. This is the new x coordinate, say: x_new
b*+    % Bubble up the remaining copy of N, multiply, add. This computes
       % x_new*N+y_new, which is the linear index for those x_new, y_new 
Q      % Add 1, because MATL uses 1-based indexing
(      % Assigmnent indexing: write the values of the original matrix into
       % (another copy of) the original matrix at the entries given by the
       % indexing matrix. Implicitly display the result
tt    % Take the input implicitly and push two more copies
&n    % Get its size as two (equal) numbers: N, N
:qt   % Push range [0  1 ... N-1] twice. This represents the original x values
&+    % Matrix of all pairwise additions. This represents x+y
&y    % Push a copy N onto the top of the stack
\     % Modulo. This is the new y coordinate, say y_new
t     % Push another copy
b+    % Bubble up the remaining copy of [0 1 ... N-1] and add. This is 2*x+y
&y    % Push a copy N onto the top of the stack
\     % Modulo. This is the new x coordinate, say x_new
b*+   % Bubble up the remaining copy of N, multiply, add. This computes
      % x_new*N+y_new, which is the linear index for those x_new, y_new 
Q     % Add 1, because MATL uses 1-based indexing
(     % Assigmnent indexing: write the values of the original matrix into
      % (another copy of) the original matrix at the entries given by the
      % indexing matrix. Implicitly display the result
tt     % Take the input implicitly and push two more copies
&n     % Get its size as two (equal) numbers: N, N
:qt    % Push range [0  1 ... N-1] twice. This represents the original x values
&+     % Matrix of all pairwise additions. This represents x+y
&y     % Push a copy of N onto the top of the stack
\      % Modulo. This is the new y coordinate: y_new
t      % Push another copy
b+     % Bubble up the remaining copy of [0 1 ... N-1] and add. This is 2*x+y
&y     % Push a copy of N onto the top of the stack
\      % Modulo. This is the new x coordinate: x_new
b*+    % Bubble up the remaining copy of N, multiply, add. This computes
       % x_new*N+y_new, which is the linear index for those x_new, y_new 
Q      % Add 1, because MATL uses 1-based indexing
(      % Assigmnent indexing: write the values of the original matrix into
       % (another copy of) the original matrix at the entries given by the
       % indexing matrix. Implicitly display the result
added 2802 characters in body
Source Link
Luis Mendo
  • 105.3k
  • 9
  • 135
  • 372

###Explanation

A matrix in MATL can be indexed with a single index instead of two. This is called linear indexing, and uses column-major order. This is illustrated by the following 4×4 matrix, in which the value at each entry coincides with its linear index:

1   5   9  13
2   6  10  14
3   7  11  15
4   8  12  16

There are two similar approaches to implement the mapping in the challenge:

  1. Build an indexing matrix that represents Arnold's inverse mapping on linear indices, and use it to select the values from the original matrix. For the 4×4 case, the indexing matrix would be

     1  8 11 14
    15  2  5 12
     9 16  3  6
     7 10 13  4
    

telling that for example the original 5 at x=2, y=1 goes to x=3, y=2. This operation is called reference indexing: use the indexing matrix to tell which element to pick from the original matrix. This is functon ), which takes two inputs (in its default configuration).

  1. Build an indexing matrix that represents Arnold's direct mapping on linear indices, and use it to write the values into the original matrix. For the 4×4 case, the indexing matrix would be

     1 10  3 12
     6 15  8 13
    11  4  9  2
    16  5 14  7
    

telling that the entry x=2, y=1 of the new matrix will be overwritten onto the entry with linear index 10, that is, x=3, y=2. This is called assignment indexing: use the indexing matrix, a data matrix and the original matrix, and write the data onto the original matrix at the specified indices. This is function (, which takes three inputs (in its default configuration).

Method 1 is more straightforward, but method 2 turned out to be shorter.

tt    % Take the input implicitly and push two more copies
&n    % Get its size as two (equal) numbers: N, N
:qt   % Push range [0  1 ... N-1] twice. This represents the original x values
&+    % Matrix of all pairwise additions. This represents x+y
&y    % Push a copy N onto the top of the stack
\     % Modulo. This is the new y coordinate, say y_new
t     % Push another copy
b+    % Bubble up the remaining copy of [0 1 ... N-1] and add. This is 2*x+y
&y    % Push a copy N onto the top of the stack
\     % Modulo. This is the new x coordinate, say x_new
b*+   % Bubble up the remaining copy of N, multiply, add. This computes
      % x_new*N+y_new, which is the linear index for those x_new, y_new 
Q     % Add 1, because MATL uses 1-based indexing
(     % Assigmnent indexing: write the values of the original matrix into
      % (another copy of) the original matrix at the entries given by the
      % indexing matrix. Implicitly display the result

###Explanation

A matrix in MATL can be indexed with a single index instead of two. This is called linear indexing, and uses column-major order. This is illustrated by the following 4×4 matrix, in which the value at each entry coincides with its linear index:

1   5   9  13
2   6  10  14
3   7  11  15
4   8  12  16

There are two similar approaches to implement the mapping in the challenge:

  1. Build an indexing matrix that represents Arnold's inverse mapping on linear indices, and use it to select the values from the original matrix. For the 4×4 case, the indexing matrix would be

     1  8 11 14
    15  2  5 12
     9 16  3  6
     7 10 13  4
    

telling that for example the original 5 at x=2, y=1 goes to x=3, y=2. This operation is called reference indexing: use the indexing matrix to tell which element to pick from the original matrix. This is functon ), which takes two inputs (in its default configuration).

  1. Build an indexing matrix that represents Arnold's direct mapping on linear indices, and use it to write the values into the original matrix. For the 4×4 case, the indexing matrix would be

     1 10  3 12
     6 15  8 13
    11  4  9  2
    16  5 14  7
    

telling that the entry x=2, y=1 of the new matrix will be overwritten onto the entry with linear index 10, that is, x=3, y=2. This is called assignment indexing: use the indexing matrix, a data matrix and the original matrix, and write the data onto the original matrix at the specified indices. This is function (, which takes three inputs (in its default configuration).

Method 1 is more straightforward, but method 2 turned out to be shorter.

tt    % Take the input implicitly and push two more copies
&n    % Get its size as two (equal) numbers: N, N
:qt   % Push range [0  1 ... N-1] twice. This represents the original x values
&+    % Matrix of all pairwise additions. This represents x+y
&y    % Push a copy N onto the top of the stack
\     % Modulo. This is the new y coordinate, say y_new
t     % Push another copy
b+    % Bubble up the remaining copy of [0 1 ... N-1] and add. This is 2*x+y
&y    % Push a copy N onto the top of the stack
\     % Modulo. This is the new x coordinate, say x_new
b*+   % Bubble up the remaining copy of N, multiply, add. This computes
      % x_new*N+y_new, which is the linear index for those x_new, y_new 
Q     % Add 1, because MATL uses 1-based indexing
(     % Assigmnent indexing: write the values of the original matrix into
      % (another copy of) the original matrix at the entries given by the
      % indexing matrix. Implicitly display the result
Source Link
Luis Mendo
  • 105.3k
  • 9
  • 135
  • 372

MATL, 23 bytes

tt&n:qt&+&y\tb+&y\b*+Q(

The (0,0) point is upper left, as in the examples in the challenge text.

Try it online!