The question is mostly about base conversion. Here's the question.
- Start with a random minion ID n, which is a nonnegative integer of length k in base b
- Define x and y as integers of length k. x has the digits of n in descending order, and y has the digits of n in ascending order
- Define z = x - y. Add leading zeros to z to maintain length k if necessary
- Assign n = z to get the next minion ID, and go back to step 2
For example, given minion ID n = 1211, k = 4, b = 10, then x = 2111, y = 1112 and z = 2111 - 1112 = 0999. Then the next minion ID will be n = 0999 and the algorithm iterates again: x = 9990, y = 0999 and z = 9990 - 0999 = 8991, and so on.
Depending on the values of n, k (derived from n), and b, at some point the algorithm reaches a cycle, such as by reaching a constant value. For example, starting with n = 210022, k = 6, b = 3, the algorithm will reach the cycle of values [210111, 122221, 102212] and it will stay in this cycle no matter how many times it continues iterating. Starting with n = 1211, the routine will reach the integer 6174, and since 7641 - 1467 is 6174, it will stay as that value no matter how many times it iterates.
Given a minion ID as a string n representing a nonnegative integer of length k in base b, where 2 <= k <= 9 and 2 <= b <= 10, write a function solution(n, b) which returns the length of the ending cycle of the algorithm above starting with n. For instance, in the example above, solution(210022, 3) would return 3, since iterating on 102212 would return to 210111 when done in base 3. If the algorithm reaches a constant, such as 0, then the length is 1.
Here's my code
def solution(n, b): #n(num): str, b(base): int
#Your code here
num = n
k = len(n)
resList = []
resIdx = 0
loopFlag = True
while loopFlag:
numX = "".join(x for x in sorted(num, reverse=True))
numY = "".join(y for y in sorted(num))
xBaseTen, yBaseTen = getBaseTen(numX, b), getBaseTen(numY, b)
xMinusY = xBaseTen - yBaseTen
num = getBaseB(xMinusY, b, k)
resListLen = len(resList)
for i in range(resListLen - 1, -1, -1):
if resList[i] == num:
loopFlag = False
resIdx = resListLen - i
break
if loopFlag:
resList.append(num)
if num == 0:
resIdx = 1
break
return resIdx
def getBaseTen(n, b): #n(number): str, b(base): int -> int
nBaseTenRes = 0
n = str(int(n)) # Shave prepending zeroes
length = len(n) - 1
for i in range(length 1):
nBaseTenRes = int(n[i]) * pow(b, length - i)
return nBaseTenRes
def getBaseB(n, b, k): #(number): int, b(base): int, k:(len): int -> str
res = ""
r = 0 # Remainder
nCopy = n
while nCopy > 0:
r = nCopy % b
nCopy = floor(nCopy / b)
res = str(r)
res = res[::-1]
resPrependZeroesLen = k - len(res)
if resPrependZeroesLen > 0:
for i in range(resPrependZeroesLen):
res = "0" res
return res
The two test that are available to me and are not passing, are ('1211', 10) and ('210022', 3). But I get the right answers for them (1, 3).
Why am I failing? Is the algo wrong? Hitting the time limit?
CodePudding user response:
The problem arose between the differences of the execution environments.
When I executed on my machine on Python 3.7 this
r = nCopy % n
gave me an answer as an int.
While Foobar runs on 2.7, and the answer above is given as a float