简体   繁体   English

Python:找到一个数字的代码,其中前N个数字可被N整除(从0到9)

[英]Python: Code to find a number where first N digits are divisible by N (from 0-9)

I've been trying to write a recursive solution to a program to find a number where first N digits are divisible by N. 我一直在尝试为程序编写递归解决方案,以找到前N个数字可被N整除的数字。

As an example: 3816547290, 3 is divisible by 1, 38 is divisible by 2, 381 is divisible by 3 and so on... 例如:3816547290、3被1整除,38被2整除,381被3整除,依此类推...

My recursive solution works fine while going "into" the recursion, but has issues when the stack unwinds (ie I don't specifically know how to backtrack or take steps on the way out 我的递归解决方案在“进入”递归过程中可以很好地工作,但是在堆栈展开时会出现问题(即,我不知道如何回溯或在退出时采取步骤)

ARR = [0]*10
ARR[0] = 1 #dummy entry
def numSeq(pos, num):

    if all(ARR):
        print num
        return True

    if (pos>0) and (num%pos) != 0:
        return False

    for i in xrange(1,10):
        if ARR[i] == 1:
            continue
        new_num = num*10 + i
        if new_num%(pos+1) == 0:
            ARR[i] = 1
        numSeq(pos+1,new_num)

The problem with this code seems to be that it follows the number generation correctly while going into the recursion...so it correctly generates the number 123654 which is divisible by 6 and follows first N digits being divisible by N, but after it fails to find any further digits from 7-8 or 9 that divide 7, i don't get the next set of steps to "reset" the global ARR and begin from index 2, ie try 24xxxx,and eventually get to 3816547290 此代码的问题似乎是在递归时它正确地遵循了数字生成...因此,它正确地生成了可以被6整除的数字123654,并且跟随着前N个数字被N整除,但是之后却无法从7-8或9中找到除以7的任何其他数字,我没有获得下一组步骤来“重置”全局ARR,而是从索引2开始,即尝试使用24xxxx,最终到达3816547290

Thanks in Advance for your help! 在此先感谢您的帮助!

EDIT : One condition I'd forgotten to mention is that each digit must be used exactly once (ie repetition of digits is disallowed) 编辑 :我忘了提到的一个条件是每个数字必须精确地使用一次(即不允许重复数字)

2nd EDIT : 第二次编辑

I was able to finally apply proper backtracking to solve the problem...this code works as is. 终于能够应用适当的回溯来解决问题...此代码按原样工作。

ARR = [0]*10
def numDivisibile(num,pos):

    if all(ARR):
        print num
        return True

    for i in xrange(0,10):
        if ARR[i] == 1:
            continue
        new_num = num*10+i
        #check for valid case
        if new_num%(pos+1) == 0:
            ARR[i] = 1
            if numDivisibile(new_num, pos+1):
                return True
            #backtrack
            ARR[i] = 0

    return False

print numDivisibile(0, 0)

To generate all 10 digits integers where the first n digits are divisible by n for each n from 1 to 10 inclusive: 要生成所有10位整数,其中对于从11010每个n ,前n数字可被n整除:

#!/usr/bin/env python3

def generate_ints_nth_digit_divisible_by_n(n=1, number=0):
    number *= 10
    if n == 10:
        yield number  # divisible by 10
    else:
        for digit in range(not number, 10):
            candidate = number + digit
            if candidate % n == 0:  # divisible by n
                yield from generate_ints_nth_digit_divisible_by_n(n + 1, candidate)

print("\n".join(map(str, generate_ints_nth_digit_divisible_by_n())))

Output 输出量

1020005640
1020061620
1020068010
...
9876062430
9876069630
9876545640

To get numbers where each digit occurs only once ie, to find the permutations of the digits that satisfy the divisibility condition: 要获取每个数字仅出现一次的数字,即找到满足除数条件的数字的排列:

def divisibility_predicate(number):
    digits = str(number)
    for n in range(1, len(digits) + 1):
        if int(digits[:n]) % n != 0:
            return n - 1
    return n

def generate_digits_permutation(n=1, number=0, digits=frozenset(range(1, 10))):
    # precondition: number has n-1 digits
    assert len(set(str(number))) == (n - 1) or (number == 0 and n == 1)
    # and the divisibility condition holds for n-1
    assert divisibility_predicate(number) == (n - 1) or (number == 0 and n == 1)

    number *= 10
    if n == 10:
        assert not digits and divisibility_predicate(number) == 10
        yield number  # divisible by 10
    else:
        for digit in digits:
            candidate = number + digit
            if candidate % n == 0:  # divisible by n
                yield from generate_digits_permutation(n + 1, candidate, digits - {digit})


from string import digits
print([n for n in generate_ints_nth_digit_divisible_by_n()
       if set(str(n)) == set(digits)])
print(list(generate_digits_permutation()))

Output 输出量

[3816547290]
[3816547290]

In your function, you never do return numSeq(...) , this seems like causing the issue. 在您的函数中,您永远不会return numSeq(...) ,这似乎是导致问题的原因。

If you want to have a iterative solution, you can check the following: 如果要使用迭代解决方案,可以检查以下内容:

def getN(number):
    strNum = str(number)
    for i in range(1, len(strNum)+1):
        if int(strNum[:i]) % i != 0:
            return i-1
    return i

print getN(3816)
print getN(3817)
print getN(38165)

Output: 输出:

4
3
5

We can modify your recursive function a little to try different possibilities. 我们可以稍微修改您的递归函数,以尝试不同的可能性。 Rather than have a global record ( ARR ) of used positions, each thread of the recursion will have its own hash of used digits: 递归的每个线程将具有自己的使用数字hash ,而不是使用位置的全局记录( ARR ):

def numSeq(pos, num, hash):
  if pos != 1 and num % (pos - 1) != 0:   # number does not pass the test
    return

  elif pos == 11:                         # number passed all the tests
    print num

  elif pos == 5:
    numSeq(pos + 1,10 * num + 5,hash)     # digit is 5 at position 5

  elif pos == 10:
    numSeq(pos + 1,10 * num,hash)         # digit is 0 at position 10

  else:  
    k = 2 if pos % 2 == 0 else 1          # digit is even at even positions
    for i in xrange(k,10,2):
      if hash & (1 << i):                 # digit has already been used, skip it
        continue
      numSeq(pos + 1,10 * num + i,hash | (1 << i))

numSeq(1,0,0) # 3816547290

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 前 n 位可被 n 整除的 10 位数字 - 10 digit number whose first n digits are divisible by n 查找一个10位整数,其中前n位数字可从1到n整除 - Find a 10 digit integer in which the first n digits are divisible from 1 to n 如何找到不能被 3 整除的最小 n 位数? - How can I find the smallest number of n digits that is not divisible by 3? 从列中删除前n位数字 - Delete first n digits from a column 从2到N的给定数字应该将每个数字整除为[(2,4),(2,6),(2,8),(3,9),(3,12),(3,15) ...]在Python 2/3中 - A given number from 2 to N should have each number divisible outputted as [(2,4), (2,6),( 2,8),( 3,9),( 3,12), (3,15) …] in Python 2/3 给定数字n找到最接近它的素数,最大偶数位 - Given a number n find the prime number closest to it with maximum even digits 生成具有被n整除的随机数列表 - Generate list of random number with the sum divisible by n Plot txt 文件中前 N 条数据 Python - Plot first N number of data from txt file Python python3 计算 PI 的 N 位数 python 切长数 - python3 calculate N digits of PI python cut the long number 如何从python端为散景图指定第n个股票代码,其中n是股票代码的数量 - How to specify n-th ticker for bokeh plot from python side, where n is the number of tickers
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM