您能帮我减少代码执行时间吗?

问题描述

我正在对Codewars进行练习,练习(用他们的语言写的kata)由几次操作后返回字母R G或B组成。我们得到了这样的字符串:RGBGBRRB。我们必须制作一种倒金字塔。金字塔的每一行都是这样构建的:here

因此,如果颜色为RG:结果为B,如果颜色为BR:结果为G;依此类推...如果两种颜色相同,则会导致出现问题的颜色。如果您听不懂,我会放在练习-here- ...的链接

从我的角度来看,这是我的代码,它可以工作,但是Codewars的服务器不允许代码执行时间超过12秒,我的代码就是其中的一部分...您能帮我加快编码速度吗?代码

#define the function we have to code

def triangle(row):
    while len(row) > 1: #loop will stop when 'row' will be one char length 
        inter = '' #intermediate string which will be row at the end of the while loop
        inter2 = [None,None] #it is a list where the code put the colour letters to be ''calculated''
        
        for i,color in enumerate(row): #'for' loop which make the new 'line' of inverted pyramid
            if inter2[0] is None: #if the first item of intermediate list isn't a colour yet
                inter2[0] = color
            else: #if the first item of intermediate list is already a colour
                inter2[1] = color #put second colour in second item of the intermediate list
                #'if' condition to add letter to the new ''row'' of the ''inverted pyramid''
                if inter2[0] == inter2[1]: inter += inter2[0]
                if 'R' in inter2 and 'G' in inter2: inter +='B'
                if 'R' in inter2 and 'B' in inter2: inter += 'G'
                if 'G' in inter2 and 'B' in inter2: inter += 'R'
                inter2 = [color,None] #make the future intermediate list (so the first if 
condition will not be used anymore)
            row = inter                 
    return row[0] #return the final colour letter

解决方法

这是一项具有挑战性的练习。要超过12秒的时间限制,您可能需要使用一些组合方法(有关示例非常详细,请参见here)和类似Luca's theorem的方法。

接受的答案here使用C进行了更详细的介绍,但是原理是相同的。在Python中,潜在的解决方案可能如下所示:

def get_mapping():
    return {'R': 0,0: 'R','G': 1,1: 'G','B': 2,2: 'B',}


def signat(n):
    res = []
    i = 0
    while n > 0:
        n,m = divmod(n,3)
        if m > 0:
            res.append((i,m))
        i += 1
    return res[::-1]


def triangle_recursive(row,sig,pos,acc,accm):
    if pos == len(sig):
        return get_mapping()[row[acc]] * accm
    
    res = 0
    for i in range(sig[pos][1] + 1):
        acc_part = acc + (i * (3 ** sig[pos][0]))
        accm_part = accm
        
        if sig[pos][1] == 2 and i == 1:
            accm_part *= 2
            
        res += triangle_recursive(row,pos + 1,acc_part,accm_part)
    return res % 3


def triangle(row):
    sig = signat(len(row)-1)
    color_val = triangle_recursive(row,1)
    
    if len(row)%2 == 0:
        color_val = (-1 * color_val) % 3
        
    return get_mapping()[color_val]