初次Python 暴力解益智遊戲 ( 三 )
除了細節稍做改良之外,提供路徑打印模式,有答案便能快速給出路徑。現在配合人腦,勉強能解出5 * 5。
還有些功能正在思考怎麼實作比較好:
像是若知道某些字串存在,但不知道何時何地使用,是否能做合理的剪枝。
也該做某種東西顯示它大略的進度,否則還要跑多久是完全不會有概念的。
import enchant from collections import Counter d = enchant.Dict( "en_US" ) f = open( 'banned', 'r' ) banned = set() for line in f: banned.add( line[ : -1 ] ) MAXLEN = 0 dx = [ 0, 1, 0, -1, 1, -1, 1, -1 ] dy = [ 1, 0, -1, 0, -1, 1, 1, -1 ] def outOfRange( x, y ): return x < 0 or x >= n or y < 0 or y >= m def drop( g, path ): T = [ "" for i in xrange( n ) ] for i in xrange( n ): T[ i ] = g[ i ][ : ] for ( i, j ) in path: T[ i ] = T[ i ][ 0 : j ] + '$' + T[ i ][ j + 1 : ] for _i in xrange( n ): for j in xrange( m ): i = n - _i - 1 if T[ i ][ j ] != '$': continue k = i while T[ k ][ j ] == '$': k -= 1 if k < 0: break if k >= 0: T[ i ] = T[ i ][ 0 : j ] + T[ k ][ j ] + T[ i ][ j + 1 : ] T[ k ] = T[ k ][ 0 : j ] + '$' + T[ k ][ j + 1 : ] """for i in xrange( n ): for j in xrange( m ): print T[ i ][ j ], print ''""" return T def printPath( path ): G = [ [ '$' for j in xrange( m ) ] for i in xrange( n ) ] cnt = 1 for ( x, y ) in path: G[ x ][ y ] = cnt cnt += 1 print '--------' for i in xrange( n ): for j in xrange( m ): print G[ i ][ j ], print '' def rsolve( g, slist, plist, depth ): if PRINT_MODE == -1: return global ans, vis, PRINT_MODE if depth == dpt: if PRINT_MODE: for path in plist: printPath( path ) PRINT_MODE = -1 else: print slist # ans.append( slist ) return for i in xrange( n ): for j in xrange( m ): if g[ i ][ j ] != '$': for _i in xrange( n ): for _j in xrange( m ): vis[ depth + 1 ][ _i ][ _j ] = 0 dfs( g, i, j, [], [], slist, plist, depth + 1 ) def dfs( g, sx, sy, vc, path, slist, plist, depth ): if PRINT_MODE == -1: return if len( vc ) > MAXLEN: return global vis, ans vis[ depth ][ sx ][ sy ] = 1 vc.append( g[ sx ][ sy ] ) path.append( ( sx, sy ) ) s = ''.join( vc ) if PRINT_MODE and s not in ans: path.pop() vc.pop() vis[ depth ][ sx ][ sy ] = 0 return if qlen[ len( s ) ] > 0 and d.check( s ) and s not in banned: qlen[ len( s ) ] -= 1 T = drop( g, path ) slist.append( s ) if PRINT_MODE: plist.append( path ) rsolve( T, slist, plist, depth ) if PRINT_MODE: plist.pop() slist.pop() qlen[ len( s ) ] += 1 for di in xrange( 8 ): nx = sx + dx[ di ] ny = sy + dy[ di ] if outOfRange( nx, ny ): continue if g[ sx ][ sy ] == '$': continue if vis[ depth ][ nx ][ ny ]: continue dfs( g, nx, ny, vc, path, slist, plist, depth ) path.pop() vc.pop() vis[ depth ][ sx ][ sy ] = 0 """def printAns(): if len( ans ) == 0: print "Answer not found, maybe some letter must be capitalized." else: for s in ans: print s """ def solve(): rsolve( G, [], [], 0 ) # printAns() G = [ "" for i in xrange( 8 ) ] vis = [ [ [ 0 for i in xrange( 8 ) ] for j in xrange( 8 ) ] for depth in xrange( 30 ) ] ans = set() qlen = Counter() PRINT_MODE = 0 n = int( input( "n ( 999 for PRINTPATH mode )= " ) ) if n == 999: PRINT_MODE = 1 n = int( input( "n = " ) ) m = int( input( "m = " ) ) q = int( input( "q = " ) ) for i in xrange( q ): if PRINT_MODE: s = ( raw_input( "Ans %d = " % ( i + 1 ) ) ) for i in xrange( len( s ) + 1 ): ans.add( s[ 0 : i ] ) qlen[ len( s ) ] += 1 MAXLEN = max( MAXLEN, len( s ) ) else: v = ( int( input( "len %d : " % ( i + 1 ) ) ) ) qlen[ v ] += 1 MAXLEN = max( MAXLEN, v ) dpt = int( input( "Try depth = " ) ) for i in xrange( n ): G[ i ] = raw_input( "Row %d : " % ( i + 1 ) ) solve()