2^n question (it didn't work on large numbers) - python-3.x

a power of two is a number of the form 2n where n is an integer, i.e. the result of exponentiation with number two as the base and integer n as the exponent.
i want to test a power of two number.For example if i input 128 program input should be True because 128=2^7
so i wrote this code:
import math
def power_of_two(x):
if(x==0):
print ("False")
return False
else:
n = math.log2(x)
if n%1 > 0:
return False
else:
return True
but in this code if i try for example 4096 it works well but if i try larger numbers,for example 4722366482869645213702 it didn't work it output True(should be False)
how can i fix this problem??

def power_of_two(x):
return x > 0 and (x & (x-1)) == 0
Explanation.
Powers of 2 look like
10000000000000000000
After subtraction of 1 they look like
01111111111111111111
Bitwise and of these numbers is 0. For other positive numbers it's false.

A simple solution is to convert the number to its binary form, using bin then test if the first digit is a 1 and all others are 0.
def is_a_power_of_two(x):
if x == 1:
return True
b = bin(x)[2:]
return int(b[0]) == 1 and int(b[1:]) == 0
That's not very fast, but if performances are not an issue for you then it's just fine.
You can test that there are no false negatives using this:
for i in range(100):
assert is_a_power_of_two(2**i)

Related

Checking if the integer only contains odd number

I can't figure out what I'm doing wrong, but my solution seems to be not working.
Check that the given positive integer n contains only odd digits (1, 3, 5, 7 and 9) when it is written out. Return True if this is the case, and False otherwise. Note that this question is not asking whether the number n itself is odd or even. You therefore will have to look at every digit of the given number before you can proclaim that the number contains no odd digits.
My solution (for Python)
def only_odd_digits(n):
b = list(str(n))
onlyodd = [1,3,5,7,9]
for index, value in enumerate(b):
if value in onlyodd:
return True
else:
return False
Can someone help? Thanks
You can also use all to avoid the loops, and then use modulo as already suggested by alparslan mimaroğlu to avoid the lookup:
def only_odd_digits(n):
digits = map(int, str(n))
return all(dig % 2 for dig in digits)
I liked the set-based answer which got deleted now. It works when using it like this:
def only_odd_digits(n):
return set(str(n)).issubset(set("13579"))
You already created the list of integers you want to check.
You just have to check every digit if it is divisible by 2.
If any of them are you can just return False. If none of them are you can return True
def only_odd_digits(n):
digits = [int(digit) for digit in str(n)]
for digit in digits:
if digit % 2 == 0:
return False
return True
Use the following codes:
def odd(n):
return set(str(n))-set('13579')==set()

Python 3, any better/cleaner way to write these functions that use for loops?

I'm trying to write code in the most simplest and cleanest way possible. I've found a few ways to shorten and simplify my code through functions that I've never seen before or through using other methods. I'd like to expand my knowledge on writing code using various (but simple) methods, and also expand my function 'vocabulary'.
Here are the functions:
1. Perfect number:
If a number's divisors' sum is equal to the number itself, it is a perfect number. We dont count the number itself as a divisor. E.g. 6's divisors are 1, 2, 3. The sum of the divisors is 6. Therefore 6 is a perfect number.
def perfect_number(num):
if type(num) != int or num < 0:
return None
divisors = []
total = 0
for x in range(num):
if num % (x+1) == 0:
if num != x+1:
divisors += [x+1]
for x in divisors:
total += x
if total == num:
return True
return False
2. Pattern:
A function that takes a positive integer and prints a pattern as follows:
pattern(1): '#-'
pattern(2): '#-#--'
pattern(5): '#-#--#---#----#-----'
def pattern(num):
if type(num) != int or num < 0:
return None
output = ''
for x in range(num):
output += '#'+('-'*(x+1))
return output
3. Reversed Numbers:
A function that takes 2 integers. It goes through every number in the range between those 2 numbers, if one of those numbers is a palindrome (the same thing backwards e.g. 151 is a 'palindrome'), it will increase a variable by 1. That variable is then returned.
invert_number(num) returns the opposite of num as an integer.
def reversed_numbers(low, high):
output = 0
for x in range(low,high+1):
if invert_number(x) == x:
output += 1
return output
It is assumed that low is lower than high.
If I broke a rule or if this doesnt fit here, please tell me where I can post it/how I can improve. Thanks :)

Generating sequence of numbers with recursion python

The goal is to generate catalan numbers ! my code works up to n = 30 (i tried the same algorithm in JAVA and it's totally correct,but, then something strange happens with python , it gives wrong numbers back after n=30. I'm totally sure that there is an issue about rounding or maybe formats, but can't figure it out by myself!
def catalan(n):
if n < 0:
return -1
else:
if n == 0:
return 1
else:
c_n = (4*n-2)/(n+1)*catalan(n-1)
return int(c_n)
By using /(n+1) you produce a floating point number, which by its nature has a limited precision. This precision is not accurate enough for the larger numbers that appear with n > 30.
So instead, use a formula that sticks with integer numbers: first multiply and only then perform the division, an integer division:
c_n = (4*n-2)*catalan(n-1)//(n+1)
The cast to int is then also unnecessary, and you can just do:
return c_n
Side note: you don't need else when you return in the if part of the statement. So you can write:
def catalan(n):
if n < 0:
return -1
if n == 0:
return 1
return (4*n-2)*catalan(n-1)//(n+1)

How to handle negative cases for prime check in Python?

With regard to the "xrange" function - ("range" in Python3) what happens when I do a negative check inside a loop? In this case, a negative number could be regarded as an edge case, but always returns None. Any insights?
The problem is you are checking if the number is negative inside the for loop. For instance if x=-3, then you are trying to run a for loop in range(2,-1) which is None. So the for loop never runs and hence returns True.
def isprime(x):
if x<=0:
return(False)
for a in range(2,(x//2)+1):
if(x%a==0):
return(False)
return(True)
By it's elementary school definition, prime numbers are defined for positive numbers only, thus your function should return False for every negative number, for example:
def isprime(x):
if x <= 0:
return False
for a in range(2, (x//2)+1):
if x % a == 0:
return False
return True
That being said, it is possible to extend the definition (as done in some fields in math), to include negative numbers as well (for further discussion see here and here). In this case, for every negative number -n, -n is prime iff n is prime. Therefore your code could be something like:
def isprime(x):
if x <= 0: # or use any |abs| method you'd like, like numpy's
x = -x
for a in range(2, (x//2)+1):
if x % a == 0:
return False
return True

Trying to understand this simple python code

I was reading Jeff Knupp's blog and I came across this easy little script:
import math
def is_prime(n):
if n > 1:
if n == 2:
return True
if n % 2 == 0:
return False
for current in range(3, int(math.sqrt(n) + 1), 2):
if n % current == 0:
return False
return True
return False
print(is_prime(17))
(note: I added the import math at the beginning. You can see the original here:
http://www.jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/)
This is all pretty straightforward and I get the majority of it, but I'm not sure what's going on with his use of the range function. I haven't ever used it this way or seen anyone else use it this way, but then I'm a beginner. What does it mean for the range function to have three parameters, and how does this accomplish testing for primeness?
Also (and apologies if this is a stupid question), but the very last 'return False' statement. That is there so that if a number is passed to the function that is less than one (and thus not able to be prime), the function won't even waste its time evaluating that number, right?
The third is the step. It iterates through every odd number less than or equal to the square root of the input (3, 5, 7, etc.).
import math #import math module
def is_prime(n): #define is_prime function and assign variable n to its argument (n = 17 in this example).
if n > 1: #check if n (its argument) is greater than one, if so, continue; else return False (this is the last return in the function).
if n == 2: #check if n equals 2, it so return True and exit.
return True
if n % 2 == 0: #check if the remainder of n divided by two equas 0, if so, return False (is not prime) and exit.
return False
for current in range(3, int(math.sqrt(n) + 1), 2): #use range function to generate a sequence starting with value 3 up to, but not including, the truncated value of the square root of n, plus 1. Once you have this secuence give me every other number ( 3, 5, 7, etc)
if n % current == 0: #Check every value from the above secuence and if the remainder of n divided by that value is 0, return False (it's not prime)
return False
return True #if not number in the secuence divided n with a zero remainder then n is prime, return True and exit.
return False
print(is_prime(17))

Resources