I am trying to figure out a way to determine the total number of non-matching, common digits between two numbers in python.
So far I can get the number of matching digits between the two numbers.The end goal is to have a function that takes two numbers ie 6621 and 6662 and return the numbers 2 for the number of matching digits and 1 for the number of non-matching shared digits.
I have tried using nested while loops to do this, but the count is not always accurate depending on the numbers being compared.
while i < n:#check 2. Nested while statements
j = 0
while j < n:
if g_list[i] == p_list[j] and j == i:
x
elif g_list[i] == p_list[j]:
z += 1
print(g_list[i],p_list[j],z, i, j)
j += 1
i += 1
You could do it this way:
a = 6661
b = 6662
def find_difference(first, second):
first_list = list(str(first))
second_list = list(str(second))
c = set(first_list)
d = set(second_list)
print((len(c.symmetric_difference(d)),len(c.intersection(d))))
Output:
(2, 1)
You can count the number of occurrence of each digit in each number and take the minimum of those. This will get you the number of common digits, then you subtract the number of matching digits.
def get_count_of_digit(number):
l = [0 for i in range(10)]
list_digit = str(number)
for d in list_digit:
l[int(d)] += 1
return l
def number_of_common_digit(number1, number2):
l1, l2 = [get_count_of_digit(n) for n in (number1, number2)]
return sum([min(l1[i], l2[i]) for i in range(10)])
Related
Enter the natural number N (1 <= N <= 1,000,000). Print to the screen the Nth number of the sequence: 9 18 27 36 45 54 63 72 81 90 108 117
(they all have their sum of digit equal to 9)
N = 9+(int(input())-1)*9
def sumnum(N):
sum = 0
while N > 0:
d = N%10
N = N//10
sum += d
sumnum(N)
while sum != 9:
N+=1
sumnum(N)
print(N)
Here's my code and it got this error
TimeLimitError: Stopped on Line 4
Your sumnum function doesn't return anything, so it never changes sum (or any other value) outside of the function. Normally you'd get an error trying to compare an undefined variable, but sum is actually the name of a builtin function, so that's what you're comparing 9 to.
Here's a simple approach: iterate through all numbers in a while loop, and check the sum of each one's digits by converting it to a string and summing the int values of its characters. Each time you find one whose sum is 9, decrement N by one. When it hits zero, print the current number.
>>> N = 12
>>> i = 0
>>> while True:
... i += 1
... if sum(int(d) for d in str(i)) == 9:
... N -= 1
... if N == 0:
... print(i)
... break
...
117
Here's a more code-golf-y approach using a filtered generator with itertools.count() (less efficient for big numbers because it builds a list of the sequence up to N instead of just printing the last element):
>>> import itertools
>>> list(zip(range(N), (i for i in itertools.count() if sum(int(d) for d in str(i)) == 9)))[-1][-1]
117
The millionth such number is 1020011001021000. Found in less than a second by either of these two solutions:
Solution 1
Produce all such numbers with up to 16 digits and then print the N-th (Try it online!):
from itertools import combinations_with_replacement
N = 1_000_000
worths = (10**i for i in range(16))
combs = combinations_with_replacement(worths, 9)
nums = sorted(map(sum, combs))
print(nums[N-1])
With up to 16 digits, the digit positions are worth 10^0 to 10^15. By picking 9 of those position worths (allowing repeats) and adding them, you get the numbers with digit sum 9.
For example, 1020011001021000 came from picking 10^15 once, 10^13 twice, 10^10 once, etc.
Solution 2
Imagine you have nine 1s and you move them around in the digit positions (the "ones" position, "tens" position, "hundreds" position, etc). They all start at the "ones" position, so the first number is 9. Then move one to the "tens" position, so you have the number 18. Move another there and you have 27. And so on. (Try it online!)
N = 1_000_000
digits = [9] + [0] * 15
for _ in range(N-1):
for i, d in enumerate(digits):
if d:
digits[i] = 0
digits[i+1] += 1
digits[0] = d - 1
break
print(int(''.join(map(str, reversed(digits)))))
This worked for me!
def getSum(n):
sum = 0
for digit in str(n):
sum += int(digit)
return sum
for i in range(0, 1000000):
n = i
sum = getSum(n)
if sum == 9:
print(f"{n} -- {sum}")
Numbers whose digits add to 9 are multiples of 9 and vice versa. So the Nth number whose digits add to 9 is N*9. So all you need is this:
N = int(input("Enter N: "))
print (N*9)
You can add range checking for N being between 1 and 1,000,000 if you like.
How can I write a recursive backtracking function count(N,S) in which it prints all N-digit numbers such that the sum of each 3 consecutive digits in the number is exactly equal to S where N will be less than or equal to 10, and is from 0 to 27.
Code:
def count(S):
n = int(S)
if n % 3 == 0:
print(int(n / 3 - 1),int(n / 3),int(n / 3 + 1))
else:
print(None)
S = 27
count(S)
Sample Output:
8 9 10
I'm quite confused on how can I write this recursively.
Your current function is not recursive. To make it recursive, you'd basically have to call count(n-1, s) somewhere within the execution of count(n, s). One way to do it would be like this:
if n > 1, get possible solutions for n-1 and append any digit that still satisfied the condition
if n == 0 just return "" (it's a bit easier if the function returns strings, not actual integers)
As a generator function, this could look somewhat like this. Of course, you can just as well collect the results in a list and return them, or just get the count of such numbers and return that.
def count(n, s):
if n > 0:
for x in count(n-1, s):
for d in range(10):
y = str(d) + x
if len(y) < 3 or sum(map(int, y[:3])) == s:
yield y
else:
yield ""
for x in count(5, 15):
print(x)
We want to find the number of 'a's in a given string s multiplied infinite times.
We will be given a number n that is the slicing size of the infinite string.
sample input:
aba 10
output:
7
Here aba is multiplied with 10, resulting in 'abaabaabaa'
and the no. of 'a's are 7.
This is my code:
def repeatedString(s, n):
count = 0
inters = s * n
reals = s[0:n+1]
for i in reals:
if (i == 'a'):
count += 1
return count
I'm getting 2 instead of 7 as the output (test case 'aba' 10). Where did I go wrong? I just multiplied the given string with n because it will never be greater than the slicing size.
Here's the link to the problem:
https://www.hackerrank.com/challenges/repeated-string/problem
Much simpler solution using python3.
s = input().strip()
n = int(input())
print(s[:n%len(s)].count('a')+(s.count('a')*(n//len(s))))
There's no reason to slice the string
def repeatedString(s, n):
count = 0
for index, i in enumerate(s*n):
if index >= n:
return count
if(i == 'a'):
count += 1
# empty string
return count
I used a simple unitary method.
Number of 'a' in one repetition is cnt_a so the number of 'a' in first n characters will be (cnt_a/len(s)) * n
def repeatedString(s, n):
if len(s)==1 and s=='a':
return n
cnt_a=0
for i in s:
if i == 'a':
cnt_a+=1
if cnt_a % 2 == 0:
no_a = (cnt_a/len(s)) * n
return math.ceil(no_a)
else:
no_a = (cnt_a/len(s)) * n
return math.floor(no_a)
If you would like a more readable answer....
def repeatedString(s, n):
target = 'a'
target_count = 0
# how many times does the string need to be repeated: (n // len(s) * s) + s[:(n % len(s))]
quotient = n // len(s)
remainder = n % len(s)
for char in s: # how many times target appears in 1 instance of the substring
if char == target:
target_count += 1
# how many times the target appears in many instances of the substring provided
target_count = target_count * quotient
for char in s[:remainder]: # count the remaining targets in the truncated substring
if char == target:
target_count += 1
return target_count
One liner answer:
return [s[i%len(s)] for i in range(n)].count('a')
There is only two problem in your code
s = 'aba'
n = 10
count = 0
inters = s * n
# Here you need to slice(inters) not (s) because s only hold 'aba'
# And not n+1 it's take 11 values only n
reals = inters[0:n]
for i in reals:
if (i == 'a'):
count += 1
print(count)
so if the string contains "a"s only simply return n. otherwise, count the number of a's in the string s, now using divmond() function I have found the number of string that can be added without surpassing n. for example string s is "aba" and n=10, so I can add 3 "abs"s completely without the length of string going over 10. now the number of a's in the added string (3*2). Now the places left to be filled are equal to the remainder(y) of divmond() function. Now slice the string s up to y and find the number of a's in it and add it to count.
divmond(10,3) returns (10//3) and it's remainder.
def repeatedString(s, n):
if len(s)==1 and s=="a":
return n
count=s.count("a")
x,y=divmod(n,len(s))
count=count*x
str=s[:y]
return count+str.count("a")
The solution in Python 3:
def repeatedString(s,n):
i = 0
c = 0
for i in s:
if i == 'a':
c += 1
q = int(n / len(s)) #Finding the quotient
r = int(n % len(s)) #Finding the remainder
if r == 0:
c *= q
else:
x = 0
for i in range(r):
if s[i] == 'a':
x += 1
c = c*q + x
return int(c)
s = input()
n = int(input())
print(repeatedString(s,n))
if character 'a' is present in a given string pattern, then its quite faster to get the repeated count for it and later based on the total length of final string mentioned, will be trying to repeat the given pattern for same number of times & hence will multiple the repeated count with number of times a string pattern is going to repeat. Importantly if final string input is in odd numbers then we need to identify the those odd pattern and separately count the occurance of character 'a' in odd string pattern. Finally summing up the total count ( even & odd ) will gives us the expected result
def repeatedString(s, n):
# Get the length of input string
strlen = len(s)
a_repeat = 0
# Get the total count of a repeated character from the input string
for i in range(0,strlen):
if s[i] == 'a':
a_repeat = a_repeat + 1
# Get the multiplier to make sure that desired input string length achieved
str_multiplier = int(n // strlen)
# Get the repeated count if new string is been created
result = a_repeat*str_multiplier
new_str = s[:int( n % strlen )]
# for odd length of string, get the remaining characters and find repated characters count and add up it to final count
for i in range(0, len(new_str)):
if new_str[i] == 'a':
result += 1
return result
For this problem,
Get the length of string s.
First, if conditions: constrain
Now, instead of using a loop to add to space and time complexity, we use basic math's. Find the quotient of n//Len (s). Now find the number of times "a" is used in our string.
We can multiply the quotient with this number to get the total "a" used. Now, we can find the remainder of the string and use slice to search for "a" in the string we have left in the last.
Add both to get our answer.
def repeatedString(s, n):
#finding quotient and remainder of division
str1=len(s)
remainder=0
if 1<=str1<=100 and 1<=n<=10**12:
quotient= n//str1
a_s = s.count("a")
if a_s==0:
return 0
else:
remainder=s[:n%str1].count('a')
return quotient*a_s + remainder
Simple answer:
def repeatedString(s, n):
totalNumber = 0 // setting total of a's to 0
// using count function to find the total number of a's in the substring
totalNumber = s.count('a')
// finding how many number of times the substring fits in "n" and multiplying that by the number of a's we found earlier
totalNumber = n//len(s) * totalNumber
// if there is a remainder, we loop through the remainder string and add the number of "a's" found in that substring to the total
for i in s[:n%len(s)]:
if(i == "a"):
totalNumber +=1
return totalNumber
I can't came up with an algorithm to solve the following problem:
Generate an array of first n prime numbers.
Remove k numbers from this array in such way that after concatenating all numbers left we get the largest possible result.
E.G.
Input: 4 2
First value(4) is n
Second value(2) is k
Array [2, 3, 5, 7] is generated
the program have to remove numbers 2 and 3 from this array(to get 57, which is the max possible number we can get from this array after deleting k numbers and merging all the numbers left together).
e.g. If it removes 2 and 7 - we will get 35(which is not the max number). So, this solution is wrong.
Output: 57
This is the code I have so far:
def getInputedVals():
return [int(el) for el in input().split(" ")]
def get_primes_array(x):
primes = []
a = 2
# for a in range(2, 10000):
while(len(primes) != x):
for b in range(2, a):
if a % b == 0:
break
else:
primes.append(a)
a += 1
if len(primes) == x:
return primes
def combine_numbers(nums):
s = [str(i) for i in nums]
return int("".join(s))
# Algorithm to find the max number should be written here
def get_result(nums, n_nums_to_delete):
print("algorithm goes here")
def main(item):
primes = get_primes_array(item["n_first"])
summed = sum(primes)
# print(get_result(primes, item["n_nums_to_delete"]))
print("Primes: ", primes)
n_first, n_nums_to_delete = getInputedVals()
item = {"n_first": n_first, "n_nums_to_delete": n_nums_to_delete}
main(item)
You have the answer, sort your results and take the sorted list starting from the n_nums_to_delete :
def get_result(nums, n_nums_to_delete):
return sorted(nums)[n_nums_to_delete:]
As #Yuri Ginsburg mentioned in the comment, your prime number list is already sorted, so you can simply do :
def get_result(nums, n_nums_to_delete):
return nums[n_nums_to_delete:]
A Python coding exercise asks to make a function f such that f(k) is the k-th number such that its k-th digit from the left and from the right sums to 10 for all k. For example 5, 19, 28, 37 are the first few numbers in the sequence.
I use this function that explicitly checks if the number 'n' satisfies the property:
def check(n):
#even digit length
if len(str(n)) % 2 == 0:
#looping over positions and checking if sum is 10
for i in range(1,int(len(str(n))/2) + 1):
if int(str(n)[i-1]) + int(str(n)[-i]) != 10:
return False
#odd digit length
else:
#checking middle digit first
if int(str(n)[int(len(str(n))/2)])*2 != 10:
return False
else:
#looping over posotions and checking if sum is 10
for i in range(1,int(len(str(n))/2) + 1):
if int(str(n)[i-1]) + int(str(n)[-i]) != 10:
return False
return True
and then I loop over all numbers to generate the sequence:
for i in range(1, 10**9):
if check(i):
print(i)
However the exercise wants a function f(i) that returns the i-th such number in under 10 seconds. Clearly, mine takes a lot longer because it generates the entire sequence prior to number 'i' to calculate it. Is it possible to make a function that doesn't have to calculate all the prior numbers?
Testing every natural number is a bad method. Only a small fraction of the natural numbers have this property, and the fraction decreases quickly as we get into larger numbers. On my machine, the simple Python program below took over 3 seconds to find the 1,000th number (2,195,198), and over 26 seconds to find the 2,000th number (15,519,559).
# Slow algorithm, only shown for illustration purposes
# '1': '9', '2': '8', etc.
compl = {str(i): str(10-i) for i in range(1, 10)}
def is_good(n):
# Does n have the property
s = str(n)
for i in range((len(s)+1)//2):
if s[i] != compl.get(s[-i-1]):
return False
return True
# How many numbers to find before stopping
ct = 2 * 10**3
n = 5
while True:
if is_good(n):
ct -= 1
if not ct:
print(n)
break
n += 1
Clearly, a much more efficient algorithm is needed.
We can loop over the length of the digit string, and within that, generate numbers with the property in numeric order. Sketch of algorithm in pseudocode:
for length in [1 to open-ended]:
if length is even, middle is '', else '5'
half-len = floor(length / 2)
for left in (all 1) to (all 9), half-len, without any 0 digits:
right = 10's complement of left, reversed
whole-number = left + middle + right
Now, note that the count of numbers for each length is easily computed:
Length First Last Count
1 5 5 1
2 19 91 9
3 159 951 9
4 1199 9911 81
5 11599 99511 81
In general, if left-half has n digits, the count is 9**n.
Thus, we can simply iterate through the digit counts, counting how many solutions exist without having to compute them, until we reach the cohort that contains the desired answer. It should then be relatively simple to compute which number we want, again, without having to iterate through every possibility.
The above sketch should generate some ideas. Code to follow once I’ve written it.
Code:
def find_nth_number(n):
# First, skip cohorts until we reach the one with the answer
digits = 1
while True:
half_len = digits // 2
cohort_size = 9 ** half_len
if cohort_size >= n:
break
n -= cohort_size
digits += 1
# Next, find correct number within cohort
# Convert n to base 9, reversed
base9 = []
# Adjust n so first number is zero
n -= 1
while n:
n, r = divmod(n, 9)
base9.append(r)
# Add zeros to get correct length
base9.extend([0] * (half_len - len(base9)))
# Construct number
left = [i+1 for i in base9[::-1]]
mid = [5] * (digits % 2)
right = [9-i for i in base9]
return ''.join(str(n) for n in left + mid + right)
n = 2 * 10**3
print(find_nth_number(n))
This is a function that exploits the pattern where the number of "valid" numbers between adjacent powers of 10 is a power of 9. This allows us to skip over very many numbers.
def get_starting_point(k):
i = 0
while True:
power = (i + 1) // 2
start = 10 ** i
subtract = 9 ** power
if k >= subtract:
k -= subtract
else:
break
i += 1
return k, start
I combined this with the method you've defined. Supposing we are interested in the 45th number,
this illustrates the search starts at 1000, and we only have to find the 26th "valid" number occurring after 1000. It is guaranteed to be less than 10000. Of course, this bound gets worse and worse at scale, and you would want to employ the techniques suggested by the other community members on this post.
k = 45
new_k, start = get_starting_point(k)
print('new_k: {}'.format(new_k))
print('start at: {}'.format(start))
ctr = 0
for i in range(start, 10**9):
if check(i):
ctr += 1
if ctr == new_k:
break
print(i)
Output:
new_k: 26
start at: 1000
3827
It seems the 45th number is 3827.