MoyaSystem

もやしです。

運命の出会いは何通り?を強引に解いてみました

codeIQの問題「今週のアルゴリズム 運命の出会いは何通り?」を解いてみました。
https://codeiq.jp/ace/thisweek_masuipeo/q711
この手の道順を考える問題は辺の長さが大きくなると計算量が爆発的に増えるんで、アルゴリズムをうまく考える必要があるんでしょうけども、
全然思いつかなかったのですべての道の組み合わせを総当たりで点検するという暴挙に出てしまいました。己の無力さを呪うばかり。解説を楽しみにします。。

import os
# reset files
girlFile = 'girlRoot.txt'
boyFile = 'boyRoot.txt'
os.remove(girlFile)
os.remove(boyFile)

# define static values
sideLength = 2

# find valid root
for i in range(2**(2*sideLength)):
	# transfer number to binary digits
	root = ('{0:0>' + str(2*sideLength) + 'b}').format(i)
	if root.count('1') == sideLength:
		girlX = 0
		girlY = sideLength
		boyX = sideLength
		boyY = 0
		girlRoot = []
		boyRoot = []
		for j in list(root):
			if j == '0':
				girlX +=1
				boyX -=1
			else:
				girlY -=1
				boyY +=1
			girlRoot.append((girlX, girlY))
			boyRoot.append((boyX, boyY))
		f = open(girlFile,'a')
		f.write(str(girlRoot))
		f.write('\n')
		f.close()
		f = open(boyFile,'a')
		f.write(str(boyRoot))
		f.write('\n')
		f.close()
else:
	# find "destiny" root
	count = 0
	gf = open(girlFile, 'r')
	gline = gf.readline()
	while gline:
		girl = eval(gline)
		bf = open(boyFile, 'r')
		bline = bf.readline()
		while bline:
			passbyCount = 0
			boy = eval(bline)
			for i in range(2*sideLength-1):
				# whether stop same point or not
				if girl[i] == boy[i]:
					count += 1
					break
				# whether pass by more than twice or not
				if girl[i][0] == boy[i][0] or girl[i][1] == boy[i][1]:
					passbyCount += 1
				if passbyCount == 2:
					count += 1
					break
			bline = bf.readline()
 		gline = gf.readline()
 		bf.close()
	gf.close()
	print count
	print 'end'