I am beginner in programming, So can you please tell me what's wrong with my code?
I want to print next palindrome number if the number entered by the user (n) is not palindrome
n = int(input("Enter any number :- "))
reverse = 0
temp = n
while (n!=0):
reverse = reverse * 10
reverse = reverse + n%10
n=n//10
if(temp==reverse):
print ("Already palindrome:: ")
if(temp != reverse):
new_temp = temp
new_reverse = 0
for i in range(new_temp,new_temp+10):
while(temp != 0):
new_reverse = new_reverse * 10
new_reverse = new_reverse + temp%10
temp = temp//10
if(new_temp==new_reverse):
print ("Next pallindrome is :- ",new_temp)
break
if(new_temp != new_reverse):
temp = new_temp+1
There are two problems with your code.
1) Your "for i in range" loop calculates the reverse of the temp variable, but you don't change the temp variable's value.
You do
new_temp = temp
for i in range(new_temp,new_temp+10):
[SNIP]
if(new_temp != new_reverse):
temp = new_temp+1 #this value never changes.
So you're making 10 iterations with one and the same value.
2) Ten iterations might not be enough to find a palindrome. Keep going until you find a palindrome.
Working code:
def reverse(num):
reverse= 0
while num:
reverse= reverse*10 + num%10
num= num//10
return reverse
num= int(input("Enter any number :- "))
if num==reverse(num):
print ("Already palindrome.")
else:
while True:
num+= 1
if num==reverse(num):
print ("Next palindrome is : %s"%num)
break
To check if a number is a palindrome, you don't need to convert it to a number. In fact, its a lot simpler if you just check the string equivalent of your number.
>>> i = '212'
>>> i == i[::-1]
True
>>> i = '210'
>>> i == i[::-1]
False
Use this to your advantage, and create a function:
def is_palindrome(foo):
return str(foo) == str(foo)[::-1]
Next, to find the next palindrome, simply increment the number till your palindrome check is true.
Combine all that, and you have:
def is_palindrome(n):
return str(n) == str(n)[::-1]
n = raw_input('Enter a number: ')
if is_palindrome(n):
print('Congratulations! {0} is a palindrome.'.format(n))
else:
n1 = n
while not is_palindrome(n1):
n1 = int(n1)+1
print('You entered {0}, but the next palindrome is {1}'.format(n, n1))
Here is how it works:
$ python t.py
Enter a number: 123
You entered 123, but the next palindrome is 131
$ python t.py
Enter a number: 121
Congratulations! 121 is a palindrome.
If it helps, I believe it's possible to solve this problem with n/2 iterations where n is the length of the input number. Here's my solution in Python:
def next_palin_number(number):
number+=1
# Convert the number to a list of its digits.
number = list(str(number))
# Initialize two indices for comparing symmetric digits.
i = 0
j = len(number) - 1
while i < j:
# If the digits are different:
if number[i] != number[j]:
# If the lower-power digit is greater than the higher-power digit:
if int(number[j]) > int(number[i]):
if number[j-1]!='9':
number[j - 1] = str(int(number[j - 1]) + 1)
number[j] = number[i]
else:
number = list(str(int(''.join(number[:j]))+1))+number[j:]
else:
number[j] = number[i]
i += 1
j -= 1
# Concatenate and return the result.
return "".join(number)
This problem has a wonderful number of ways to solve them.
One of them is
def nearest_palindrome(number):
#start writitng your code here
while True:
number+=1
if str(number) == str(number)[::-1]:
return number
number=12300
print(nearest_palindrome(number))
Thanks for your time to read my answer : )
I have written this for finding next pallindrome number given a pallindrome number.
def palindrome(num):
bol=False
#x=len(str(num))
num=num+1
while(bol==False):
if(check_palindrome(num)):
bol=True
else:
num=num+1
return num
def check_palindrome(n):
temp=n
rev=0
while(n>0):
dig=n%10
rev=rev*10+dig
n=n//10
if(temp==rev):
return True
b=palindrome(8)
print(b)
def next_palin_drome(n):
while True:
n+=1
if str(n) == str(n)[::-1]:
return n
n=12231
print(next_palin_drome(n))
output:12321
def nearest_palindrome(number):
for i in range(1,number):
number=number+1
tem=str(number)
tem1=tem[-1::-1]
if(tem==tem1):
return number
else:
continue
number=12997979797979797
print(nearest_palindrome(number))
def nearest_palindrome(number):
n = len(str(number))//2
if(len(str(number)) % 2 == 0):
#number like 1221
number_1 = int((str(number))[:n]) #12
number_2 = int((str(number))[n:]) #21
if(number_1 < number_2):
number_1 += 1
number_2 = int(str(number_1)[::-1])
else:
number_2 = int(str(number_1)[::-1])
# if last half part is zero then just reverse the first number
if number_2 == 0:
number_2 = str(number_1)[::-1]
#combining the both parts
ans = int(str(number_1) + str(number_2))
return ans
else:
#numer like 12510 n=2
nu = int((str(number))[:n+1]) #add in this number
number_1 = int((str(number))[:n]) # 12
number_2 = int((str(number))[n+1:]) # 21
if (number_1 < number_2):
nu += 1
number_2 = int((str(nu))[::-1][1:])
else:
number_2 = int((str(nu))[::-1][1:])
#if last half part is zero then just reverse the first number
if number_2 == 0:
number_2 = str(nu)[::-1]
number_2 = number_2[1:]
#combinning both parts
ans = int(str(nu) + str(number_2))
return ans
number=12331
print(nearest_palindrome(number))
If a definite range is given:
# function to check if the number is a palindrome
def palin(x):
s=str(x)
if s==s[::-1]:
return True
else:
return False
n=int(input("Enter the number"))
# Putting up range from the next number till 15 digits
for i in range(n+1,int(10e14)):
if palin(i) is True:
print(i)
break
A brute force method:
def math(n):
while not var:
n += 1
if str(n) == str(n)[::-1] : f = 'but next is : '+str(n); return f
n = int(input()); t = math(n); print('Yes',t) if str(n) == str(n)[::-1] else print('No',t); global var; var = False
This is a good fast solution. I saw that the other solutions were iterating and checking through every +1 they did, but this is really slow for big numbers.
This solution has O(n) time if you look at the length of the number
beginNumber = 123456789101112131415161718 #insert number here for next palidrome
string = str(beginNumber + 1)
length = len(string)
number= [int(x) for x in list(string)]
for i in range(length//2):
if (number[i] != number[length-1-i]):
if (number[i]<number[length-1-i]):
number[length-2-i] += 1
number[length-1-i] = number[i]
print("".join([str(x) for x in number]))
I have written this for finding next pallindrome number given a pallindrome number..
#given a pallindrome number ..find next pallindrome number
input=999
inputstr=str(input)
inputstr=inputstr
#append 0 in beginning and end of string ..in case like 99 or 9999
inputstr='0'+inputstr+'0'
length=len(inputstr)
halflength=length/2;
#if even length
if(length%2==0):
#take left part and reverse it(which is equal as the right part )
temp=inputstr[:length/2]
temp=temp[::-1]
#take right part of the string ,move towards lsb from msb..If msb is 9 turn it to zero and move ahead
for j,i in enumerate(temp):
#if number is not 9 then increment it and end loop
if(i!="9"):
substi=int(i)+1
temp=temp[:j]+str(substi)+temp[j+1:]
break;
else:
temp=temp[:j]+"0"+temp[j+1:]
#now you have right hand side...mirror it and append left and right part
output=temp[::-1]+temp
#if the length is odd
if(length%2!=0 ):
#take the left part with the mid number(if length is 5 take 3 digits
temp=inputstr[:halflength+1]
#reverse it
temp=temp[::-1]
#apply same algoritm as in above
#if 9 then make it 0 and move on
#else increment number and break the loop
for j,i in enumerate(temp):
if(i!="9"):
substi=int(i)+1
temp=temp[:j]+str(substi)+temp[j+1:]
break;
else:
temp=temp[:j]+"0"+temp[j+1:]
#now the msb is the middle element so skip it and copy the rest
temp2=temp[1:]
#this is the right part mirror it to get left part then left+middle+right isoutput
temp2=temp2[::-1]
output=temp2+temp
print(output)
similarly for this problem take the left part of given number ...reverse it..store it in temp
inputstr=str(number)
if(inputstr==inputstr[::-1])
print("Pallindrome")
else:
temp=inputstr[:length/2]
temp=temp[::-1]
for j,i in enumerate(temp):
if(i!="9"):
substi=int(i)+1
temp=temp[:j]+str(substi)+temp[j+1:]
break;
else:
temp=temp[:j]+"0"+temp[j+1:]
now depending on length of your number odd or even generate the output..as in the code
if even then output=temp[::-1]+temp
if odd then temp2=temp1[1:]
output=temp2[::-1]+temp
I am not sure about this solution..but hope it helps
Related
Link to kata on Сodewars
Task is to find the next greater number that has same digits.
So, here are some samples:
Input: n = "218765"
Output: "251678"
Input: n = "1234"
Output: "1243"
Input: n = "4321"
Output: "Not Possible"
Input: n = "534976"
Output: "536479"
Samples were taken from geeks for geeks
def next_bigger(n):
if len(str(n)) == 1:
return -1
else:
pass
k = math.factorial(len(str(n)))
lst2 = []
lst3 = []
lst4 = []
for num in str(n):
lst2.append(num)
for num in lst2:
if lst2.count(num) == len(lst2):
return -1
else:
pass
for num in lst2:
if lst2.count(num) > 1 and num not in lst4:
k = k/math.factorial(lst2.count(num))
lst4.append(num)
else:
pass
while True:
shuffle(lst2)
if int(''.join(lst2)) not in lst3:
lst3.append(int(''.join(lst2)))
print(len(lst3))
pass
if int(''.join(lst2)) in lst3:
if len(lst3) == k:
break
else:
pass
t = sorted(lst3)
for num in t:
if num > n:
return num
else:
pass
return -1
My code seems to work, but it runs into timeout.
First, code checks for corner solutions like n = 1111 or n = 3
Second, it uses combinatorics to determine how many combinations are available to get from the given number.
Third, it shuffles numbers to get all available combinations and adds them to the list. From there it just gets the next number from the given one or returns -1.
It seem to work with all samples.
Is it possible to somehow optimize this way of solving this problem ?
With Python everything is possible :)
you can do something like this
def next_greater_number(n):
n_s = str(n)
N = len(n_s)
min_digit = int(n_s[-1])
min_digit_idx = N-1
left_side = n_s
right_side = ''
for i in range(len(n_s)-1, 0, -1):
left_side = left_side[:i]
right_side = n_s[i] + right_side
# print(left_side, right_side)
# keep record of minimum number
if int(n_s[i]) < min_digit:
min_digit_idx = i
min_digit = int(n_s[i])
# get to the point where right digit is greater than left digit
if int(n_s[i]) > int(n_s[i-1]):
# exclude min digit, because we will append it on the left side
right_side = n_s[i:min_digit_idx] + n_s[min_digit_idx+1:] + left_side[-1]
right_side = ''.join(sorted(right_side))
output = left_side[:-1] + str(min_digit) + right_side
break
else:
output = "Not Possible"
return output
By traversing right to left looking for a pattern where right side digit is greater than the left digit. We need to replace minimum of the right side with left side last digit. After that sorting the right side makes number just greater than current number.
I wrote this code for summing up digits of a number which is bigger than 10 until the result only have one digit and when I try to compile it, it won't even give me an error until I stop it. I want to know what's the problem.
number = input()
#sumed_up_digits = result
result = 0
while len(number) != 1:
for i in number:
int_i = int(i)
result = result + int_i
number = str(result)
print(result)
Try the following code:
s=input()
n=len(s)
result=0
for i in range(n-1):
result=result+int(s[i])
print(result)
This for loop runs from 0th to (n-2)th index of the given string, hence the last digit will not be added to the result. Like for 1245, it will add 1,2 and 4 to result, but not 5.
result is cumulative and include previous sums.
try:
number = input()
#sumed_up_digits = sum
sum = 0
while len(number) != 1:
result = 0
for i in number:
int_i = int(i)
result = result + int_i
sum = sum + result
number = str(result)
print(sum)
You can do it like this:
number = input()
if len(number) <= 1:
print(0)
while len(number) > 1:
number = str(sum(int(i) for i in number))
print(int(number))
Of course, you would need to check that the initial input number is made of digits...
the problem is number isn't being shortened so the condition for the loop to stop is never reached.
number = input()
result = 0
while len(number) != 1:
# set digit to last number
digit = int(number) % 10
result += digit
number = number[:-1]
print(result)
I'm writing a program that accepts as input a 9 digit number with each number from 1-9 (i.e 459876231) The program takes that number and then finds the next highest number with the same digits. The code I have works, but only when I put the print statement within the for loop.
n = int(input("Please input a 9 digit number"))
n_str = str(n)
n_str1 = str(n+1)
while n < 1000000000:
for char in n_str:
if not char in n_str1:
n += 1
n_str1 = str(n)
print(n)
If I put don't indent the print statement to where it is now, the program will not work. Putting the print statement here also displays every number that the program tries on the way to the correct number, and I only want to display the final answer. Why is this happening? I've tried storing n in a completely new variable and then trying to print outside the loop but get the same thing.
It's because if you do n += 1, n will be 1, then 2, 3.., so you need to print n every time. If you print n outside of the for, it will only print its last value.
Your code is fixed like:
n = int(input("Please input a 9 digit number: "))
n_str = str(n)
n_str1 = str(n+1)
while n < 1000000000:
found = True
for char in n_str:
if not char in n_str1:
n += 1
n_str1 = str(n)
found = False
break
if found:
print(n)
break
There is a bug in your condition
for char in n_str:
if not char in n_str1:
If input number is 333222323, n_str1 is 333222324, digit check char in n_str1 would be all true and 333222323 would be the result.
I find the LeetCode problem 31. Next Permutation is quite similar to your question, and there are already many recommended solutions, most are more efficient than yours.
This example code is based on my LeetCode answer:
nstr = input("Please input a 9 digit number: ")
nums = [int(c) for c in nstr]
l = len(nums) # length should be 9
for i in range(l-2, -1, -1):
swap_idx, swap_n = None, None
for j in range(i+1, l):
if (nums[i] < nums[j]) and (not swap_n or (nums[j] < swap_n)):
swap_idx, swap_n = j, nums[j]
if swap_idx:
tmp = nums[i]
nums[i] = nums[swap_idx]
nums[swap_idx] = tmp
break
nums = nums[:i+1] + sorted(nums[i+1:])
print(''.join([str(i) for i in nums]))
With a test:
Please input a 9 digit number: 459876231
459876312
Please input a 9 digit number: 333222323
333222332
I'm a beginner in python and I just wrote a program to find 2 digit happy numbers. we should give it a 2 digit number and then if it's a happy number it should print that it's a happy number and if it's not it should loop endlessly in a cycle which does not include 1.
this is my code :
input_number = int(input("Please Enter a positive 2 digits number\n"))
digits = [int(i) for i in str(input_number)]
while input_number != 1:
for i in range(len(digits)):
sum_of_squares = digits[i]**2 + digits[i-1]**2
input_number = sum_of_squares
print(input_number)
if input_number == 1:
print("Happy ;)")
break
my problem is that my program never leaves the loop, for example 49 is a happy number, but when i enter it, it prints 97 endlessly.
what's wrong with my code?
A slight variation to #joyal-mathew 's answer. This would work for any number of digits
input_number = int(input("Please Enter a positive number\n"))
while input_number != 1:
digits = [int(i) for i in str(input_number)]
digit_squares = [i*i for i in digits]
sum_of_squares = sum(digit_squares)
input_number = sum_of_squares
print(input_number)
iter_count+=1
if input_number == 1:
print("Happy ;)")
break
Inside the loop you need to change the value of digits. Also since it's for 2 digit numbers you can just use list indices of 0 and 1.
input_number = input()
digits = [int(i) for i in input_number]
while input_number != 1:
sum_of_squares = digits[0]**2 + digits[1]**2
digits = [int(i) for i in str(sum_of_squares)]
input_number = sum_of_squares
print(input_number)
if input_number == 1:
print("Happy ;)")
break
A recursive and verbose solution:
def is_happy(int_tc, seen = None):
"""checks if the number is a happy number"""
if seen is None:
seen = [int_tc]
sum_squares = sum_of_squares_of_all_digits(seen[-1])
if sum_squares == 1:
return True
elif sum_squares in seen: # check if the numbers are repeating infinitely
return False
else:
seen.append(sum_squares)
return is_happy(int_tc, seen)
def sum_of_squares_of_all_digits(number):
"""return sum of square of all digits"""
return sum([digit ** 2 for digit in get_all_digits(number)])
def get_all_digits(number):
"""gets all the digits from the number right to left one bye one(yield)"""
while(number > 0):
yield number % 10
number = (number - number % 10) / 10
I'm trying to write a program in python that can either print 1 through nth numbers of the prime number sequence, or print just the nth number of the prime number sequence. Here is the code.
import math
P = 2
X = raw_input('Choose a number: ')
Y = 1
def prime(P, Y):
Choice = raw_input('Select 1 to print X numbers of the Prime sequence. \nSelect 2 to print the Xth number in the Prime sequence. \nWhat is your choice: ')
if Choice == "1":
while Y <= int(X):
isprime = True
for x in range(2, int(P) - 1):
if P % x == 0:
isprime = False
break
if isprime:
print P
Y += 1
P += 1
elif Choice == "2":
prime(P, Y)
Basically, i have the first part down, so that it prints 1 through nth numbers of the prime sequence. However, I'm quite lost on how to make it calculate just the nth prime, where the nth prime is the given through raw input. It must be possible to do this in python, however, how would it be done, and what would be the best way to do so, without having to add too many new variables that i don't have here, (though i would be fine doing so). Help would be appreciated.
Add a condition so that if either the user wants to print all numbers, or you have reached the final prime number of the sequence, the number will be printed. (I have also replaced some of the variable names with more descriptive ones, and altered it so that the function is passed the number_of_primes as its only parameter, which would seem to make more sense.)
def print_primes(X):
choice = raw_input('Select 1 to print X numbers of the Prime sequence. \nSelect 2 to print the Xth number in the Prime sequence. \nWhat is your choice: ')
count = 1
n = 2
while count <= X:
is_prime = True
for i in range(2, int(n) - 1):
if n % i == 0:
is_prime = False
break
if is_prime:
if choice == "1" or count == X:
print n
count += 1
n += 1
number_of_primes = int(raw_input('Choose a number: '))
print_primes(number_of_primes)
Just only print if it's the Yth number:
if isprime:
Y += 1
if Y == X:
print P