[英]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 == 100
和25+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))
一种可能的方法,分为每个逻辑步骤的函数:
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)))
l
因子n
, 将str(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)]
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
所有正除数,从1
到l
,包括两者。 使用math.sqrt
和divmod
可能有更快的方法为大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.