[英]Smallest number whose digits are decreasing
I found a problem to implement functions that takes a positive integer n as an input and returns the smallest positive integer larger than n whose digits are decreasing and similarly for a function that returns the smallest positive integer larger than n whose digits are increasing. 我发现了一个实现函数的问题,该函数接受一个正整数n作为输入并返回大于n的最小正整数,该正整数的位数在减小,而对于返回大于n的最小正整数的函数,其正整数又递增。 I think the increasing function works correctly.
我认为增加功能可以正常工作。 But what is the mistake in the function decrease?
但是函数减少有什么错误呢? For the input decreasing(100) it returns 11 rather than 110.
对于减少的输入(100),它返回11而不是110。
# the next integer whose digits are increasing.
def increasing(n):
asastring = str(n)
length = len(asastring)
if asastring == "9"*length:
return "1"*(length+1)
if length == 1:
return int(n)+1
if length >= 2:
firstcharacter = asastring[0]
secondcharacter = asastring[1]
if int(firstcharacter) > int(secondcharacter):
return int(str(firstcharacter)*length)
if firstcharacter == secondcharacter:
return firstcharacter+str(increasing(int(asastring[1:])))
if int(firstcharacter) < int(secondcharacter):
if secondcharacter == "9":
return str(int(firstcharacter)+1) * len(str(n))
return firstcharacter+str(increasing(int(asastring[1:])))
# the next integer whose digits are decreasing.
def decreasing(n):
asastring = str(n)
length = len(asastring)
# First the case where we need to add a digit.
if asastring == "9"*length:
return "1"+"0"*length
# Now we know that the next integer has the same number of digits as the original number.
if length == 1:
return int(n)+1
if length >= 2:
firstcharacter = asastring[0]
secondcharacter = asastring[1]
if int(firstcharacter) > int(secondcharacter):
endpart = str(((asastring[1:3])))
value = firstcharacter + str(decreasing(int(asastring[1:])))
return str(firstcharacter) + str(decreasing(int(asastring[1:])))
if int(firstcharacter) == int(secondcharacter):
return decreasing(firstcharacter+str(decreasing(int(asastring[1:]))))
if int(firstcharacter) < int(secondcharacter):
return str(int(firstcharacter)+1)+'0'*(length-1)
i=100
print(increasing(i))
print(decreasing(i))
You need to remove the int type casting done in the recursive calls as int('00') is converting your number to zero(basically removing all starting zeros) and shortening the length of your string. 您需要删除在递归调用中完成的int类型转换,因为int('00')将您的数字转换为零(基本上删除了所有开头的零)并缩短了字符串的长度。 Just remove that casting.. remaining code is working fine:
只需删除该转换即可。.其余代码工作正常:
def decreasing(n):
asastring = str(n)
length = len(asastring)
# First the case where we need to add a digit.
if asastring == "9"*length:
return "1"+"0"*length
# Now we know that the next integer has the same number of digits as the original number.
if length == 1:
return int(n)+1
if length >= 2:
firstcharacter = asastring[0]
secondcharacter = asastring[1]
if int(firstcharacter) > int(secondcharacter):
return str(firstcharacter) + str(decreasing(asastring[1:]))
if int(firstcharacter) == int(secondcharacter):
return decreasing(firstcharacter+str(decreasing(asastring[1:])))
if int(firstcharacter) < int(secondcharacter):
return str(int(firstcharacter)+1)+'0'*(length-1)
There are multiple intertwined issues that need to be addressed. 有多个相互交织的问题需要解决。 The naming of these two functions is a source of confusion.
这两个功能的命名令人困惑。 If we follow the logic, then the function
increasing()
should be called nondecreasing()
and similarly, the function decreasing()
should be called nonincreasing()
. 如果我们遵循逻辑,则函数
increasing()
应称为nondecreasing()
,类似地,函数decreasing()
应称为nonincreasing()
。 It's the difference between > (greater than) and >= (greater than or equal). >(大于)和> =(大于或等于)之间的区别。
The next confusion is what type do these functions accept and return ? 下一个困惑是这些函数接受并返回哪种类型? If we examine what the working
increasing()
function returns, we get: 如果我们检查工作中的
increasing()
函数返回的内容,则会得到:
str return "1"*(length+1)
int return int(n)+1
int return int(str(firstcharacter)*length)
str return firstcharacter+str(increasing(int(asastring[1:])))
str return str(int(firstcharacter)+1) * len(str(n))
str return firstcharacter+str(increasing(int(asastring[1:])))
If we similarly look at how the increasing()
deals with its own internal recursive calls to see what it thinks it accepts and returns, we get: 如果我们类似地查看
increasing()
如何处理其自身的内部递归调用,以查看其认为接受和返回的内容,则会得到:
int -> int return firstcharacter+str(increasing(int(asastring[1:])))
int -> int return firstcharacter+str(increasing(int(asastring[1:])))
So here's an attempted rework of increasing()
, aka nondecreasing()
, that tries to make it consistently accept an int
and return an int
: 因此,这里尝试了
increasing()
,又称为nondecreasing()
重做,试图使其始终接受一个int
并返回一个int
:
def nondecreasing(n): # aka increasing()
as_string = str(n)
length = len(as_string)
if as_string == "9" * length:
return int("1" * (length + 1))
if length == 1:
return int(n) + 1
first_digit, second_digit, second_digit_onward = as_string[0], as_string[1], as_string[1:]
if first_digit > second_digit:
return int(first_digit * length)
if first_digit == second_digit:
return int(first_digit + str(nondecreasing(int(second_digit_onward))))
if as_string == first_digit + "9" * (length - 1):
return int(str(int(first_digit) + 1) * length)
return int(first_digit + str(nondecreasing(int(second_digit_onward))))
The decreasing()
, aka nonincreasing()
, function is more problematic. decreasing()
aka nonincreasing()
函数的问题更大。 It relies on its ability to accept an int
, or a str
upon internal calls, to solve the problem. 它依靠接受
int
或内部调用的str
来解决问题的能力。
Discussing these sort of issues, and not making other programmers rediscover them, are what code comments are all about. 讨论这些问题,而不是让其他程序员重新发现它们,是代码注释的全部内容。
I don't believe the above issue precludes nonincreasing()
from consistently returning an int
: 我不认为上述问题会阻止
nonincreasing()
始终返回 int
:
def nonincreasing(n): # aka decreasing()
as_string = str(n)
length = len(as_string)
if as_string == "9" * length:
return int("1" + "0" * length)
if length == 1:
return int(n) + 1
first_digit, second_digit, second_digit_onward = as_string[0], as_string[1], as_string[1:]
if first_digit > second_digit:
return int(first_digit + str(nonincreasing(second_digit_onward)))
if first_digit == second_digit:
remaining_digits = str(nonincreasing(second_digit_onward))
second_digit = remaining_digits[0]
n = first_digit + remaining_digits
if first_digit < second_digit:
return int(str(int(first_digit) + 1) + '0' * (length - 1))
return int(n)
The key to fixing this function was to remove the return
statement from the penultimate if
clause and instead fix up the data and let it fall through to the next if
clause to see if the results need repair or not. 修复此功能的关键是从倒数第二个
if
子句中删除return
语句,而是修复数据,然后让它进入下一个if
子句,以查看结果是否需要修复。
I believe @devender22's insight about int()
casting is a crucial one but I don't believe the accompanying solution is valid as it generates large blocks of incorrect results (eg 990 through 998 all go to 1000 when they should simply be bumped up by 1). 我相信@ devender22对
int()
强制转换的见解是至关重要的,但是我不认为随附的解决方案是有效的,因为它会生成大量错误结果(例如,从990到998到1000时它们都应该被简单地撞掉) 1)。
In order to check my nonincreasing()
function with all of its cases, I wrote a less efficient, non-recursive solution, without separate cases, using completely different Python operators: 为了检查我的
nonincreasing()
函数的所有情况,我使用完全不同的Python运算符编写了一个效率较低,非递归的解决方案,没有单独的情况:
def nonincreasing(n):
def is_increasing(n):
string = str(n)
return any(map(lambda x, y: y > x, string, string[1:]))
while is_increasing(n + 1):
n += 1
return n + 1
And then made sure the two implementations agreed on their output. 然后确保两个实现在其输出上达成一致。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.