繁体   English   中英

在python上测试数字中数字之和的相等性?

[英]Testing the equality of the sum of a digits within a number on python?

例如def f(n):

我想检查n中的数字之和是否等于100,无论是1s,2s,3,s4s,5s等等,这取决于n的长度。

f(5050)
>>> True

这测试5 + 0 + 5 + 0 == 100以及50 + 50 ==100是否为真,如果有,则返回True

它是以1s,2s 3s 4s等进行测试,取决于数字的长度。 例如,长度为5的数字只能在1秒内测试。

f(12345)
>>> False

这测试1 + 2 + 3 + 4 + 5 == 100只有那个。

如果n的长度是15,它将测试1s,3s和5s中的数字。

最后再举一个例子:

f(25252525)
>>> True

这将测试2+5+2+5+2+5+2+5 == 10025+25+25+25==100以及2525+2525==100所以n ,其长度为8将在1s,2s和4s进行测试。 它不能用3和5进行测试,因为总和的数字中所有数字的长度必须相同。

我希望我能够解释我所追求的是什么。 通常我会发布我尝试过但我不知道如何以这种方式迭代数字的数字

下面的方法使用generator来分割整数,而不是integer <-> string转换。

这可能是目前列出的最有效的方法。

import math

# Define a generator that will split the integer v into chunks of length cl
# Note: This will return the chunks in "reversed" order.
#   split(1234, 2) => [34, 12]
def split(v, cl):
    while v:
        (v,c) = divmod(v, 10**cl)
        yield c


def f(v):
    # Determine the number of digits in v
    n = int(math.log10(v)) + 1
    m = int(math.sqrt(v))
    # Check all chunk lengths in [1, sqrt(v)]
    for cl in range(m):
        # Skip the chunk lengths that would result in unequal chunk sizes 
        if n % (cl+1): continue
        # Create a generator, to split the value v into chunks of length cl
        chunks = split(v, cl+1)
        # If the sum of the chunks is 100, print a message and return True
        if sum(chunks) == 100:
            print("sum = 100 with chunklength: %d" % cl)
            return True
    # If we get here, none of the chunk lengths result in a sum of 100, return False
    return False

print(f(5050))      # True (cl=2)
print("---")
print(f(12345))     # False
print("---")
print(f(25252525))  # True (cl=2)
print("---")

输出:

sum = 100 with chunklength: 2
True
---
False
---
sum = 100 with chunklength: 2
True
---

没有评论和调试print

import math

def split(v, cl):
    while v:
        (v,c) = divmod(v, 10**cl)
        yield c

def f(v):
    n = int(math.log10(v)) + 1
    m = int(math.sqrt(v))
    for cl in range(m):
        if n % (cl+1): continue
        if sum(split(v, cl+1)) == 100: return True
    return False

print(f(5050))      # True
print(f(12345))     # False
print(f(25252525))  # True

假设数字总是正整数,你可以将它们divmod()除以10直到你得到零:

def int_iter(number):
    while number > 0:
        number, last_digit = divmod(number, 10)
        yield last_digit

请注意,它以相反的顺序为您提供数字。 但是,如果您只是将它们组合在一起并不重要。

你可以传递它或在for循环中使用它,就像任何其他iterable一样:

digit_sum = sum(int_iter(number))

如果你真的需要一个序列,只需将它传递给list()

digit_list = list(int_iter(number))

如果您需要以最重要的第一顺序将它们传递给reversed()

digits_msf = reversed(list(int_iter(number)))

编辑:

哎呀,我错过了〜大约一半的问题。 事情变得更加复杂。 你需要一个功能来获得一个数字的所有因素 - 我确定有很多,所以我会把它留给你作为一个练习。 让我们假设有一个函数factors(number)返回所有数字因子的迭代(包括非主数和1,但不是number本身)。 我们也将使用int_iter()从我原来的答复,一个int_from_digits()它利用数字列表并返回一个整数(有点像的倒数int_iter()以及一种叫grouper()itertools食谱

from itertools import zip_longest

def int_from_digits(digits):
    "Generate an integer from an iterable of single decimal digits"
    # int_from_digits([4, 0, 2, 8, 9]) --> 40289
    # int_from_digits([]) --> 0
    number = 0
    for digit in digits:
        number *= 10
        number += digit
    return number

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

def digit_subsequences(number):
    digits = list(reversed(list(int_iter(number))))
    for factor in factors(number):
        for digit_grouping in grouper(digits, factor):
            yield int_from_digits(digit_grouping)

最后,使用所有这些工具(或者更确切地说,一个工具及其依赖项),我们可以通过简单的理解和对any()的调用来执行检查:

any(digit_subsequence == 100 for digit_subsequence in digit_subsequences(number))

一种可能的方法,分为每个逻辑步骤的函数:

  1. 得到n因子

def get_factors(n):    
    return set(reduce(list.__add__, 
                ([i, n//i] for i in range(1, int(n**0.5) + 1) if n % i == 0)))
  1. 对于每个l因子nstr(n)拆分为长度为l

def get_chunks(str_n, chunk_size):
    total_size = len(str_n)
    return [int(str_n[i:i+chunk_size]) for i in range(0, total_size, chunk_size)]
  1. 检查步骤2中的块总数是否等于100。

def f(n):
    factors = get_factors(n)
    for l in factors:
        if sum(get_chunks(str(n), l)) == 100:
            return True
    return False

认为这样做了。 但不确定:

def f(n):
    s = str(n)
    l = len(s)
    for n in (n for n in range(1, l + 1) if l % n == 0):
        ints = [int(''.join(x)) for x in zip(*[iter(s)]*n)]
        if sum(ints) == 100:
            return True
    return False

zip东西来自这里 这有点奇怪,但它允许我将字符串分成n长度段,然后将它连接在一起,这样我就可以应用int映射然后减少sum

生成器只获得l所有正除数,从1l ,包括两者。 使用math.sqrtdivmod可能有更快的方法为大n做这divmod

def factors(num):
    yield 1
    for i in range(2, num - 1):
        if num % i == 0:
            yield i


def pieces(string, sz):
    for i in range(0, len(string), sz):
        yield string[i:i+sz]


def check_sum(string):
    for f in factors(len(string)):
        pcs = pieces(string, f)
        if sum([int(x) for x in pcs]) == 100:
            print 'True'
            return
    print 'False'

>>> check_sum('5050')
True
>>> check_sum('25252525')
True
>>> check_sum('12345')
False

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM