How to iterate faster through a loop with a range that goes to at least 2 digits (10) until 1000 digits (10^100) using Python 3 +? - python-3.x

I receive a non-empty string S of at most 1000 characters and an integer N (1 ≤ N ≤ 1000). Each character of S is either a decimal digit or the character “ ? ”; the leftmost character is not “ 0 ” and at least one character is “ ? ”.
I have to show an integer D without leading zeros indicating the smallest multiple of N that has | S | digits and such that the digits in S are coincident with the corresponding digits in D. If there exists no such an integer D, i write an “ * ”.
So, i managed to write a code that kind do that, but it takes forever for large numbers, i want to find a way to make it faster or if i can improve my code.
Here its an example of input and output:
input: 1??????????????????????????????? 2 / output: 10000000000000000000000000000000
input: ???????????????????????????????1 2 / output: *
input: ?294?? 17 / output: 129404
my code:
D, N = input().split()
lenOfD = len(D)
lowerD = ''
higherD = ''
infos = {}
for index, letter in enumerate(D):
if letter.isdigit():
lowerD += letter
higherD += letter
infos[index] = letter
else:
if index == 0:
lowerD += '1'
higherD += '9'
else:
lowerD += '0'
higherD += '9'
rest = int(lowerD) % int(N)
quotient = int(int(lowerD) / int(N))
if rest != 0:
while True:
result = quotient * int(N)
resultString = str(result)
matchInfo = 0
if len(resultString) == lenOfD:
newRest = result % int(N)
if newRest == 0:
for position, value in infos.items():
if resultString[position] == value:
matchInfo += 1
quotient += 1
if result > int(higherD):
print('*')
break
if len(infos) == matchInfo:
print(result)
break
else:
print(lowerD)
and still have a minor problem, that when a divide a large number for a small one, the precision sucks because it approximate to scientific notation, and that is why i converted the variable quotient to int, but its not converting to the right number.

Related

The algorithm receives a natural number N > 1 as input and builds a new number R from it as follows:

Python.
It's a problem:
The algorithm receives a natural number N > 1 as input and builds a new number R from it as follows:
We translate the number N into binary notation.
Invert all bits of the number except the first one.
Convert to decimal notation.
Add the result with the original number N.
The resulting number is the desired number R. Indicate the smallest odd number N for which the result of this algorithm is greater than 310. In your answer, write this number in decimal notation.
This is my solution:
for n in range(2, 10000):
s = bin(n)[2:]
for i in range(len(s)):
if s[i+1] == 0:
s[i] = '1'
else:
s[i] = 'k'
for i in range(len(s)):
if s[i] == 'k':
s[i] = '0'
h = int(s, 2)
r = h + n
if n % 2 == 1 and r > 310:
print(n)
break
So it doesn't work and i dont know why. I am now preparing for the exam, so I would be grateful if you could explain the reason to me
the bin function returns a string and my idea is to go through the binary elements of this string, starting from the second element, to replace 0 with 1, and 1 with k. Then iterate over the elements of a new line again and replace k with 0
Took me longer than I expected but feels good.
Comments might make it look chaotic but will make it easily understandable.
#since N is supposed to be odd and >1 the loop is being run from 3
for N in range(3, 10000,2):
#appending binary numbers to the list bin_li
bin_li=[]
bin_li.append((bin(N)[2:]))
for i in bin_li:
#print("bin_li item :",i)
#storing 1st digit to be escaped in j
j=i[:1]
#reversing the digits
for k in i[1:]:
if k=='0':
#putting together the digits after reversing
j=j+'1'
else:
j=j+'0'
#print("reversed item :",j) #note first digit is escaped
#converting back to decimal
dec=int(j,2)
R=dec+N
#print("current sum:---------" ,R)
if R > 310:
print("The number N :",N)
print("The reversed binary number:",dec)
print("Sum :",R)
break
#break will only break the inner loop
# for reference https://www.geeksforgeeks.org/how-to-break-out-of-multiple-loops-in-python/
else:
continue
break

Number of Palindromic Substrings- error in dynamic programming

I'm trying to solve the number of palindromic substrings problem using DP.
The problem requires us to find the number of palindromic substrings in a string.
My current code is as follows:
def palindromic_substrings(s):
result = 0
dp = [[False] * len(s) for i in range(len(s))]
for i in range(len(s)):
for j in range(i, len(s)):
dp[i][j] = j-i <= 1 or (s[i] == s[j] and dp[i+1][j-1])
if dp[i][j]:
result += 1
return result
print(palindromic_substrings("aaa")) # returns 5- should be 6
My logic is a follows:
Let dp[i][j] represents whether the substring defined by s[i:j] is a palindromic substring. There are two cases to consider to determine dp[i][j].
The first is noticing that any substring of length less than 2 is always a palindrome i.e. j-i <= 1.
The second is that any substring that has length greater than 2 is a palindrome iff the first and last characters are the same and the inner substring, excluding the first and last characters is a palindrome i.e. s[i] == s[j] and dp[i+1][j-1].
If dp[i][j] is True i.e. it is palindromic, we increment the result.
My code is returning the wrong result and I'm unsure where the gap in my logic is.
Any help would be appreciated.
This is inspired by #Stef great comments, so the working code will be like this: (credit to him, question for me... ;-)
def countSubstrings(self, s: str) -> int:
n = len(s)
dp = [[0] * n for _ in range(n)]
ans = 0
for i in range(n-1, -1, -1):
for j in range(i, n):
dp[i][j] = s[i] == s[j] and ((j-i+1) < 3 or dp[i+1][j-1])
ans += dp[i][j]
return ans
And this is non-DP version to compare:
def countSubstrings(self, s: str) -> int:
count = 0
n = len(s)
for i in range(2 * n - 1):
left = i // 2
right = (i+1) // 2
while left >= 0 and right <n and s[left] == s[right]:
count += 1
left -= 1
right += 1
return count

Removing a specific digit from a number that was specified by the user

I tried to make a Python program that removes specific digit from a number, example a = 12025 k = 2 result is 105, however none of the guides helped me do that, can anybody help me with that?
Conversion to string does not seem elegant.
As pseudo-code:
number without digit (number, digit)
if number == digit
0
else if number < 10
number
else if number % 10 == digit
number without digit (number / 10, digit)
else
number without digit (number / 10, digit) * 10 + (number % 10)
Where / is integer division, truncating the remainder, and % is the modulo, remainder.
So it is a matter of recursion.
You have to convert into str type, then remove the occurrencies, and go back to int
int(str(a).replace(str(k),''))
a = 12025
k = 2
print(int(str(a).replace(str(k), '')))
If you want to use math rather than converting to and from string you can do
a = 12025
k = 2
result = 0
exp = 0
while a:
a, remainder = divmod(a, 10)
if remainder != k:
result = result + 10**exp * remainder
exp += 1

Counting 9's in numbers from 1 to n

I'm trying to count all 9's in numbers from 1 to n, including repeating digits such as in 99. My code (python 3) works and returns the corrects answer for most cases except for very large numbers (like 20 digit numbers). Could someone help and let me know how this is possible?
Thanx.
def count_nines(n):
count = 0
num = [i for i in str(n)]
while len(num) > 0:
if len(num) == 1:
if num[0] == '9':
count += 1
else:
count += int(num[0]) * int(str(len(num)-1).ljust(len(num)-1, '0'))
if num[0] == '9':
count += int(''.join(num[1:]))+1
num.pop(0)
return count
The problem is in this expression:
int(str(len(num)-1).ljust(len(num)-1, '0'))
This works fine as long as str(len(num)-1) is one character, but when len(num) > 10, this is no longer the case, and then ljust will add fewer zeroes than needed. In fact, you always want to append len(num)-2 zeroes. So change this expression to:
int(str(len(num)-1) + '0' * (len(num)-2))
Simply:
def count_nines(n):
count = 0
for i in range(n+1):
if "9" in [*str(i)]:
count = count + str(i).count('9')
return count
sum((str(i).count('9') for i in range(1, n+1)))

Problem with Python Code and the Functions in it

I have a Problem, I have to solve a task in Python and I dont know how to do it. The task is to define a function number_of_vowels, where the output should be the Number of vowels in a Word. With this function I have to write anotherone, many_vowels thats working with a list an a Number and where the number says how many vowels have to be at least in a word to be appended to the result list and then I have to append this Word. Thanks to everybody helping me ;D.
here is the code:
Wort = "parameter"
def number_of_vowels(Word):
result = 0
counter0 = 0
while result < 20:
if Word[counter0] == 'a' or 'e' or 'i' or 'o' or 'u':
result = result + 1
counter0 = counter0 + 1
else:
counter0 = counter0 + 1
return result
Words = []
counter1 = 0
def many_vowels(List , number):
if number_of_vowels(List[counter1]) < number:
counter1 + 1
else:
Words.append(List[counter1])
counter1 + 1
return Words
This code just gives me the answer to the letter a and not to the other vowels. For
print(number_of_vowels(Wort))
the output is: 1
but there are 4 vowels in this word
it also says: line 21, in many_vowels
IndexError: string index out of range
You're trying to call a function with wrong brackets. Function call should use round ones.
Try changing number_of_vowels[List[counter1]] with number_of_vowels(List[counter1])
This code contains some errors:
Calling for function should be using round brackets: number_of_vowels(List[counter1]) instead of number_of_vowels[List[counter1]]
doing result + 1 won't change value of the variable result, since you did not put the calculation result in the variable. use result = result + 1 (same for counters)
in number_of_vowels function, you want to scan the whole word? cause you did not use any loop, so it currently looking only at the first letter. Secondly, you put the compression in result and then add 1 to it. I'm not really sure why
edit:
Word = "parameter"
def number_of_vowels(Word):
result = 0
counter0 = 0
for index, letter in enumerate(Word):
if letter == 'a' or letter == 'e' or letter == 'i' or letter == 'o' or letter == 'u':
result = result + 1
return result
Words = []
counter1 = 0
def many_vowels(List_name , number):
for index, item in enumerate (List_name):
if number_of_vowels(item) >= number:
Words.append(item)
return Words

Resources