创建循环自己的链

时间:2016-05-30 22:16:27

标签: python recursion while-loop

我希望有一个数字可以分成2个其他数字并检查结束条件,中断每个数字直到满足条件。

我想出了以下示例来试图找出它。取一个数字,并将其分成另外两个数字:一个是原始数字乘以2而另一个数字是原始数字除以3而没有余数(//)。这将继续,直到数字大于100,等于6或正方形。

我想记录最后返回并打印出来的每一条链。我只能通过检查当前链中的第二个数字来做到这一点,并且不够聪明,无法弄清楚如何检查这两个数字。我希望每次将数字分成2个新数字时创建一个新链。

目前,这就是我所拥有的:

import numpy as np

def check_conditions(number):
    if number > 100:
        return False
    if number == 6:
        return False
    if np.sqrt(number) % 1 == 0:
        return False
    return True

def find_decay(number):
    '''
    Rule: Number is broken into two chains. First chain is 
    mulitplied by 2. Seconds chain is // 3. Same thing happens
    to both chains unless end condition is met:
    1. number is greater than 100
    2. number is equal to 6
    3. number is a perfect square
    '''
    master_chain = []
    while check_conditions(number):
        new_chain1 = [number * 2]
        master_chain.append(new_chain1)
        new_chain2 = [number // 3]
        master_chain.append(new_chain2)
        number = new_chain2[-1]
    return master_chain

if __name__ == '__main__':
    print find_decay(int(raw_input('Number: ')))

有没有人想办法检查2个单独数字的while循环中的条件,比如?

2 个答案:

答案 0 :(得分:1)

此类问题通常适用于trees和/或recursion。但是,与您满足条件的速度相比,您产生新作品的速度相当高。 (即,虽然每个值的一个产品不会超过100,但是在任何一个叉子上找到一个完美的正方形或正好6个的机会很少)

因此,您希望为您的实施设置最大递归深度,否则您将遇到解释器的限制(sys.getrecursionlimit())并且难以理解。

我提供了一个简单的示例,说明如何在下面执行此操作,递归构建树。

但这并不是特别有效,如果你对很长的连锁店感兴趣,那么那么你可能需要考虑用另一种方式解决。

import sys
import numpy as np

class Node(object):
    def __init__(self,number,parent):
        self._parent = parent
        self._number = number
        self._satisfied = number > 100 or number == 6 or np.sqrt(number) % 1 == 0
        self._left = None
        self._right = None
        self._depth = parent.depth + 1 if parent != None else 1

    @property
    def parent(self):
        return self._parent

    @property
    def number(self):
        return self._number

    @property
    def satisfied(self):
        return self._satisfied

    @property
    def depth(self):
        return self._depth

    @property
    def left(self):
        return self._left

    @left.setter
    def left(self,value):
        self._left = value

    @property
    def right(self):
        return self._right

    @right.setter
    def right(self,value):
        self._right = value

def print_all_chains(node,chain=[]):
    if node.left is None:
        chain.append(node.number)
        print '{0}: {1}'.format(node.satisfied, chain)
    else:
        print_all_chains(node.left, chain[:] + [node.number])
        print_all_chains(node.right, chain[:] + [node.number])

def build_tree(node, maxDepth):
    if not node.satisfied and node.depth<maxDepth:
        node.left = Node(node.number*2, node)
        build_tree(node.left,maxDepth)
        node.right = Node(node.number//3, node)
        build_tree(node.right,maxDepth)

def find_decay(number):
    root = Node(number,None)
    build_tree(root,maxDepth=10)
    print_all_chains(root)

if __name__ == '__main__':
    find_decay(int(raw_input('Number: ')))

答案 1 :(得分:1)

使用简单的Node类,可以让您了解树结构。这会以级别顺序遍历树(这可以保证找到最短的链):

from collections import deque
import numpy as np

def check_conditions(number):
    return number > 100 or number == 6 or np.sqrt(number) % 1 == 0

class Node():
    def __init__(self, value, parent=None):
        self.value, self.parent = value, parent

    def chain(self):
        node = self
        while node:
            yield node.value
            node = node.parent

def find_decay(number):
    agenda = deque([Node(number)])

    while agenda:
        node = agenda.popleft()  # use pop() for depth-first
        num = node.value
        if check_conditions(num):
            return list(node.chain())
        agenda.append(Node(num//3, parent=node))
        agenda.append(Node(num*2, parent=node))


if __name__ == '__main__':
    for x in find_decay(int(raw_input('Number: '))):
        print x,

37: 37 12 4