我正在尝试对给我的一组数字进行逆向工程(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),答案是否在哪里甚至接近,这是有意义的由于生成路径的差异)。注意我也在递归函数中尝试了这个(找到世代)并使用非反转方法(构建列表并检查答案;由于显而易见的原因,它显着变慢)
<小时/> 以下是一些测试用例及其答案:
f = "1" m = "2" Output: "1" f = "4" m = "7" Output: "4" f = "4" m = "2" Output: "impossible"
非常感谢任何帮助!附:我正在运行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)
答案 0 :(得分:2)
这不是一个Python问题,也不是一个编程问题。这是一个旨在让您思考的问题。因此,如果您只是从其他人那里得到答案,那么您将无法从练习中获得任何知识或后见之明。
只需在print(m, f)
循环中添加while
,并观看小输入的数字变化情况。例如,尝试(3, 100)
这样的事情:难道你没有看到任何可以加快速度的方法,而不是反复从较大数字中删除3?
答案 1 :(得分: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)
使用上述内容,answer(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
和answer(4, 7)
产生
7 4 0
4 3 1
3 1 2
4
答案 2 :(得分:0)
尝试一种递归形式:
(Python 2.7.6)
def back():
global f,m,i
if f<m:
s=m//f
i+=s
m-=s*f
elif m<f:
s=f//m
i+=s
f-=s*m
else:
return False
return True
while True:
f=int(raw_input('f = '))
m=int(raw_input('m = '))
i=0
while True:
if f==m==1:
print 'Output:',str(i)
break
else:
if not back():
print 'Output: impossible'
break
print
(Python 3.5.2)
def back():
global f,m,i
if f<m:
s=m//f
i+=s
m-=s*f
elif m<f:
s=f//m
i+=s
f-=s*m
else:
return False
return True
while True:
f=int(input('f = '))
m=int(input('m = '))
i=0
while True:
if f==m==1:
print('Output:',str(i))
break
else:
if not back():
print('Output: impossible')
break
print()
注意:我是一个Python 3.5编码器,所以我试图回溯我的代码,请告诉我它是否有问题。
输入格式也不同:现在f = "some_int"
代替f = some_int
,输出格式相似。