一个逻辑题的解决方案和代码

一个逻辑题的解决方案和代码

题目:
"""下面五个人正在讨论刚刚结束的奥林匹克运动会。他们中有一个是讲真话的南区人,一个是讲假话的北区人,一个是既讲真话又讲假话的中区人,还有两个是局外人,他们要么先说两句真话,再说一句假话,要么先说两句假话,再说一句真话。他们的陈述如下:
A. 1.如果运动员都围腰布,我本来会参加的。
2.B不是南区人。
3.D没有得金牌。
4.C要不是有晒斑,本来会得金牌的。
B. 1.E得了银牌。
2.C第一次说的是假的。
3.C没有得奖牌。
4.E不是中区人就是局外人。
C. 1.我不是中区人。
2.我就是没有晒斑也得不了金牌。
3.B没有得铜牌。
4.B是南区人。
D. 1.我得了金牌。
2.B没有得铜牌。
3.如果运动员都围腰布,A本来会参加的。
4.C不是北区人。
E. 1.我得了金牌。
2.C就是没有晒斑也得不了金牌。
3.我不是南区人。
4.如果运动员都围腰布,A本来会参加的。
那么,谁是南区人,谁是北区人,谁是中区人,哪两个是局外人,谁得了奖牌呢?
"""
方案:
将每个人的四句话作
# coding:GB2312

从五个人中挑出两个来,分别假设为南区人和北区人,检查他俩的话是否有冲突
语义解释分为真时的情况和假时的情况,
冲突检查用了一个异常处理类

代码如下:
d.py

[Copy to clipboard] [ - ]
CODE:

# coding:GB2312
#语义解释
def a1(t):
if t==1:
  A.set_out(1)
  A.set_gold(0)
  A.set_silver(0)
  A.set_copper(0)
if t==0:
  pass
def a2(t):
if t==1:
  B.set_south(1) #2是南区人
  B.set_north(0) #2不是其他人
  B.set_middle(0)
  B.set_out(0)
  for i in range(4): #2所有话都为真
   B.set_trueness(i,1)
if t==0:
  B.set_south(0)
def a3(t):
if t==1:
  D.set_gold(0) #4没得金牌
if t==0:
  D.set_gold(1) #4得金牌
  D.set_out(0) #4不是局外人
def a4(t):
if t==1:
  C.set_sunburn(1) #3有晒斑
  C.set_gold(0) #3没得金牌
  #C.set_out(0) #3不是局外人
if t==0:
  pass
def b1(t):
if t==1:
  E.set_silver(1) #5得银牌
  E.set_out(0) #5不是局外人
if t==0:
  E.set_silver(0)
def b2(t):
if t==1:
  C.set_trueness(0,0) #3第一次假
  C.set_north(0) #3不是南区人
if t==0:
  C.set_trueness(0,1)
def b3(t):
if t==1:
  C.set_gold(0) #3没得任何奖牌
  C.set_silver(0)
  C.set_copper(0)
if t==0:
  C.set_out(0)
def b4(t):
if t==1:
  E.set_south(0) #5不是南区人
  E.set_north(0) #5不是北区人
if t==0:
  E.set_out(0)
  E.set_middle(0)
def c1(t):
if t==1:
  C.set_middle(0) #3不是中区人
if t==0:
  C.set_middle(1)
  C.set_south(0)
  C.set_north(0)
  C.set_out(0)
def c2(t):
if t==1:
  C.set_sunburn(0) #3没晒斑
  C.set_gold(0) #3没金牌
if t==0:
  pass
def c3(t):
if t==1:
  B.set_copper(0) #2没有铜牌
if t==0:
  B.set_copper(1)
  B.set_out(0)
c4=a2
def d1(t):
if t==1:
  D.set_gold(1) #4得金牌
  D.set_out(0) #4不是局外人
if t==0:
  D.set_gold(0)
def d2(t):
if t==1:
  B.set_copper(0) #2没铜牌
if t==0:
  B.set_copper(1)
  B.set_out(0) #2不是局外人
d3=a1
def d4(t):
if t==1:
  C.set_north(0) #3不是北区人
if t==0:
  C.set_north(1)
  C.set_south(0)
  C.set_middle(0)
  C.set_out(0)
  for i in range(4):
   C.set_trueness(i,0)
def e1(t):
if t==1:
  E.set_gold(1) #5得金牌
  E.set_out(0) #5不是局外人
if t==0:
  E.set_gold(0)
e2=c2
def e3(t):
if t==1:
  E.set_south(0) #5不是南区人
if t==0:
  E.set_south(1) #2是南区人
  E.set_north(0) #2不是其他人
  E.set_middle(0)
  E.set_out(0)
  for i in range(4): #2所有话都为真
   E.set_trueness(i,1)
e4=a1
all_words=[a1, a2, a3, a4, b1, b2, b3, b4, \
c1, c2, c3, c4, d1, d2, d3, d4, e1, e2, e3, e4]
class ConflictException(Exception):
    '''A user-defined exception class.'''
    def __init__(self):
        Exception.__init__(self)
#定义类,并初始化对象
class Person:
def __init__(self,name,words):
  self.name=name
  self.south=self.north=self.middle=self.out=\
  self.gold=self.silver=self.copper=self.sunburn=-1
  self.words=words
  self.trueness=[-1,-1,-1,-1]
def test_wrong_status(self):
  snmo=[self.south, self.north, self.middle, self.out]
  count=0
  for i in snmo:
   if i==1:
    count+=1
  if count>1:
   raise ConflictException()
def out_init(self):
  self.south=self.north=self.middle=self.out=\
  self.gold=self.silver=self.copper=self.sunburn=-1
  self.trueness=[-1,-1,-1,-1]
def set_south(self, value):
  if self.south!=value and self.south!=-1:
   raise ConflictException()
  self.south=value
  self.test_wrong_status()
def set_north(self, value):
  if self.north!=value and self.north!=-1:
   raise ConflictException()
  self.north=value
  self.test_wrong_status()
def set_middle(self, value):
  if self.middle!=value and self.middle!=-1:
   raise ConflictException()
  self.middle=value
  self.test_wrong_status()
def set_out(self, value):
  if self.out!=value and self.out!=-1:
   raise ConflictException()
  self.out=value
  self.test_wrong_status()
def set_gold(self, value):
  if self.gold!=value and self.gold!=-1:
   raise ConflictException()
  else:
   self.gold=value
def set_silver(self, value):
  if self.silver!=value and self.silver!=-1:
   raise ConflictException()
  else:
   self.silver=value
def set_copper(self, value):
  if self.copper!=value and self.copper!=-1:
   raise ConflictException()
  else:
   self.copper=value
def set_sunburn(self, value):
  if self.sunburn!=value and self.sunburn!=-1:
   raise ConflictException()
  else:
   self.sunburn=value
def set_trueness(self, id, value):
  if self.trueness[id]!=value and self.trueness[id]!=-1:
   raise ConflictException()
  else:
   self.trueness[id]=value
def run_words(self):
  try:
   for i in range(4):
    each=self.words[i](self.trueness[i])
  except ConflictException:
   return 0
  return 1

def show_me(self):
  k=0
  status=["south", "north", "middle", "out"]
  bb=[self.south, self.north, self.middle, self.out]
  for i in zip(bb,status):
   if i[0]==1:
    print self.name, "i am ", i[1]
A=Person('A', all_words[0:4])
B=Person('B', all_words[4:8])
C=Person('C', all_words[8:12])
D=Person('D', all_words[12:16])
E=Person('E', all_words[16:20])

test.py

[Copy to clipboard] [ - ]
CODE:
# coding:GB2312
#随机调出两个人,分别为南区人和北区人,对各对象强制赋值
import d
A=d.A
B=d.B
C=d.C
D=d.D
E=d.E
all_people=[A,B,C,D,E]
def all_init():
for i in all_people:
  i.out_init()
def all_show():
for i in all_people:
  i.show_me()
def if_south(p):
try:
  p.set_south(1)
  p.set_north(0)
  p.set_middle(0)
  p.set_out(0)
  for i in range(4): #p所有话都为真
   t=p.set_trueness(i, 1)
except d.ConflictException:
  return 0
return 1
def if_north(p):
try:
  p.set_north(1)
  p.set_south(0)
  p.set_middle(0)
  p.set_out(0)
  for i in range(4): #p所有话都为假
   t=p.set_trueness(i,0)
except d.ConflictException:
  return 0
return 1
def perm(pp, n):
r=[]
if n==1:
  for i in range(len(pp)):
   r.append([pp[i]])
  return r
else:
  for i in range(len(pp)):
   rest=pp[:i]+pp[i+1:]
   for j in perm(rest,n-1):
    r.append([pp[i]]+j)
  return r
def main():
index=perm(range(5), 2)
for i in index:
  all_init()
  [s,n]=all_people[i[0]], all_people[i[1]]
  test=[if_south(s), s.run_words(), if_north(n), n.run_words()]
  if test==[1,1,1,1,]:
   print "ok"
   print s.name, n.name
   all_show()
  else:
   #print "fail"
   continue
main()