nested lists as arrays
Michael Spencer
mahs at telcopartners.com
Mon Feb 14 18:43:03 EST 2005
Terry Reedy wrote:
> <benjamin.cordes at blawrc.de> wrote in message
> news:1108402043.941832.34110 at f14g2000cwb.googlegroups.com...
>
>> def setRandomState(self):
>> # container for the elements to pick from
>> container = [1,2,3,4,5,6,7,8,-1]
>>
>> # create elements of puzzle randomly
>> i = 0
>> j = 0
>> while i <= self.dim-1:
>> while j <= self.dim-1:
>> if len(container) > 0:
>> randomindex = random.randint(0,len(container)-1)
>> self.elements[j][i] = container[randomindex]
>> del container[randomindex]
>> j=j+1
>> else:
>> break
>> j=0
>> i=i+1
>
>
> Without reading closely, I believe that the above can generate any possible
> position. Are you aware that half are unsolvable? If that matters, you
> need to either find a book or site that explains the parity test for
> solvability or generate the start position from the goal position by a
> series of random moves.
>
> Terry J. Reedy
>
This covers the test for solvability - enjoy ;-):
http://www.cs.tcd.ie/publications/tech-reports/reports.01/TCD-CS-2001-24.pdf
BTW, just because your puzzle looks like a grid doesn't neceesarily mean that
representing the data as nested arrays is easiest. A flat list might be just as
good here. It simplifies some of the operations (creating a random ordering
becomes a one-liner), at the expense of a little more complexity in some others:
import random
class n2grid(object):
"""A grid for the n squared puzzle"""
def __init__(self,dim = 4):
self.cells = range(dim*dim)
self.dim = dim
self.pos = (0,0)
def shuffle(self):
random.shuffle(self.cells)
self.pos = divmod(self.cells.index(0),self.dim)
def show(self):
for row in self._asarray():
print "".join("[%2s]" % (cell or "") for cell in row)
def _move(self,dy,dx):
dim = self.dim
cells = self.cells
oldy, oldx = self.pos
newy, newx = oldy + dy, oldx + dx
if 0 <= newx < dim and 0 <= newy < dim:
ix = newy * dim + newx
ox = oldy * dim + oldx
cells[ix], cells[ox] = cells[ox], cells[ix]
self.pos = newy,newx
else:
raise Exception, "Illegal move to: (%s,%s)" % (newy, newx)
def move(self, dx, dy):
try:
self._move(dx,dy)
self.show()
except:
pass
def _asarray(self): #create the array representation when needed
cells = iter(self.cells)
dim = self.dim
return [[cells.next() for j in range(dim)] for i in range(dim)]
def __repr__(self):
return repr(self._asarray())
>>> p = n2grid()
>>> p.show()
...
[ ][ 1][ 2][ 3]
[ 4][ 5][ 6][ 7]
[ 8][ 9][10][11]
[12][13][14][15]
>>> p.shuffle()
>>> p.show()
[ 3][15][ 6][ 7]
[10][ ][12][ 5]
[ 4][ 1][14][ 8]
[ 2][11][13][ 9]
>>> p.move(1,1)
[ 3][15][ 6][ 7]
[10][14][12][ 5]
[ 4][ 1][ ][ 8]
[ 2][11][13][ 9]
>>> p.move(1,0)
[ 3][15][ 6][ 7]
[10][14][12][ 5]
[ 4][ 1][13][ 8]
[ 2][11][ ][ 9]
>>> p.move(1,0) # illegal (does nothing)
>>>
Cheers
Michael
More information about the Python-list
mailing list