failing to compare two numbers converted from string - python-3.x

here is my code... It's considering only 8 and 88 among 1 to 100 which aren't karpekar numbers...failing at if condition(s==n)
def kaprekarNumbers(p, q):
for i in range(p,q+1):
n=i
m=str(i*i);
sl1=m[:int(len(m)/2)]
sl2=m[int(len(m)/2):]
if(sl2==""):
sl2=0
s=int(sl2)+int(sl2)
print(s==n)
if s==n:
print(i)

Using strings to process numbers is not usually a good idea.
You can get the number of digits of a number n with
math.ceil(math.log10(n))
You can get the last a digits of a number n with
n % a
(See: How does % work in Python?)
You can get the first a digits of a number n with
p // (10 ** a)
Those would be useful for base-10 Kaprekar numbers.
[Please note, I do not have a copy of Python to hand to check those.]

Related

What the time complexity of DigitalRoot?

Example 1:
Input:
n = 1
Output: 1
Explanation: Digital root of 1 is 1
Example 2:
Input:
n = 99999
Output: 9
Explanation: Sum of digits of 99999 is 45
which is not a single digit number, hence
sum of digit of 45 is 9 which is a single
digit number.
Could someone help what is the time complexity of my code? I think its O(loglog(N)) but not sure.
def sumOfDigits(n):
if n==0:
return 0
else:
return int(n%10) + sumOfDigits(n//10)
def digitalRoot(n):
ans = n
if n<=9:
return n
else:
while ans>9:
ans = sumOfDigits(ans)
return ans
Let's calculate the complexity for the first step
If an algorithm depends on the number of digits it contains the time complexity of such algorithm is:
O(log10(n))
This is because we represent numbers in base 10 notation.
For example, this would make the relation crystal clear:
O(log10(100)) = 2
O(log10(1000)) = 3
O(log10(10000)) = 4
Now this answers the question to some extent, if we were only adding all digits once, we'd stop here.
But since we're not, let's move forward. Now if all the digits are added once, we again add the digits of that resultant number. Making it a convergent series.
Thus the answer could be:
O(log10(n)) + O(log10(log10(n))) + O(log10(log10(log10(n)))) + ...
This is my best estimation for the upper bound of complexity.

Loop won't finish...Poor indentation?

I am new to python and Jupyter Notebook
The objective of the code I am writing is to request the user to introduce 10 different integers. The program is supposed to return the highest odd number introduced previously by the user.
My code is as followws:
i=1
c=1
y=1
while i<=10:
c=int(input('Enter an integer number: '))
if c%2==0:
print('The number is even')
elif c> y
y=c
print('y')
i=i+1
My loop is running over and over again, and I don't get a solution.
I guess the code is well written. It must be a slight detail I am not seeing.
Any help would be much appreciated!
You have elif c > y, you should just need to add a colon there so it's elif c > y:
Yup.
i=1
c=1
y=1
while i<=10:
c=int(input('Enter an integer number: ')) # This line was off
if c%2==0:
print('The number is even')
elif c> y: # Need also ':'
y=c
print('y')
i=i+1
You can right this in a much compact fashion like so.
Start by asking for 10 numbers in a single line, separated by a space. Then split the string by , into a list of numbers and exit the code if exactly 10 numbers are not provided.
numbers_str = input("Input 10 integers separated by a comma(,) >>> ")
numbers = [int(number.strip()) for number in numbers_str.split(',')]
if len(numbers) != 10:
print("You didn't enter 10 numbers! try again")
exit()
A bad run of the code above might be
Input 10 integers separated by a comma(,) >>> 1,2,3,4
You didn't enter 10 numbers! try again
Assuming 10 integers are provided, loop through the elements, considering only odd numbers and updating highest odd number as you go.
largest = None
for number in numbers:
if number % 2 != 0 and (not largest or number > largest):
largest = number
Finally, check if the largest number is None, which means we didn't have any odd numbers, so provide the user that information, otherwise display the largest odd number
if largest is None:
print("You didn't enter any odd numbers")
else:
print("Your largest odd number was:", largest)
Possible outputs are
Input 10 integers separated by a comma(,) >>> 1,2,3,4,5,6,7,8,9,10
Your largest odd number was: 9
Input 10 integers separated by a comma(,) >>> 2,4,6,8,2,4,6,8,2,4
You didn't enter any odd numbers

Efficiently counting the number of substrings of a digit string that are divisible by k?

We are given a string which consists of digits 0-9. We have to count number of sub-strings divisible by a number k. One way is to generate all the sub-strings and check if it is divisible by k but this will take O(n^2) time. I want to solve this problem in O(n*k) time.
1 <= n <= 100000 and 2 <= k <= 1000.
I saw a similar question here. But k was fixed as 4 in that question. So, I used the property of divisibility by 4 to solve the problem.
Here is my solution to that problem:
int main()
{
string s;
vector<int> v[5];
int i;
int x;
long long int cnt = 0;
cin>>s;
x = 0;
for(i = 0; i < s.size(); i++) {
if((s[i]-'0') % 4 == 0) {
cnt++;
}
}
for(i = 1; i < s.size(); i++) {
int f = s[i-1]-'0';
int s1 = s[i] - '0';
if((10*f+s1)%4 == 0) {
cnt = cnt + (long long)(i);
}
}
cout<<cnt;
}
But I wanted a general algorithm for any value of k.
This is a really interesting problem. Rather than jumping into the final overall algorithm, I thought I'd start with a reasonable algorithm that doesn't quite cut it, then make a series of modifications to it to end up with the final, O(nk)-time algorithm.
This approach combines together a number of different techniques. The major technique is the idea of computing a rolling remainder over the digits. For example, let's suppose we want to find all prefixes of the string that are multiples of k. We could do this by listing off all the prefixes and checking whether each one is a multiple of k, but that would take time at least Θ(n2) since there are Θ(n2) different prefixes. However, we can do this in time Θ(n) by being a bit more clever. Suppose we know that we've read the first h characters of the string and we know the remainder of the number formed that way. We can use this to say something about the remainder of the first h+1 characters of the string as well, since by appending that digit we're taking the existing number, multiplying it by ten, and then adding in the next digit. This means that if we had a remainder of r, then our new remainder is (10r + d) mod k, where d is the digit that we uncovered.
Here's quick pseudocode to count up the number of prefixes of a string that are multiples of k. It runs in time Θ(n):
remainder = 0
numMultiples = 0
for i = 1 to n: // n is the length of the string
remainder = (10 * remainder + str[i]) % k
if remainder == 0
numMultiples++
return numMultiples
We're going to use this initial approach as a building block for the overall algorithm.
So right now we have an algorithm that can find the number of prefixes of our string that are multiples of k. How might we convert this into an algorithm that finds the number of substrings that are multiples of k? Let's start with an approach that doesn't quite work. What if we count all the prefixes of the original string that are multiples of k, then drop off the first character of the string and count the prefixes of what's left, then drop off the second character and count the prefixes of what's left, etc? This will eventually find every substring, since each substring of the original string is a prefix of some suffix of the string.
Here's some rough pseudocode:
numMultiples = 0
for i = 1 to n:
remainder = 0
for j = i to n:
remainder = (10 * remainder + str[j]) % k
if remainder == 0
numMultiples++
return numMultiples
For example, running this approach on the string 14917 looking for multiples of 7 will turn up these strings:
String 14917: Finds 14, 1491, 14917
String 4917: Finds 49,
String 917: Finds 91, 917
String 17: Finds nothing
String 7: Finds 7
The good news about this approach is that it will find all the substrings that work. The bad news is that it runs in time Θ(n2).
But let's take a look at the strings we're seeing in this example. Look, for example, at the substrings found by searching for prefixes of the entire string. We found three of them: 14, 1491, and 14917. Now, look at the "differences" between those strings:
The difference between 14 and 14917 is 917.
The difference between 14 and 1491 is 91
The difference between 1491 and 14917 is 7.
Notice that the difference of each of these strings is itself a substring of 14917 that's a multiple of 7, and indeed if you look at the other strings that we've matched later on in the run of the algorithm we'll find these other strings as well.
This isn't a coincidence. If you have two numbers with a common prefix that are multiples of the same number k, then the "difference" between them will also be a multiple of k. (It's a good exercise to check the math on this.)
So this suggests another route we can take. Suppose that we find all prefixes of the original string that are multiples of k. If we can find all of them, we can then figure out how many pairwise differences there are among those prefixes and potentially avoid rescanning things multiple times. This won't find everything, necessarily, but it will find all substrings that can be formed by computing the difference of two prefixes. Repeating this over all suffixes - and being careful not to double-count things - could really speed things up.
First, let's imagine that we find r different prefixes of the string that are multiples of k. How many total substrings did we just find if we include differences? Well, we've found k strings, plus one extra string for each (unordered) pair of elements, which works out to k + k(k-1)/2 = k(k+1)/2 total substrings discovered. We still need to make sure we don't double-count things, though.
To see whether we're double-counting something, we can use the following technique. As we compute the rolling remainders along the string, we'll store the remainders we find after each entry. If in the course of computing a rolling remainder we rediscover a remainder we've already computed at some point, we know that the work we're doing is redundant; some previous scan over the string will have already computed this remainder and anything we've discovered from this point forward will have already been found.
Putting these ideas together gives us this pseudocode:
numMultiples = 0
seenRemainders = array of n sets, all initially empty
for i = 1 to n:
remainder = 0
prefixesFound = 0
for j = i to n:
remainder = (10 * remainder + str[j]) % k
if seenRemainders[j] contains remainder:
break
add remainder to seenRemainders[j]
if remainder == 0
prefixesFound++
numMultiples += prefixesFound * (prefixesFound + 1) / 2
return numMultiples
So how efficient is this? At first glance, this looks like it runs in time O(n2) because of the outer loops, but that's not a tight bound. Notice that each element can only be passed over in the inner loop at most k times, since after that there aren't any remainders that are still free. Therefore, since each element is visited at most O(k) times and there are n total elements, the runtime is O(nk), which meets your runtime requirements.

mathematical puzzle on binary string

I have been given a binary string of length n and i need to find the minimum numbers of operations to perform such that string does not contain more than k consecutive equal characters.
Only kind of operation I am allowed to perform is to flip any ith character of the string. flipping a character means changing a '1' to '0' or a '0' to '1'.
for example:
if n = 4 , k = 1 and string = 1001
then Answer:
string = 1010 and minimum operations = 2
I need to also find the new string.
can anyone tell me an efficient algorithm for solving problem considering n <=10^5
There's one way:
if k>1:
if k+1 matching characters are found:
if a[k+1]==a[k+2]:
flip a[k+1]
else if a[k+1]!=a[k+2]:
flip a[k]
for k=1 you can do it!
Here flipping means from 1 to 0 and vice-versa
For k=1 there are only two possible output strings - the one beginning with 0 and the one beginning with 1. You can check which of them is closer to the input string.
For larger k, you can just look at every sequence of k+1 identical characters, and fix it internally - without changing the characters at either end. For a sequence of k' > k you would need floor(k'/(k+1)) flips. It should not be hard to show that this is optimal.
Running time is linear and extra space is constant.
There are 2 cases:
1)For k>1
We have 2 possibilities.
a)one that is starting with 0:
eg:0101010101
b)one that is starrting with 1
eg:10101010.....
We should now calculate the distance(the number of different elements between the 2 strings)for each possiblity.Then the ans will be the one that has minimum changes.
2)for k>1
res2=0;res1=1;
c1=A[i];//it represents the last elemnet
i=1;
while(A[i]!='\0'){
if(A[i]==c1){
res1++;//the no of consecutive elements
if(res1>k){
if(A[i]==A[i+1])
flip(i);//it flips the ith element
else
flip(i-1);
res2++;//it counts the no of changes
res1=1;
}
}
else
res1=1;
c1=A[i];
i++;
}

Finding a number sequence in an integer

Guys heres my problem:
I am trying to read an integer from the user(e.g. 12345)
How can i check if the pattern "34" exists in the first integer?
My constraint is that i cannot convert it to string and cannot use arrays.
Here is what i managed to write to print some of the patterns that exists in 12345:
import math
int1 = int(input("input an integer: "))
#I used this to find out how many digits are in the integer
count = math.ceil(math.log10(int1))
for i in range(count):
print (int1 % (10 ** (i+1)))
for i in range(count):
print (int1 // (10 ** (i+1)))
Since this seems to be homework, I won't provide an answer, but only a rough hint.
Hint: extract each digit of the number using divmod(n, 10), which returns n without the last digit and the last digit of n. Hold the current digit and the previous digit in variables and compare them with the pattern, 34, each time a new a digit is extracted.

Resources