python-数数的倒数

我试图对提供给我的一组数字进行逆向工程(f,m),我需要使用下面的算法为每一代找出从1,1开始需要多少代:

x = 1
y = 1
new_generation = y+x
x OR y = new_generation

IE,我不知道X或Y是否更改,其他变量保持不变…对于4和7的最终值,可能的输出列表如下所示:

f = 4
m = 7
[1, 1]
[2, 1, 1, 2]
[3, 1, 2, 3, 3, 2, 1, 3]
[4, 1, 3, 4, 5, 3, 2, 5, 5, 2, 3, 5, 4, 3, 1, 4]
[5, 1, 4, 5, **7, 4**, 3, 7, 7, 5, 2, 7, 7, 2, 5, 7, 7, 3, **4, 7**, 5, 4, 1, 5]

每两组数字(2,1)和(1,2)都是可能的输出.注意**表示答案(在这种情况下,顺序不重要,只要m和f在列表中都具有它们的值).

显然这里有指数级增长,所以我无法(或效率较低)列出并找到答案.相反,我正在使用以下代码来逆转此过程…

def answer(m,f):
    #the variables will be sent to me as a string, so here I convert them...
    m = (int(m))
    f = (int(f))
    global counter
    #While I have not reduced my given numbers to my starting numbers....
    while m != 1 or f != 1:
        counter +=1
        #If M is greater, I know the last generation added F to M, so remove it
        if m > f:
            m = m-f
        #If F is greater, I know the last generation added M to M, so remove it
        elif f > m:
            f = f-m
        else:
            #They can never be the same (one must always be bigger, so if they are the same and NOT 1, it can't be done in any generation)
            return "impossible"
    return str(counter)

print(answer("23333","30000000000"))

这将返回正确的答案(例如,4,7返回“ 4”,这是正确的),但是当我传递更大的数字时,它会花费很长时间(我必须能够处理10 ^ 50,疯狂的数量,我知道!).

我的想法是我应该能够对数字应用一些数学方程式以将其减少,并使它们成倍增加,但是我很难找到一种方法来做到这一点,同时又保持了答案的完整性(例如,如果我用较大的数字除以较小的数字,在较小的数字(7,300000)上,我得到一个非常接近的(但错误的)答案,但是在较小的数字(例如,23333,300000)上,答案甚至没有接近的地方,这是有道理的生成路径的差异).请注意,我还在递归函数(查找代)中使用了非反向方法(构建列表并检查答案;由于明显的原因,速度明显较慢)也进行了尝试

以下是一些测试用例及其答案:

06003

任何帮助深表感谢!附言我正在运行Python 2.7.6

[编辑]

下面的代码按要求工作.

from fractions import gcd

def answer(m,f):
    #Convert strings to ints...
    m = (int(m))
    f = (int(f))

    #If they share a common denominator (GCD) return impossible
    if gcd(m,f) != 1:
        return "impossible"
    counter = 0
    #While there is still a remainder...
    while m != 0 and f != 0:
        if m > f:
            counter += m // f
            #M now equals the remainder.
            m %= f
        elif f > m:
            counter += f // m
            f %= m
    return str(counter - 1)

解决方法:

您采用自上而下的方法在正确的轨道上.如果使用整数除法而不是重复减法,则可以极大地提高它的速度.

def answer(m, f):
    m = int(m)
    f = int(f)
    counter = 0
    while m != 0 and f != 0:
        if f > m:
            m, f = f, m
        print(m, f, counter, sep="\t")
        if f != 1 and m % f == 0:
            return "impossible"
        counter += m // f
        m %= f
    return str(counter - 1)

使用上面的方法,答案(23333,30000000000)产生

30000000000 23333   0
23333   15244   1285732
15244   8089    1285733
8089    7155    1285734
7155    934 1285735
934 617 1285742
617 317 1285743
317 300 1285744
300 17  1285745
17  11  1285762
11  6   1285763
6   5   1285764
5   1   1285765
1285769

和答案(4,7)产生

7   4   0
4   3   1
3   1   2
4
上一篇:python-计算字典键的总和


下一篇:python-计算熊猫地理密度的有效方法?