Threadthread=newThread("t1"){@Overridepublicvoidrun(){// TODO Auto-generated method stubSystem.out.println(Thread.currentThread().getName());}};thread.start();
如果调用start,则输出是t1
Threadthread=newThread("t1"){@Overridepublicvoidrun(){// TODO Auto-generated method stubSystem.out.println(Thread.currentThread().getName());}};thread.run();
publicvoidrun(){while(true){if(Thread.currentThread().isInterrupted()){System.out.println("Interruted!");break;}try{Thread.sleep(2000);}catch(InterruptedExceptione){System.out.println("Interruted When Sleep");//设置中断状态,抛出异常后会清除中断标记位Thread.currentThread().interrupt();}Thread.yield();}}
defcross(A,B):"Cross product of elements in A and elements in B."return[a+bforainAforbinB]digits='123456789'rows='ABCDEFGHI'cols=digitssquares=cross(rows,cols)unitlist=([cross(rows,c)forcincols]+[cross(r,cols)forrinrows]+[cross(rs,cs)forrsin('ABC','DEF','GHI')forcsin('123','456','789')])units=dict((s,[uforuinunitlistifsinu])forsinsquares)peers=dict((s,set(sum(units[s],[]))-set([s]))forsinsquares)
如果你对 Python 的一些特性不熟悉,请注意‘字典’是哈希表在Python中的叫法,它将每个键映射到一个值。dict((s, […]) for s in squares) 创建了一个字典,把每个方块 s 映射到是一个列表的值。表达式 [u for u in unitlist if s in u] 的意思是:这个值是由那些包含s的单元u构成的列表。所以这个赋值表达式要这么读:units是一个字典,其中每个方块映射到包含它的单元组成的列表。类似地,下一个赋值语句要这么读:peers 是个字典,其中每个方块s映射到s所属单元的方块的并集,但不包括 s 自身。
做一些测试是没有坏处的(它们都通过了):
deftest():"A set of unit tests."assertlen(squares)==81assertlen(unitlist)==27assertall(len(units[s])==3forsinsquares)assertall(len(peers[s])==20forsinsquares)assertunits['C2']==[['A2','B2','C2','D2','E2','F2','G2','H2','I2'],['C1','C2','C3','C4','C5','C6','C7','C8','C9'],['A1','A2','A3','B1','B2','B3','C1','C2','C3']]assertpeers['C2']==set(['A2','B2','D2','E2','F2','G2','H2','I2','C1','C3','C4','C5','C6','C7','C8','C9','A1','A3','B1','B3'])print'All tests pass.'
defparse_grid(grid):"""Convert grid to a dict of possible values, {square: digits}, or
return False if a contradiction is detected."""## To start, every square can be any digit; then assign values from the grid.
values=dict((s,digits)forsinsquares)fors,dingrid_values(grid).items():ifdindigitsandnotassign(values,s,d):returnFalse## (Fail if we can't assign d to square s.)
returnvaluesdefgrid_values(grid):"Convert grid into a dict of {square: char} with '0' or '.' for empties."chars=[cforcingridifcindigitsorcin'0.']assertlen(chars)==81returndict(zip(squares,chars))
defassign(values,s,d):"""Eliminate all the other values (except d) from values[s] and propagate.
Return values, except return False if a contradiction is detected."""other_values=values[s].replace(d,'')ifall(eliminate(values,s,d2)ford2inother_values):returnvalueselse:returnFalsedefeliminate(values,s,d):"""Eliminate d from values[s]; propagate when values or places <= 2.
Return values, except return False if a contradiction is detected."""ifdnotinvalues[s]:returnvalues## Already eliminated
values[s]=values[s].replace(d,'')## (1) If a square s is reduced to one value d2, then eliminate d2 from the peers.
iflen(values[s])==0:returnFalse## Contradiction: removed last value
eliflen(values[s])==1:d2=values[s]ifnotall(eliminate(values,s2,d2)fors2inpeers[s]):returnFalse## (2) If a unit u is reduced to only one place for a value d, then put it there.
foruinunits[s]:dplaces=[sforsinuifdinvalues[s]]iflen(dplaces)==0:returnFalse## Contradiction: no place for this value
eliflen(dplaces)==1:# d can only be in one place in unit; assign it there
ifnotassign(values,dplaces[0],d):returnFalsereturnvalues
在能走得更远之前,我们需要能显示一个谜题:
defdisplay(values):"Display these values as a 2-D grid."width=1+max(len(values[s])forsinsquares)line='+'.join(['-'*(width*3)]*3)forrinrows:print''.join(values[r+c].center(width)+('|'ifcin'36'else'')forcincols)ifrin'CF':printlineprint
defsolve(grid):returnsearch(parse_grid(grid))defsearch(values):"Using depth-first search and propagation, try all possible values."ifvaluesisFalse:returnFalse## Failed earlier
ifall(len(values[s])==1forsinsquares):returnvalues## Solved!
## Chose the unfilled square s with the fewest possibilities
n,s=min((len(values[s]),s)forsinsquaresiflen(values[s])>1)returnsome(search(assign(values.copy(),s,d))fordinvalues[s])defsome(seq):"Return some element of seq that is true."foreinseq:ife:returnereturnFalse
不幸的是,这不是一个真正的数独谜题,因为它有多个解。(它是在我包含了Olivier Grégoire关于8种不同数字的建议之前生成的,因此对于这个谜题的任何解,交换1和7,都得到另一个解。)但这是一个本质上很难的谜题吗?或者它的困难性是我的search程序所使用的变量顺序和值顺序方案的产物?为了检验,我随机化了值顺序(我把search最后一行中的for d in values[s]改成for d in shuffled(values[s]),我用了random.shuffle来实现shuffled)。结果明显地两边倒:30次尝试中的27次用了不到0.02秒,其他的3次每次用时都超过190秒(大约长了10000倍)。这个谜题有多个解,随机化的search找到13个不同的解。我的猜测是在搜索早期的某处,有一系列的方块(可能2个),如果我们选则了某种错误的值的组合来填充方块,就需要大约190秒来发现矛盾。但如果做了其他选择,我们很快要么发现一个解,要么发现矛盾,从另一个选择前进。因此算法的速度取决于它是否能避免选中致命的值组合。
importtime,randomdefsolve_all(grids,name='',showif=0.0):"""Attempt to solve a sequence of grids. Report results.
When showif is a number of seconds, display puzzles that take longer.
When showif is None, don't display any puzzles."""deftime_solve(grid):start=time.clock()values=solve(grid)t=time.clock()-start## Display puzzles that take long enough
ifshowifisnotNoneandt>showif:display(grid_values(grid))ifvalues:display(values)print'(%.2f seconds)n'%treturn(t,solved(values))times,results=zip(*[time_solve(grid)forgridingrids])N=len(grids)ifN>1:print"Solved %d of %d %s puzzles (avg %.2f secs (%d Hz), max %.2f secs)."%(sum(results),N,name,sum(times)/N,N/sum(times),max(times))defsolved(values):"A puzzle is solved if each unit is a permutation of the digits 1 to 9."defunitsolved(unit):returnset(values[s]forsinunit)==set(digits)returnvaluesisnotFalseandall(unitsolved(unit)forunitinunitlist)deffrom_file(filename,sep='n'):"Parse a file into a list of strings, separated by sep."returnfile(filename).read().strip().split(sep)defrandom_puzzle(N=17):"""Make a random puzzle with N or more assignments. Restart on contradictions.
Note the resulting puzzle is not guaranteed to be solvable, but empirically
about 99.8% of them are solvable. Some have multiple solutions."""values=dict((s,digits)forsinsquares)forsinshuffled(squares):ifnotassign(values,s,random.choice(values[s])):breakds=[values[s]forsinsquaresiflen(values[s])==1]iflen(ds)>=Nandlen(set(ds))>=8:return''.join(values[s]iflen(values[s])==1else'.'forsinsquares)returnrandom_puzzle(N)## Give up and make a new puzzle
defshuffled(seq):"Return a randomly shuffled copy of the input sequence."seq=list(seq)random.shuffle(seq)returnseqgrid1='003020600900305001001806400008102900700000008006708200002609500800203009005010300'grid2='4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......'hard1='.....6....59.....82....8....45........3........6..3.54...325..6..................'if__name__=='__main__':test()solve_all(from_file("easy50.txt",'========'),"easy",None)solve_all(from_file("top95.txt"),"hard",None)solve_all(from_file("hardest.txt"),"hardest",None)solve_all([random_puzzle()for_inrange(99)],"random",100.0)
defvanquishMonster(monsterIndex):delmonsterName[monsterIndex]delmonsterHealth[monsterIndex]delmonsterMagicPoints[monsterIndex]# Note there is no del for monsterInventory
vanquishMonster(0)
classLivingThing():def__init__(self,name,health,magicPoints,inventory):self.name=nameself.health=healthself.magicPoints=magicPointsself.inventory=inventory# Create the LivingThing object for the hero.
hero=LivingThing('Elsa',50,80,{})monsters=[]monsters.append(LivingThing('Goblin',20,0,{'gold':12,'dagger':1}))monsters.append(LivingThing('Dragon',300,200,{'gold':890,'magic amulet':1}))print('The hero %s has %s health.'%(hero.name,hero.health))
# Create the LivingThing object for the hero.
hero=LivingThing('Elsa',50,80,{})monsters=[LivingThing('Goblin',20,0,{'gold':12,'dagger':1}),LivingThing('Dragon',300,200,{'gold':890,'magic amulet':1}),LivingThing('Goblin',18,0,{'gold':15,'dagger':1})]print('The hero %s has %s health.'%(hero.name,hero.health))
def__init__(self,name,health,magicPoints,inventory):self.name=nameself.health=healthself.magicPoints=magicPointsself.inventory=inventoryself.hunger=0# all living things start with hunger level 0
deftakeDamage(livingThingObject,dmgAmount):livingThingObject.health=self.health-dmgAmountiflivingThingObject.health<0:print(livingThingObject.name+' is dead!')hero=LivingThing('Elsa',50,{})takeDamage(hero,10)# Elsa takes 10 points of damage
classLivingThing():# ...other code in the class...
deftakeDamage(self,dmgAmount):self.health=self.health-dmgAmountifself.health==0:print(self.name+' is dead!')# ...other code in the class...
hero=LivingThing('Elsa',50,{})hero.takeDamage(10)# Elsa takes 10 points of damage
hero=LivingThing('Elsa',50,{})# ...some more code...
ifsomeCondition:hero._health-=50# WAIT! This code is outside the hero object's class but modifying a private member variable! This must be a bug!