# -*- coding:utf8 -*-
shape={
0:[(0,0),(1,0),(1,1),(1,2)],
1:[(0,0),(0,1),(1,0),(1,1),(1,2)],
2:[(0,0),(1,0),(1,1),(1,2),(1,3)],
3:[(0,1),(1,0),(1,1),(1,2),(1,3)],
4:[(0,0),(0,1),(1,1),(1,2),(1,3)],
5:[(0,0),(1,0),(1,1)],
6:[(0,0),(1,0),(2,0),(2,1),(2,2)],
7:[(0,0),(1,0),(1,1),(2,1),(2,2)],
8:[(0,0),(0,1),(1,0),(2,0),(2,1)],
9:[(0,0),(0,1),(0,2),(0,3)],
10:[(0,0),(1,0),(1,1),(0,1)],
11:[(1,0),(0,1),(1,1),(1,2),(2,1)],
}
allshape={}
field=[]
prepos=[]
def rotate(v, d):
ibin=[0]*5
rv0=max([vi[0] for vi in v])
rv1=max([vi[1] for vi in v])
dd=d/4
d%=4
ta= 1 if d<2 else -1
tb= -1 if (d%2)==1 else 1
for vi in v:
v0= vi[0] if ta>0 else (rv0+vi[0]*ta)
v1= vi[1] if tb>0 else (rv1+vi[1]*tb)
v0,v1 = (v1,v0) if dd==1 else (v0,v1)
ibin[v1] |= (1<<v0)
vmap=reduce(lambda x,y: x|y, ibin)
rot=0
while vmap&(1<<rot)==0:
rot+=1
if rot>0:
ibin=map(lambda x:x<<1, ibin)
trim=0
if ibin[trim]==0:
trim+=1
ibin=ibin[trim:]
trim=0
while trim<len(ibin) and ibin[trim]!=0:
trim+=1
return tuple(ibin[:trim])
def init():
for k,v in shape.items():
allshape[k]=set()
for d in xrange(8):
ret=rotate(v, d)
allshape[k].add(ret)
class bcolors:
block=['\033[91m','\033[92m','\033[93m','\033[94m','\033[95m',
'\033[96m','\033[97m','\033[98m','\033[99m','\033[100m',
'\033[90m','\033[89m' ]
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
def dump(binmap, info, pos):
print info
print "^^"*5
for b in binmap:
print str(bin(b))[2:]
print "**"*5
import unicodedata
def dumpput(blocks):
fields=[' '*10]*10
binfield=[0]*10
for i,b in enumerate(blocks):
for y,c in enumerate(b[0]):
binfield[b[2]+y]|=c<<b[1]
pos=0
while c>0:
if c&1 == 1:
fields[b[2]+y] = fields[b[2]+y][:pos+b[1]] + chr(ord('a')+i) + fields[b[2]+y][pos+b[1]+1:]
pos+=1
c>>=1
for col,f in enumerate(fields):
f=f[:col+1]
for i in xrange(12):
f=f.replace(chr(ord('a')+i), ["❤️","?","?","?","?","?","?","?","?","?","?","?"][i])
f=f.replace(' ','⭕')
print f
#
# print "----"*4
#
# for f in binfield:
# print bin(f)[2:]
print "===="*4
def addoneshape(target, current, used, shapeid, shape, pos):
pass
def rmoneshape(current, used, shapeid, shape):
pass
def tryfeed(targetmap, ks):
feed=[0]*10
check1=[0]*10
check2=[0]*10
bakcheck=[0]*10
for i,onek in enumerate(ks):
block=onek[0]
x0=onek[1]
y0=onek[2]
for y,b in enumerate(block):
if y0+y>=10: return False
feed[y0+y] |= b<<x0
if i&1 == 0:
check1[y0+y] |= b<<x0
check2[y0+y] &= b<<x0
else:
check1[y0+y] &= b<<x0
check2[y0+y] |= b<<x0
if i&1==0:
if check2!=bakcheck:
return False
else:
if check1!=bakcheck:
return False
if feed==targetmap:
return True
print feed
return False
def checkfeed(target, feed, failedpos):
cnt=0
for f in feed:
cnt+=1
if cnt%1000000 == 0:
print cnt
if tryfeed(target, f):
print f
return None
def findhole(targetfield):
lasth=[0]*12
for i,v in enumerate(targetfield):
if v<0:
v+=2**32
lasth[i+1]=v<<1
tmp=lasth[i]
oldtmp=lasth[i]
while tmp!=0:
tmp=tmp&(-tmp)
oldtmp-=tmp
#print "check:", tmp
tmp0=tmp<<1
tmp1=tmp>>1
tmp2=tmp>>2
tmp3=tmp>>3
if i>0:
if (tmp&lasth[i-1]) == 0 and (tmp&lasth[i+1])==0 and (tmp0&lasth[i])==0:
if tmp1&lasth[i] == 0: return True
if tmp2&lasth[i]==0 and tmp1&lasth[i-1]==0 and (tmp1&lasth[i+1])==0: return True
if tmp3&lasth[i]==0 and tmp1&lasth[i-1]==0 and tmp1&lasth[i+1]==0 \
and tmp2&lasth[i-1] and tmp2&lasth[i+1]: return True
if i>1:
if tmp&lasth[i-2]==0 and tmp&lasth[i+1]==0 \
and tmp0&lasth[i-1]==0 and tmp1&lasth[i-1]==0 \
and tmp0&lasth[i]==0 and tmp1&lasth[i]==0:
return True
if i>2:
if tmp&lasth[i-3]==0 and tmp&lasth[i+1]==0 \
and tmp0&lasth[i-1]==0 and tmp1&lasth[i-1]==0 \
and tmp0&lasth[i-2]==0 and tmp1&lasth[i-2]==0 \
and tmp0&lasth[i]==0 and tmp1&lasth[i]==0:
return True
tmp=oldtmp
return False
import itertools
maxdeep=0
def findans():
targetfield=[]
for i in xrange(0,10):
targetfield.append(((1<<(i+1))-1))
allshapes = allshape.values()
print "try......", targetfield
def putoneblock(targetfield, shapes, putblock):
global maxdeep
if len(shapes) == 0:
print putblock
return True
if len(putblock)>maxdeep:
maxdeep=len(putblock)
if maxdeep>=10:
print putblock
dumpput(putblock)
print "deep:",maxdeep
for s in shapes[0]:
for x in xrange(10):
for y in xrange(10):
backfield=targetfield[:]
passput=False
for ybase,sc in enumerate(s):
if y+ybase>=10:
passput=True
break
checkv=targetfield[y+ybase]
targetfield[y+ybase]^=sc<<x
if checkv!=(targetfield[y+ybase]|sc<<x):
passput=True
break
215 if not passput:
216 passput=findhole(targetfield)
if passput:
targetfield=backfield[:]
continue
putblock.append((s,x,y))
putoneblock(targetfield, shapes[1:], putblock[:])
del putblock[-1]
targetfield=backfield[:]
return False
putoneblock(targetfield, allshapes, [])
# ips=[]
# for ip in allshape.values():
# ips.append(itertools.product(ip, range(10), range(10)))
#
# putpos=itertools.product(*ips)
# ret=checkfeed(targetfield, putpos, failedpos)
# return ret
init()
findans()
DFS 求解金字塔10*10等腰直角三角形摆放
最新推荐文章于 2023-02-03 19:56:10 发布