Golfscript Diagonal Array

11

1

Is there a way in Golfscript to bring all of the diagonals of an array into a single array?

For example, for the array

[[1 2 3][4 5 6][7 8 9]]

return

[[7][4 8][1 5 9][2 6][3]]

(not necessarily in that order) and for

["ABCD""EFGH""IJKL"]

return

["I""EJ""AFK""BGL""CH""D"]

(not necessarily in that order). Assume the lengths of the arrays are the same.

I am struggling with figuring it out. I tried doing something with = and iterating through the (length+1)th character of the strings, but that didn't work. Can someone help me?

I'd like the shortest way to do this, if possible.

Josiah Winslow

Posted 2014-09-18T22:24:00.197

Reputation: 725

This isn't your regular Q&A site; you need to have a winning criterion. I suggest a popularity content for starters. – Timtech – 2014-09-18T23:40:49.563

@Timtech I understand. I'll try regular stackexchange. – Josiah Winslow – 2014-09-18T23:50:17.240

7

Language-specific golf advice questions are officially on-topic: http://meta.codegolf.stackexchange.com/a/1725/20260

– xnor – 2014-09-19T00:02:44.537

5

@xnor You linked to wrong answer there. That one is about those tips lists we have. But asking for specific advice is also on topic so it would be nice if people could stop downvoting and close voting this.

– Martin Ender – 2014-09-19T07:22:56.447

Tips most definitely are on topic, but should be posted as community wiki. However I'm not convinced that this question should be reopened as the main Golfscrip tips question already has several answers that are as specific as the one requested here. Maybe anyone who has an answer should post it there. http://codegolf.stackexchange.com/q/5264/15599

– Level River St – 2014-09-19T15:45:31.750

7@steveverrill I don't agree that these should be made CW. That only applies to the list questions (in fact, I don't even agree that those should be CW), but there's really no reason for specific advice question to be CW - they are basically micro-optimisation golfing contests, and the people answering them do deserve the rep for it (as does the asker, if the question is interesting). – Martin Ender – 2014-09-19T16:21:35.577

Answers

8

Consider

[
    "ABCD"
    "EFGH"
    "IJKL"
]

To obtain the main diagonal and the diagonals above it, we can shift out the first char of the second row and the first two of the third:

[
    "ABCD"
    "FGH"
    "KL"
]

Note that all columns correspond to a diagonal, so "zipping" the array (i.e., transposing rows and columns) will yield an array containing the aforementioned four diagonals:

[
    "AFK"
    "BGL"
    "CH"
    "D"
]

We're still missing the diagonals below the main diagonal.

If we zip A itself and repeat the above process, we'll obtain an array containing the main diagonal and all diagonals below it. All that's left it to compute the set union of both arrays.

Putting it all together:

[.zip]{:A,,{.A=>}%zip}/|


[.zip]{              }/  # For the original array and it's transpose, do the following:
       :A                # Store the array in A.
         ,,{    }%       # For each I in [ 0 1 ... len(A) ], do the following:
            .A=>         # Push A[I] and shift out its first I characters.
                  zip    # Transpose the resulting array.
                       | # Perform set union.

Try it online.

Finally, if we only need the diagonals because we're searching for a string inside them (like in the Word Search Puzzle, which I assume inspired this question), a "less clean" approach might also be suitable.

You can use

..,n**\.0=,\,+)/zip

to obtain all diagonals, plus some unnecessary linefeed characters.

I've explained the process in detail in this answer.

Try it online.

Dennis

Posted 2014-09-18T22:24:00.197

Reputation: 196 637