python - All possible combinations of numbers of length 5 in a 4X4 matrix -


i have matrix

1 9 2 3 5 0 0 6 8 4 4 8 2 3 7 8 

i need find possible combinations of numbers of length 5.

constraints:

  1. starting form position in matrix can move next immediate neighbor i.e if u start form (0,0) neighbor must (0,1),(1,1),(1,0) , if pick position form position can move immediate neighbor , on.

  2. the length of number must 5 digit's i.e example if start (0,0) value 1 can produce sequence 15151 or 19232 or 10063 on can move in sequence constraint 1 applied.

  3. the solution must produce output in 7sec , python preferred since favorite. ;)

ok missed things program must use 16 numbers i.e must use 16 numbers initial , produce 5 digit sequence.

first, have think how start @ 1 position in matrix , move adjacent one.

the brute force method list available cells , adjacent cells each:

nextpos = {     (0,0): [(1,0), (1,1), (0,1)],     (0,1): [(0,0), (1,0), (1,1), (1,2), (0,2)],     (0,2): [(0,1), (1,1), (1,2), (1,3), (0,3)],     (0,3): [(0,2), (1,2), (1,3)],     # etc } allpos = nextpos.keys() 

for problem small, pretty simple; however, there chance of typos. solution write generator function:

def nextpos(p,w=4,h=4):     """     @param p     current position tuple (x,y)     @param w     width of matrix     @param h     height of matrix      generate matrix cells adjacent current 1     """     rel = ((-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1))      x,y = p     dx,dy in rel:         nx,ny = x+dx, y+dy         if 0<=nx<w , 0<=ny<h:             yield (nx,ny) 

once know cells next each other, can proceed seek valid paths:

def matrix_path(pathlen, startfrom=none):     """     @param pathlen    length of path return     @param startfrom  initial location      generate adjacency paths through matrix     """      # bad path length - quit gracefully     if pathlen<1:         yield []         return      # no starting point specified - start @ point     if startfrom none:         pos in allpos:             res in matrix_path(pathlen, pos):                 yield res         return      # end of path     if pathlen==1:         yield [startfrom]         return      # current point, recurse find rest of path     pos in nextpos[startfrom]:         morepath in matrix_path(pathlen-1, pos):             yield [startfrom]+morepath 

we can find out how long takes profiling:

import cprofile  def test():     sols = [i in matrix_path(5)]     print len(sols), "paths found"  cprofile.run("test()") 

which returns

16860 paths found 121497 function calls (16865 primitive calls) in 0.678 cpu seconds

this returns list of lists of cell-positions; want turn actual values matrix,

def path_vals(mx, path):     """     @param mx    matrix data     @param path  list of cell positions      return list of values list of cell positions     """      return tuple([mx[x][y] x,y in path]) 

then

mx = [     [1,9,2,3],     [5,0,0,6],     [8,4,4,8],     [2,3,7,8] ]  def test():     sols = [path_vals(mx, i) in matrix_path(5)] 

we want reduce list unique results:

def test():     usol = list(set([path_vals(mx, i) in matrix_path(5)]))     print len(usol),"unique results"  cprofile.run("test()") 

which gives us

8651 unique results 138357 function calls (33725 primitive calls) in 0.845 cpu seconds


Comments

Popular posts from this blog

Add email recipient to all new Trac tickets -

asp.net - repeatedly call AddImageUrl(url) to assemble pdf document -

java - Android recognize cell phone with keyboard or not? -