language-agnosticcode-golfrosetta-stone

Code Golf: Zigzag pattern scanning


The Challenge

The shortest code by character count that takes a single input integer N (N >= 3) and returns an array of indices that when iterated would traverse an NxN matrix according to the JPEG "zigzag" scan pattern. The following is an example traversal over an 8x8 matrixsrc:

zigzag layout pattern

Examples

(The middle matrix is not part of the input or output, just a representation of the NxN matrix the input represents.)

                1 2 3
(Input) 3  -->  4 5 6  -->  1 2 4 7 5 3 6 8 9 (Output)
                7 8 9

                1  2  3  4
(Input) 4  -->  5  6  7  8  -->  1 2 5 9 6 3 4 7 10 13 14 11 8 12 15 16 (Output)
                9 10 11 12
               13 14 15 16

Notes

Bonus

Extend your answer to take two inputs N and M (N, M >=3) and perform the same scan over an NxM matrix. (In this case N would be the number of columns and M the number of rows.)

Bonus Examples

                  1  2  3  4
(Input) 4 3  -->  5  6  7  8  -->  1 2 5 9 6 3 4 7 10 11 8 12 (Output)
                  9 10 11 12

                   1  2  3
(Input) 3 4  -->   4  5  6  -->  1 2 4 7 5 3 6 8 10 11 9 12 (Output)
                   7  8  9
                  10 11 12

Solution

  • J, 13 15 characters

    ;<@|.`</.i.2$
    

    Usage:

       ;<@|.`</.i.2$  3
    0 1 3 6 4 2 5 7 8
    
       ;<@|.`</.i.2$  4
    0 1 4 8 5 2 3 6 9 12 13 10 7 11 14 15
    

    Explanation

    (NB. is J's comment indicator)

    ;         NB. Link together...
    <@|.`<    NB. ... 'take the reverse of' and 'take normally'
    /.        NB. ... applied to alternating diagonals of...
    i.        NB. ... successive integers starting at 0 and counting up to fill an array with dimensions of...
    2$        NB. ... the input extended cyclically to a list of length two.
    

    J, bonus, 13 characters

    ;<@|.`</.i.|.
    

    Usage:

       ;<@|.`</.i.|. 3 4
    0 1 3 6 4 2 5 7 9 10 8 11
    
       ;<@|.`</.i.|. 9 6
    0 1 9 18 10 2 3 11 19 27 36 28 20 12 4 5 13 21 29 37 45 46 38 30 22 14 6 7 15 23 31 39 47 48 40 32 24 16 8 17 25 33 41 49 50 42 34 26 35 43 51 52 44 53