Python中的3n + 1编程挑战

时间:2014-12-07 20:17:54

标签: python arrays algorithm

3n + 1挑战非常受欢迎,可以找到here

我在下面的python中创建了一个解决方案,也在github

上创建了一个解决方案
def solution(i, j):
    count = toRtn = 1
    for n in xrange(i, j+1):
        count = 1
        while n != 1:
            if n % 2 == 0:
                n = n/2
            else:
                n = (3 * n) + 1
            count += 1
        toRtn = max(toRtn, count)
    return toRtn

print solution(100, 200)
print solution(201, 210)

我有几个问题:

  1. 可以而且应该将其重写为递归吗?那会提高效率吗?

  2. 如何计算此功能的复杂程度?

  3. 是否有针对这些挑战的Python在线评判?

3 个答案:

答案 0 :(得分:3)

您可以定义递归方法来计算3n+1

def threen(n):
    if n ==1:
        return 1
    if n%2 == 0:
        n = n/2
    else:
        n = 3*n+1
    return threen(n)+1

为避免计算两次相同的数字,您可以缓存值

cache = {}
def threen(n):
    if n in cache:
        return cache[n]
    if n ==1:
        return 1
    orig = n
    if n%2 == 0:
        n = n/2
    else:
        n = 3*n+1
    count = threen(n)+1
    cache[orig] = count
    return count

现在你可以在循环中使用它

def max_threen(i, j):
    max3n = 0
    for n in xrange(i, j+1):
        max3n= max(threen(n), max3n)
    print i, j, max3n

max_threen(100,201)

现在你可以将它与你的版本:)进行比较,它可能消耗大量内存,但对于某些范围可能更快,显然如果你缓存值,非递归方法会更快,但递归很有趣,更易读,但在任何情况下,迭代版本将更快与缓存(未测试)

cache = {}
def solution(i, j):
    count = toRtn = 1
    for n in xrange(i, j+1):
        count = 1
        orig = n
        if n in cache:
            count = cache[n]
        else:
            while n != 1:
                if n % 2 == 0:
                    n = n/2
                else:
                    n = (3 * n) + 1
                count += 1

            cache[orig] = count
        toRtn = max(toRtn, count)
    return toRtn

答案 1 :(得分:0)

  1. 不,不;递归很少(如果有的话)用于提高性能。
  2. 你不能,因为它甚至没有确定它将返回n的所有值。 (没有人发现没有返回的那个,但也没有人证明没有一个。)
  3. 据我所知。

答案 2 :(得分:0)

1)严格来说,递归本身不能优化自身。递归不是关于优化,而是关于需要时的清晰度。但是,您可以使用带有memoization的递归来提高性能:http://en.wikipedia.org/wiki/Memoization

2)每个语句的复杂性的函数和的复杂性。因此,要计算整个复杂性,您应该为每一行构建一个包含两列的表:[调用次数],[复杂性]并对每行进行求和。我们来看看以下代码:

 def print_N_times(N):
    print "------"        #Line1
    for i in range(0,N):  #Line2
        print "easy"      #Line3
    print "------"        #Line4 
-------------------------------------------------------
| Line number | Number of times executed | Complexity | 
|  Line 1     |        1                 |     1      |
|  Line 2     |        N+1               |     1      |
|  Line 3     |        N                 |     1      |
|  Line 4     |        1                 |     1      |
-------------------------------------------------------

(这里1代替了常数的复杂性)

因此,通过将每列相乘并将它们相加:

1 * 1 +(N + 1)* 1 + N * 1 + 1 * 1 = 2 * N + 3 = O(N),因此该函数具有线性复杂度。

3)有很多评委,但是spoj.pl接受各种编程语言:

http://www.spoj.com/problems/PROBTRES/

编辑:在评论中正确地指出,对于3n + 1问题,您不知道[执行次数]列的每个值,或者该函数是否将完成。有关详细信息,请参阅:

https://en.wikipedia.org/wiki/Collatz_conjecture