Palindrome number in python (leetcode) - python

class Solution:
def isPalindrome(self, x: int) -> bool:
# If x is a negative number it is not a palindrome
# If x % 10 = 0, in order for it to be a palindrome the first digit should also be 0
if x < 0 and x%10 == 0):
return False
reversedNum = 0
while x > reversedNum:
reversedNum = reversedNum * 10 + x % 10
x = x // 10
# If x is equal to reversed number then it is a palindrome
# If x has odd number of digits, dicard the middle digit before comparing with x
# Example, if x = 23132, at the end of for loop x = 23 and reversedNum = 231
# So, reversedNum/10 = 23, which is equal to x
return True if (x == reversedNum or x == reversedNum // 10) else False
This is my code which is giving wrong output for 660,
Expected output : False
My output : True
Can someone tell me how to correct this.

reversedNum = 0
Num=x
while x > 0:
reversedNum = reversedNum * 10 + x % 10
x = x // 10
return True if (Num == reversedNum) else False

You don't really need an explicit check for a negative number because the while loop (in the following code) will not be entered and the return value will be an equality test between zero and some negative number - which is obviously False.
So:
def ispalindrome(x):
n = x
r = 0
while n > 0:
r *= 10
r += n % 10
n //= 10
return r == x

if you convert the number to a string is very simple. you only need to check that the string written backwards is the same
def ispalindrome(x):
return str(x) == str(x)[::-1]
ispalindrome(23132)
>>> True

Related

Palindrome tester gives False for 11 but returns True for 121

Here is my code:
def isPalindrome(x):
if x < 0 or (x % 10 == 0 and x != 0):
return False
rev = 0
while x > rev:
rev = (rev*10 + x % 10)
x /= 10
return x == rev or x == rev/10
x = 11
print(isPalindrome(x))
Why does this code not give the desired results for all positive integer inputs?
Your code has two problems.
The first is that x /= 10 performs a floating point divide, so 11 /= 10 is 1.1, not 1. Integer divide in Python is //.
The second is that you don't want to keep looping while x > rev but rather while x > 0 because you want to reverse every digit of your number. When x > 0, you still have digits in x that you haven't added to the reversed value. The accumulated portion of the reversed value being greater than the part of the answer still to be processed doesn't mean anything.
So here's a working version of your code, at least for your two test cases and a few more I did. I didn't do an exhaustive test.
def isPalindrome(x):
if x < 0 or (x % 10 == 0 and x != 0):
return False
rev = 0
y = x
while y > 0:
rev = (rev*10 + y % 10)
y //= 10
return x == rev or x == rev/10

Function to evaluate validity of numerical palindrome for floating point numbers using Python

So there are plenty of algorithms to evaluate whether an int is a palindrome, i.e.
def ReverseNumber(n, partial=0):
if n == 0:
return partial
return ReverseNumber(n // 10, partial * 10 + n % 10)
or this one:
def isPalindrome(x):
if (x < 0):
return False
div = 1
while (x / div >= 10):
div *= 10
while (x != 0):
l = x / div
r = x % 10
if (l != r):
return False
x = (x % div) / 10
div /= 100
return True
However what I'd like to do is assess whether a number such as 1.01 or 22.22 and so on, whether such numbers are themselves palindromes.
How could either of those algorithms above be adapted to function for floats in addition to ints?
This is the code I'm using to call it:
import sys
# This method determines whether or not the number is a Palindrome
def isPalindrome(x):
x = str(x).replace('.','')
a, z = 0, len(x) - 1
while a < z:
if x[a] != x[z]:
return False
a += 1
z -= 1
return True
if '__main__' == __name__:
trial = int(sys.argv[1])
# check whether we have a Palindrome
if isPalindrome(trial):
print("It's a Palindrome!")
The simplest thing to do is just convert the number to a string, then compare characters from the ends to the middle. The string conversion is less expensive than repeated multiplications and divisions.
def isPalindrome(x):
x = str(x).replace('.','')
a, z = 0, len(x) - 1
while a < z:
if x[a] != x[z]:
return False
a += 1
z -= 1
return True

lucky sevens, sum of 3 consecutive numbers in array == 7

Write a function lucky_sevens(numbers), which takes in an array of
integers and returns true if any three consecutive elements sum to 7.
Why isn't this producing an output of True? The last 3 values sum = 7.
def lucky_sevens(numbers):
x, y = 0, 3
sum_of_numbers = sum(numbers[x:y])
while (sum_of_numbers != 7) and (y < len(numbers)):
x = x + 1
y = y + 1
if sum_of_numbers == 7:
return True
else:
return False
print(lucky_sevens([1,2,3,4,5,1,1]))
The problem that when the function first gets called the sum_of_numbers variable gets assigned the value of the sum of the first 3 values in the list, and never gets updated with the new x,y values, you'd probably want to create a callback function to achieve that behavior.
As it stands, you'll need to move the sum statement into the while loop so the sum gets updated with the new x,y values:
def lucky_sevens(numbers):
result = False
x, y = 0, 3
while (y <= len(numbers)):
if sum(numbers[x:y]) == 7:
result = True
break
x += 1
y += 1
return result
print(lucky_sevens([1,2,3,4,5,1,1]))
How about something as simple as
def lucky_sevens(numbers):
for x in range(len(numbers) - 2):
if sum(numbers[x:x+3]) == 7:
return True
return False
Or with your original code, just cleaned up a little bit.
def lucky_sevens(numbers):
if len(numbers) < 3:
return False
x, y = 0, 3
sum_of_numbers = sum(numbers[x: y])
while sum_of_numbers != 7 and y < len(numbers):
x += 1
y += 1
sum_of_numbers = sum(numbers[x: y])
if sum_of_numbers == 7:
return True
return False
Your error came in your while loop. As you were looping, sum_of_numbers was staying constant. Instead, you have to update it for every new x and y within the while loop.
Also some repetitive stuff like else: return False, can be simplified to return False, as it can only get to that line if sum_of_numbers == 7 is False.
Finally x = x + 1 can be written in the more common shorthand x += 1, the same going with y = y + 1.
This ought to do the trick:
def lucky_sevens(numbers):
if len(numbers) < 3:
return False
return 7 in [sum(numbers[i:i+3]) for i in range(0, len(numbers)-2)]
print(lucky_sevens([1,2,3,4,5,1,1]))
# True
The list comprehension will move through your list 3 numbers at a time and compute the sum of each set of three integers. If 7 is in that list, then there are 3 consecutive numbers that sum to 7. Otherwise, there isn't.
The one caveat is that doing this sort of list comprehension requires that the list have more than 3 elements in it. That's why the if statement is there.
If you wanted to use your original code though, you just have to make a few adjustments. Your logic was all there, just needs a little cleaning.
def lucky_sevens(numbers):
x, y = 0, 3
sum_of_numbers = sum(numbers[x:y])
while (sum_of_numbers != 7) and (y < len(numbers)):
x = x + 1
y = y + 1
sum_of_numbers = sum(numbers[x:y])
if sum_of_numbers == 7:
return True
else:
return False
You simply needed to redo the sum within your while loop. That way, sum_of_numbers updates with each loop and each new selection of indices.
This code returns the consecutive elements in the Array whose sum is 7 and index of initial element.
function lucky_seven(arr){
let i=0;
let lastIndex = 0;
if(arr.length < 3){
return false;
}
while(i <= lastIndex){
let sum = 0;
lastIndex = i + 3;
let subArr = arr.slice(i,lastIndex);
if(subArr.length === 3) {
sum = subArr.reduce((acc, cur) => acc + cur);
if(sum === 7){
return {
subArr: subArr,
index: i
};
}
i++;
} else{
return false;
}
}
}
lucky_seven([3,2,1,4,2])
I just used this:
def lucky_sevens(numbers):
x = 0
y = False
for i in numbers:
if i == 7:
x += 7
if x == 21:
y = True
else:
x = 0
return y
There are some very interesting responses here. Thought I will share my work as well.
def lucky_seven(num_list):
if len(num_list) < 3: return False
return any([True if sum(num_list[i:i+3]) == 7 else False for i in range(len(num_list)-2)])
print ('lucky seven for [1,2,3] is :',lucky_seven([1,2,3]))
print ('lucky seven for [3,4] is :',lucky_seven([3,4]))
print ('lucky seven for [3,4,0] is :',lucky_seven([3,4,0]))
print ('lucky seven for [1,2,3,4,5,1,1] is :',lucky_seven([1,2,3,4,5,1,1]))
print ('lucky seven for [1,2,3,4,-2,5,1] is :',lucky_seven([1,2,3,4,-2,5,1]))
The output of this will be:
lucky seven for [1,2,3] is : False
lucky seven for [3,4] is : False
lucky seven for [3,4,0] is : True
lucky seven for [1,2,3,4,5,1,1] is : True
lucky seven for [1,2,3,4,-2,5,1] is : True
def f(l):
if len(l) < 3:
return False
for i in range(len(l)):
if i+3 <= len(l):
if sum(l[i:i+3]) == 7:
return True
continue
else:
return False

sum of factors of a given number

i have written this code which finds factors of a number .after thinking and trying so much i could not get the sum of the numbers I get in output.I wish to get the sum of these numbers as output recursively.here's my code:
def p(n,c):
s = 0
if c >= n:
return n
if n % c == 0:
s += c
print(s,end=',')
return p(n,c+1)
n = int(input('enter no:'))
c = 1
print(p(n,c))
Given the comments, it appears that this might be what you want:
sum([n for n in xrange(1,24) if 24 % n == 0])
To make it a bit more generic:
def sum_of_factors(x):
return sum([n for n in xrange(1,x) if x % n == 0])
EDIT: here's a recursive version:
def sum_of_factors(x, y=1):
if (y >= x):
return 0
if (x % y == 0):
return y + sum_of_factors(x, y + 1)
return sum_of_factors(x, y + 1)
>>> sum_of_factors(24)
36
Is this the output you are looking for?
Use global variable,
s = 0
def p(n,c):
global s
if c >= n:
return n
if n % c == 0:
s += c
print(s,end=',')
return p(n,c+1)
n = int(input('enter no:'))
c = 1
print(p(n,c))
Output
enter no:1,3,6,10,16,24,36,24

Collatz conjecture sequence

The Collatz conjecture
what i am trying to do:
Write a function called collatz_sequence that takes a starting integer and returns the sequence of integers, including the starting point, for that number. Return the sequence in the form of a list. Create your function so that if the user inputs any integer less than 1, it returns the empty list [].
background on collatz conjecture:
Take any natural number n. If n is even, divide it by 2 to get n / 2, if n is odd multiply it by 3 and add 1 to obtain 3n + 1. Repeat the process indefinitely. The conjecture is that no matter what number you start with, you will always eventually reach 1.
What I have so far:
def collatz_sequence(x):
seq = [x]
if x < 1:
return []
while x > 1:
if x % 2 == 0:
x= x/2
else:
x= 3*x+1
return seq
When I run this with a number less than 1 i get the empty set which is right. But when i run it with a number above 1 I only get that number i.e. collatz_sequence(6) returns [6]. I need this to return the whole sequence of numbers so 6 should return 6,3,10,5,16,8,4,2,1 in a list.
You forgot to append the x values to the seq list:
def collatz_sequence(x):
seq = [x]
if x < 1:
return []
while x > 1:
if x % 2 == 0:
x = x / 2
else:
x = 3 * x + 1
seq.append(x) # Added line
return seq
Verification:
~/tmp$ python collatz.py
[6, 3, 10, 5, 16, 8, 4, 2, 1]
def collatz_sequence(x):
seq = [x]
while seq[-1] > 1:
if x % 2 == 0:
seq.append(x/2)
else:
seq.append(3*x+1)
x = seq[-1]
return seq
Here's some code that produces what you're looking for. The check for 1 is built into while statement, and it iteratively appends to the list seq.
>>> collatz_sequence(6)
[6, 3, 10, 5, 16, 8, 4, 2, 1]
Note, this is going to be very slow for large lists of numbers. A cache won't solve the speed issue, and you won't be able to use this in a brute-force solution of the project euler problem, it will take forever (as it does every calculation, every single iteration.)
Here's another way of doing it:
while True:
x=int(input('ENTER NO.:'))
print ('----------------')
while x>0:
if x%2==0:
x = x/2
elif x>1:
x = 3*x + 1
else:
break
print (x)
This will ask the user for a number again and again to be put in it until he quits
def collatz(x):
while x !=1:
print(int(x))
if x%2 == 0:
x = x/2
else:
x = 3*x+1
this is what i propose..
seq = []
x = (int(input("Add number:")))
if (x != 1):
print ("Number can't be 1")
while x > 1:
if x % 2 == 0:
x=x/2
else:
x = 3 * x + 1
seq.append (x)
print seq
This gives all the steps of a single number. It has worked with a 50-digit number in 0,3 second.
collatz = []
def collatz_sequence(x):
while x != 1:
if x % 2 == 0:
x /= 2
else:
x = (3*x + 1)/2
collatz.append(int(x))
print(collatz)
collatz_sequence()
Recursion:
def collatz(n):
if n == 1: return [n]
elif n % 2 == 0: return [n] + collatz(int(n/2))
else: return [n] + collatz(n*3+1)
print(collatz(27))
steps=0
c0 = int(input("enter the value of c0="))
while c0>1:
if c0 % 2 ==0 :
c0 = c0/2
print(int(c0))
steps +=1
else:
c0 = (3 * c0) + 1
print(int(c0))
steps +=1
print("steps= ", steps)
import numpy as np
from matplotlib.pyplot import step, xlim, ylim, show
def collatz_sequence(N):
seq = [N]
m = 0
maxN = 0
while seq[-1] > 1:
if N % 2 == 0:
k = N//2
seq.append(N//2)
if k > maxN:
maxN = k
else:
k = 3*N+1
seq.append(3*N+1)
if k > maxN:
maxN = k
N = seq[-1]
m = m + 1
print(seq)
x = np.arange(0, m+1)
y = np.array(seq)
xlim(0, m+1)
ylim(0, maxN*1.1)
step(x, y)
show()
def collatz_exec():
print('Enter an Integer')
N = int(input())
collatz_sequence(N)
This is how you can use it:
>>> from collatz_sequence import *
>>> collatz_exec()
Enter an Integer
21
[21, 64, 32, 16, 8, 4, 2, 1]
And a plot that shows the sequence:
seq = []
def collatz_sequence(x):
global seq
seq.append(x)
if x == 1:
return
if (x % 2) == 0:
collatz_sequence(x / 2)
else:
collatz_sequence((x * 3) + 1)
collatz_sequence(217)
print seq
def collataz(number):
while number > 1:
if number % 2 == 0 :
number = number //2
print(number)
elif number % 2 ==1 :
number = 3 * number + 1
print(number)
if number == 1 :
break
print('enter any number...!')
number=int(input())
collataz(number)

Categories