On 3/2/2010 2:54 PM David Eccles (gringer) said...
I've managed to drum up some code to obtain a list containing joined diagonal
elements of a matrix (I'm making a word finder generator), but am wondering if
there's any better way to do this:

This works. Lots of other ways would work too. What would make one better than another? Anyway, here's my take on it...

#<pasteable_code>

# setup so code snippet works properly
sizeW = 4
sizeH = 3
puzzleLayout = ['spam'] * (sizeW * sizeH)

# this allows the result to match your example

from string import digits,letters
puzzleLayout = (digits+letters)[:sizeW * sizeH]


# Starting with, say, an array with these indices:

# It might help to consider the indices numbers as that's what
# python does, so I've assumed these to be the values instead.

# 0 1 2 3
# 4 5 6 7
# 8 9 A B

# Looking at the index table above, note that all the results
# start on an edge and work diagonally from there.  I'll guess
# you found the back diags easier -- no messy 'in-the-same-row'
# problems -- but the forward diags are harder.  Note if we
# flype the table the forward diags can be built from the back
#
diag instructions

#FpuzzleLayout
# 8 9 A B
# 4 5 6 7
# 0 1 2 3

# so we'll build it once like this...
FpuzzleLayout = "".join(
  [ puzzleLayout[ii-sizeW:ii]
    for ii in range(sizeW*sizeH,0,-sizeW)
    ] )

#So now, the only starting positions we need to worry about are
# on the left and top edge ignoring the start and end corners.
edge = (range(sizeW * sizeH,0,-sizeW)+range(sizeW-1))[2:]

# and to avoid any modular impact, we'll add a length constraint
lens = range(2,sizeH+1)+range(sizeW-1,1,-1)

# and do it
result = []

for ii,ln in zip(edge,lens):
  result.append(puzzleLayout[ii::sizeW+1][:ln])
  result.append(FpuzzleLayout[ii::sizeW+1][:ln])


# now add in the reversed results
for ii in result[:]:
  result.append("".join(reversed(ii)))

# and the corners
result.extend([puzzleLayout[0],
               puzzleLayout[-1],
               FpuzzleLayout[0],
               FpuzzleLayout[-1]])


#</pasteable_code>

Emile


# I want the following items for a back diagonal (not in square brackets):
# [-2],[3],8 (+5) | div 4 = -1, 1, 2
# [-1],4,9 (+5)   | div 4 = -1, 1, 2
# 0,5,A (+5)      | div 4 =  0, 1, 2
# 1,6,B (+5)      | div 4 =  0, 1, 2
# 2,7,[C] (+5)    | div 4 =  0, 1, 3
# 3,[8],[D] (+5)  | div 4 =  0, 2, 3

# in other words, increase sequence by sizeW + 1 each time (sizeW - 1
# for forward diagonals), only selecting if the line you're on matches
# the line you want to be on

# back as in backslash-like diagonal
puzzleDiagBack = [(''.join([puzzleLayout[pos*(sizeW+1) + i] \
for pos in range(sizeH) if (pos*(sizeW+1) + i) / sizeW == pos])) \
for i in range(-sizeH+1,sizeW)]
puzzleDiagBackRev = [(''.join(reversed([puzzleLayout[pos*(sizeW+1) + i] \
for pos in range(sizeH) if (pos*(sizeW+1) + i) / sizeW == pos]))) \
for i in range(-sizeH+1,sizeW)]
# fwd as in forwardslash-like diagonal
puzzleDiagFwdRev = [(''.join([puzzleLayout[pos*(sizeW-1) + i] \
for pos in range(sizeH) if (pos*(sizeW-1) + i) / sizeW == pos])) \
for i in range(sizeW+sizeH-1)]
puzzleDiagFwd = [(''.join(reversed([puzzleLayout[pos*(sizeW-1) + i] \
for pos in range(sizeH) if (pos*(sizeW-1) + i) / sizeW == pos]))) \
for i in range(sizeW+sizeH-1)]

Cheers,
David Eccles (gringer)
_______________________________________________
Tutor maillist  -tu...@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor



_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to