Skip to content

Instantly share code, notes, and snippets.

@josyb
Last active July 2, 2016 17:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josyb/ab46119bcdb06c077288ae4dd0c6252e to your computer and use it in GitHub Desktop.
Save josyb/ab46119bcdb06c077288ae4dd0c6252e to your computer and use it in GitHub Desktop.
Doing zigzag 'My Way' ...
'''
Created on 2 Jul 2016
@author: Josy
a question by Merkourios Katsimpris on gitter:myhdl triggered me to look at
http://paddy3118.blogspot.nl/2008/08/zig-zag.html
while the solution presented there is (very probably) very pythonic
you need to read the explanation to understand what or why it is doing
so I took a shot to deliver some 'annotated' code ...
a zigzag of 4:
0 - 1 5 - 6
/ / /
2 4 7 12
| / [o]
3 8 11 13
9 10 14 15
and 5:
0 - 1 5 - 6 14
/ / /
2 4 7 13 15
| / /
3 8 [12] 16 21
/ /
9 11 17 20 22
| /
10 18 19 23 24
the [] is our centre or 'pivot' point
'''
from __future__ import print_function
import math
def zigzag( dimension):
''' generate the zigzag indexes for a square array
I exploit the fact that an array is symmetrical around its
centre
'''
NUMBER_INDEXES = dimension ** 2
HALFWAY = NUMBER_INDEXES // 2
KERNEL_ODD = dimension & 1
xy = [0 for _ in range(NUMBER_INDEXES)]
# start at 0,0
ix = 0
iy = 0
# 'fake' that we are going up and right
direction = 1
# the first index is always 0, so start with the second
# until halfway
for i in range(1, HALFWAY + KERNEL_ODD):
if direction > 0:
# going up and right
if iy == 0:
# are at top
ix += 1
direction = -1
else:
ix += 1
iy -= 1
else:
# going down and left
if ix == 0:
# are at left
iy += 1
direction = 1
else:
ix -= 1
iy += 1
# update the index position
xy[iy * dimension + ix] = i
# have first half, but they are scattered over the list
# so find the zeros to replace
for i in range(1, NUMBER_INDEXES):
if xy[i] == 0 :
xy[i] = NUMBER_INDEXES - 1 - xy[NUMBER_INDEXES - 1 - i]
return xy
def main(dim):
zz = zigzag(dim)
print( 'zigzag of {}:'.format(dim))
width = int(math.ceil(math.log10(dim**2)))
for j in range(dim):
for i in range(dim):
print('{:{width}}'.format(zz[j * dim + i], width=width), end=' ')
print()
if __name__ == '__main__':
main(4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment