用ADT方法转换程序python

2024-05-16 20:33:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我是一个初级程序员。在

我一直在为一个任务编写六猜算法的智囊解算器代码。在

(关于mastermind及其算法的更多信息:Mastermind on wiki

我几天前就知道了。但是我们的教授设置了固定的模板,然后我不知道如何将我的代码转换成它。在

下面是我的代码。可能有点尴尬,但它很管用,也不那么慢。在


def product(*args, repeat=1):
    pools = [list(pool) for pool in args] * repeat
    result = [[]]
    for pool in pools:
        result = [x+[y] for x in result for y in pool]
    for prod in result:
        yield list(prod)

def sort_list(total_list):
    d0=list()
    d1=list()
    d2=list()
    d3=list()
    d4=list()

    for x in total_list:
        mlist=list()
        alist = x
        n = 0
        while n<4:
            m = alist.count(alist[n])
            mlist.append(m)
            n = n + 1
        if max(mlist)==1:
            d0.append(alist)
        elif max(mlist)==2 and mlist.count(2)==2:
            d1.append(alist)
        elif max(mlist)==2 and mlist.count(2)>2:
            d2.append(alist)
        elif max(mlist)==3 :
            d3.append(alist)
        elif max(mlist)==4 :
            d4.append(alist)

    total_list = d0+d1+d2+d3+d4
    possible = [''.join(p) for p in total_list]
    return total_list

def computeFeedback(code,guess):    
    b = 0
    w = 0
    inCodeCount = {'A':0,'B':0,'C':0,'D':0, 'E':0, 'F':0}
    inGuessCount = {'A':0,'B':0,'C':0,'D':0, 'E':0, 'F':0}
    for i in range(0,4):
        if code[i] == guess[i]:
            b += 1
        inCodeCount[code[i]]+=1
        inGuessCount[guess[i]]+=1
    for ch in inCodeCount:
        w+=min(inCodeCount [ch], inGuessCount [ch])
    w-=b 
    feedback = str(w)+'w'+str(b)+'b'
    return feedback

guesscount=0
code=input()
while guesscount<8:
    guesscount += 1
    if guesscount==1:
        guess='ABCD'
        print("My guess is:",guess)
        feedback=computeFeedback(code,guess)
        if feedback!='0w4b':
            combinations=sort_list([''.join(x) for x in product('ABCDEF',repeat=4)])
            overlap=list()
            for x in combinations:
                fb=computeFeedback(guess,x)
                overlap.append(x)
                if fb != feedback:
                    overlap.pop()
            common=overlap
            overlap=list()

        else:
            print("Game Over in", guesscount,"steps")
            break
    if guesscount==2:
        guess='BCDE'
        print("My guess is:",guess)
        feedback=computeFeedback(code,guess)
        if feedback!='0w4b':
            combinations=sort_list([''.join(x) for x in product('ABCDEF',repeat=4)])
            overlap=list()
            for x in combinations:
                fb=computeFeedback(guess,x)
                overlap.append(x)
                if fb != feedback:
                    overlap.pop()
            common=[token for token in overlap if token in common]
            overlap=list()

        else:
            print('Game Over in,', guesscount,'steps')
            break
    if guesscount==3:
        guess='CDEF'
        print("My guess is:",guess)
        feedback=computeFeedback(code,guess)
        if feedback!='0w4b':
            combinations=sort_list([''.join(x) for x in product('ABCDEF',repeat=4)])
            overlap=list()
            for x in combinations:
                fb=computeFeedback(guess,x)
                overlap.append(x)
                if fb != feedback:
                    overlap.pop()
            common=[token for token in overlap if token in common]

            overlap=list()
        else:
            print('Game Over in', guesscount,'steps')
            break
    if guesscount==4:
        if common[0]=="acfb".upper():
            guess="dcad".upper()
        if common[0]=="aebf".upper():
            guess="edfd".upper()
        if common[0]=='AEFB':
            guess='EACC'
        if common[0]=='AFBE':
            guess='BFCD'
        if common[0]=='BAFE':
            guess='EADC'
        if common[0]=='BEAF':
            guess='EDAE'
        if common[0]=='BEFA':
            guess='EEDA'
        if common[0]=='EABF':
            guess='FDFB'
        if common[0]=='AADB':
            guess='BABD'
        if common[0]=='ABAE':
            guess='BBCC'
        if common[0]=='AEAF':
            guess='CFFD'
        if common[0]=='CAFA':
            guess='FDFA'
        if common[0]=='AAEE':
            guess='DDDF'
        else:
            guess=common[0]
        print("My guess is:",guess)
        if len(common)>1:
            common.pop(0)

            feedback=computeFeedback(code,guess)
            if feedback!='0w4b':
                combinations=sort_list([''.join(x) for x in product('ABCDEF',repeat=4)])
                overlap=list()
                for x in combinations:
                    fb=computeFeedback(guess,x)
                    overlap.append(x)
                    if fb != feedback:
                        overlap.pop()
                common=[token for token in overlap if token in common]
                overlap=list()
            else:
                print('Game Over in', guesscount,'steps')
                break
        else:
            print('Game Over in', guesscount,'steps') 
            break
    if guesscount==5:
        guess=common[0]
        print("My guess is:",guess)
        if len(common)>1:
            common.pop(0)

            feedback=computeFeedback(code,guess)
            if feedback!='0w4b':
                combinations=sort_list([''.join(x) for x in product('ABCDEF',repeat=4)])
                overlap=list()
                for x in combinations:
                    fb=computeFeedback(guess,x)
                    overlap.append(x)
                    if fb != feedback:
                        overlap.pop()
                common=[token for token in overlap if token in common]

                overlap=list()
            else:
                print('Game Over in', guesscount,'steps')
                break
        else:
            print('Game Over in', guesscount,'steps')
            break
    if guesscount==6:
            guess=common[0]
            print("My guess is:",guess)
            if len(common)>1:
                common.pop(0)

                feedback=computeFeedback(code,guess)
                if feedback!='0w4b':
                    combinations=sort_list([''.join(x) for x in product('ABCDEF',repeat=4)])
                    overlap=list()
                    for x in combinations:
                        fb=computeFeedback(guess,x)
                        overlap.append(x)
                        if fb != feedback:
                            overlap.pop()
                    common=[token for token in overlap if token in common]

                    overlap=list()
                else:
                    print('Game Over in', guesscount,'steps')
                    break
            else:
                print('Game Over in', guesscount,'steps')
                break
    if guesscount==7:
            guess=common[0]
            print("My guess is:",guess)
            if len(common)>1:
                common.pop(0)
                feedback=computeFeedback(code,guess)
                if feedback!='0w4b':
                    combinations=sort_list([''.join(x) for x in product('ABCDEF',repeat=4)])
                    overlap=list()
                    for x in combinations:
                        fb=computeFeedback(guess,x)
                        overlap.append(x)
                        if fb != feedback:
                            overlap.pop()
                    common=[token for token in overlap if token in common]

                    overlap=list()
                else:
                    print('Game Over in', guesscount,'steps')
                    break
            else:
                print('Game Over in', guesscount,'steps')
                break
if guesscount==8:
    print('Failure')

是的,这里是我必须完成的代码破译器功能的模板和运行该功能的策划器引擎:


模板

^{pr2}$

发动机

from mastermind import CodeBreaker

def computeFeedback(code,guess):
    # Given a code and guess computes the feedback string

    b = 0
    w = 0
    inCodeCount = {'A':0,'B':0,'C':0,'D':0, 'E':0, 'F':0}
    inGuessCount = {'A':0,'B':0,'C':0,'D':0, 'E':0, 'F':0}
    for i in range(0,4):
        if code[i] == guess [i]:
            b += 1
        inCodeCount[code[i]] += 1
        inGuessCount[guess[i]] += 1
    for ch in inCodeCount:
        w += min(inCodeCount [ch], inGuessCount [ch])
    w -= b 
    feedback = str(w)+'w'+str(b)+'b'
    return feedback

code = input()

while (code != None):
    guesscount = 0
    myBreaker = CodeBreaker()
    while (guesscount < 8):
        guess = myBreaker.makeGuess()
        print("My guess is:",guess)
        guesscount += 1
        feedback = computeFeedback(code, guess)
        print(feedback)
        if feedback == "0w4b":
            print("Game Over in", guesscount,"steps")
            break
        myBreaker.getFeedback(feedback)
    if guesscount == 8:
        print("Failed to find the solution in 8 steps")
    code = input()

我不擅长上课。我甚至不知道init应该包含什么。有人能帮忙吗?在

非常感谢!在


Tags: intokenforfbifcodecommonlist
1条回答
网友
1楼 · 发布于 2024-05-16 20:33:17

将代码转换为类的最简单方法是将所有代码放入getFeedback方法中,除了不计算要计算的猜测之外,self.guess属性中的猜测,并在下次调用makeGuess函数时返回该猜测。您还需要将所有全局变量(如common)转换为属性(比如self.common)。以下是草图:

class CodeBreaker:
    def __init__(self):
        self.guess_count = 0
        self.guess = 'ABCD'
        self.common = []

    def makeGuess(self):
        return self.guess

    def getFeedback(self, feedback):
        self.guess_count += 1
        if self.guess_count == 1:
            # ... your code here ...
            self.guess = 'BCDE'
        elif self.guess_count == 2:
            # ... your code here ...
            self.guess = 'CDEF'
        elif self.guess_count == 3:
            # ... your code here ...
        # ... and so on ...

我要补充的是,你的代码非常重复。以下更改是值得的:

  1. Python标准库已经包含了一个函数^{},它执行函数product的工作(尽管它以不同的方式获取参数),因此您最好使用它。

  2. 为每个猜测复制出基本上相同的代码(生成组合集,根据最近的猜测评估组合,更新common等等)。将这些代码放入方法中应该很简单,这样就不必多次复制它。

  3. 猜测数为4或更高的代码几乎是相同的:当然根本不需要复制这个代码(只需编写if guesscount >= 4:并同时处理它们)。

您可能需要研究这个类(它使用了与您的解决方案类似的方法,但所有重复都被删掉了),然后看看是否可以弄清楚它是如何工作的:

^{pr2}$

在最坏的情况下,这个算法最多需要8次猜测,但是您有8次可用的猜测,所以没关系。如果你只有六个猜测,那么你就需要一个更聪明的方法。下面的替代算法基于一个前瞻性的移动进行最佳猜测,最多需要6次猜测。(但是它运行得很慢!)同样,您可能会发现研究它是如何工作的(提示:它使用minimum of a list of maxima)。在

    def getFeedback(self, feedback):
        self.codes = [c for c in self.codes if computeFeedback(c, self.guess) == feedback]
        def key(g): return max(Counter(computeFeedback(c, g) for c in self.codes).values())
        self.guess = min(self.codes, key = key)

这里是Knuth's five-guess algorithm(运行速度更慢):

    def getFeedback(self, feedback):
        self.codes = [c for c in self.codes if computeFeedback(c, self.guess) == feedback]
        if len(self.codes) == 1:
            self.guess = self.codes[0]
        else:
            def key(g): return max(Counter(computeFeedback(c, g) for c in self.codes).values())
            self.guess = min(self.all_codes, key = key)

另外,你教授的密码也不完美!除了不遵循传统的Python风格(参见PEP8),它看起来也相当复杂和冗长。为什么不利用Python的^{}类编写一些简短而简单的内容:

from collections import Counter

def computeFeedback(code, guess):
    """
    Return the string `{white}w{black}b` where `black` is a count of the
    characters in `guess` that appear at the same position in `code`
    and `white` is a count of the characters in `guess` that appear at
    a different position in `code`.

    >>> computeFeedback('ABCD', 'ACAD')
    '1w2b'
    >>> computeFeedback('ABAB', 'AABB')
    '2w2b'
    >>> computeFeedback('ABCD', 'DCBA')
    '4w0b'
    """
    w = sum((Counter(code) & Counter(guess)).values())
    b = sum(c == g for c, g in zip(code, guess))
    return '{}w{}b'.format(w - b, b)

相关问题 更多 >