The program shows "OverflowError: Python int too large to convert to C ssize_t" for large integer inputs(which are mandatory to test the efficiency of the program for all the boundary cases).How do I deal with this error?
import random
import sys
sys.setrecursionlimit(10**6)
t=int(input())
N =[]
K =[]
B =[]
while 1<=t<=20 :
n,k,b= input().split()
n,k,b = [int(n), int(k),int(b)]
t=t-1
N.append(n)
K.append(k)
B.append(b)
if b >= 1 and b <= (10**5) and n >= 1 and k <= (10**18) and b <= k :
i1=0
for val in K:
n=N[i1]
k=K[i1]
b=B[i1]
i1=i1+1
print('i entered for loop')
if sum(list(range(1, k+1))) >= n:
print(' i entered if loop')
def possibilities():
p = random.sample(range(1, k+1), b)
if sum(p) == n:
for i in range(0,b):
print(p[i],end=" ")
print("\r")
else:
possibilities()
possibilities()
else:
print(-1)
as per the docs, random.randrange works
over an arbitrarily large range
so instead of doing:
p = random.sample(range(1, k+1), b)
you could do the following:
p = [random.randrange(1, k+1) for _ in range(b)]
and have it work for arbitrarily large values of k. note that when k is smaller than 2**63-1 (assuming you're using a 64bit machine) using sample is likely going to be faster.
as an example of where your code was apparently failing, random.sample(range(2**63), 1) gives
OverflowError: Python int too large to convert to C ssize_t
while [random.randrange(2**63) for _ in range(10)] gives me a list containing a single large number.
I also note that:
the distributions involved in your code would seem to allow you to give a nice analytical answer in O(t) time
you might also want to improve your checks to stop it running forever, e.g. n,k,b = [2,2,2] would seem to pass all your checks but will spin forever
using a for loop would be much more efficient than recursion given that Python isn't "tail recursive"
I have put together the following code in order to determine if a number has an odd or even number of divisors. The code works well with relatively small numbers but once a larger number like 9 digits is entered it hangs up.
def divisors(n):
num = len(set([x for x in range(1,n+1) if not divmod(n,x)[1]]))
if (num != 0 and num % 2 == 0):
return 'even'
else:
return 'odd'
what can I do to make this more efficient?
Here's your problem:
num = len(set([x for x in range(1,n+1) if not divmod(n,x)[1]]))
This constructs a list, then constructs a set out of that list, then takes the length of the set. You don't need to do any of that work (range(), or xrange() for that matter, does not produce repeated objects, so we don't need the set, and sum() works on any iterable object, so you don't need the list either). While we're on the subject, divmod(n, x)[1] is just a very elaborate way of writing n % x, and consumes a little bit of extra memory to construct a tuple (which is immediately reclaimed because you throw the tuple away). Here's the fixed version:
num = sum(1 for x in xrange(1,n+1) if not n % x)
You do not need to test every possible divisor, testing up to sqrt(n) is enough. This will make your function O(sqrt(n)) instead of O(n).
import math
def num_divisors(n):
sqrt = math.sqrt(n)
upper = int(sqrt)
num = sum(1 for x in range(1, upper + 1) if not n % x)
num *= 2
if upper == sqrt and num != 0:
num -= 1
return num
In my benchmarks using python2 this is 1000 times faster than sum(1 for x in range(1, n + 1) if not n % x) with n = int(1e6) and 10000 times faster for 1e8. For 1e9 the latter code gave me a memory error, suggesting that the whole sequence is stored in memory before doing the sum because in python 2 range() returns a list and I should be using xrange() instead. For python3 range() is fine.
I'm writing a function that, given a random int, will return the next int that is both a prime number and a palindrome. i.e getint(13) will return 101.
One of the conditions of this function is that recursion is not allowed.
Where am i going wrong here?
def golf(number):
x = number +1
for i in range(2, x):
while str(x) != str(x)[::-1] and x % i == 0:
x += 1
return x
Divide the problem into smaller pieces. It will be easier for you to understand what's going on:
def golf(number):
x = number + 1
while True:
if is_palindrome(x) and is_prime(x):
return x
x += 1
Now all you have to do is implement is_palindrome(x) and is_prime(x):
import math
def is_prime(x):
for i in xrange(2, math.ceil(math.sqrt(x))+1):
if x % i == 0:
return False
return True
def is_palindrome(x):
x = str(x)
return x == x[::-1]
Side note: the math.ceil(math.sqrt(x))+1 might be an overkill (perhaps int(...)+1 is enough) if math.sqrt works correctly for squares (i.e. does not depend on floating point calculations so math.sqrt(a*a)==a is always true). Well in worst case the loop will do one more iteration then necessary. Better safe then sorry.
Your for loop will only go as far as x's initial value: the range(2,x) is computed only once, right after x = number + 1. So increasing x inside the loop doesn't make a difference. Consider using a while loop, something like:
i = 2
while i <= x:
...
i += 1
And you should probably first check is x is a palindrome (a "cheap" operation) and then, if it is, check weather it is prime (an "expensive" operation), not try do it all in a couple of nested loops that make little sense.
In your code:
def golf(number):
x = number +1
for i in range(2, x):
while str(x) != str(x)[::-1] and x % i == 0:
x += 1
return x
The program execution will not satisfy the while loop half of the time since any even number will not be divisible by any odd number and vice-versa. Also in a single iteration of the for loop, x will be incremented every time the while loop is satisfied.
You need to separate the prime checking and palindrome checking. The approach given by freakish is the simplest.
I have a couple of problems to solve for an assignment, and am a bit stuck.
The question is to write a program that gets the user to input an odd number (check it's odd), then print an upside down pyramid of stars based on the size of the input.
For example, if you enter 5, it comes up with
*****
***
*
My problem is therefore two-fold.
1) How do I check if it's even or odd? I tried if number/2 == int in the hope that it might do something, and the internet tells me to do if number%2==0, but that doesn't work.
2) How do I change the asterisks in the middle of each line?
Any help with either problem is greatly appreciated.
Giving you the complete answer would have no point at all since this is homework, so here are a few pointers :
Even or Odd:
number % 2 == 0
definitely is a very good way to find whether your number is even.
In case you do not know %, this does modulo which is here the remainder of the division of number by 2. http://en.wikipedia.org/wiki/Modulo_operation
Printing the pyramid:
First advice: In order to print *****, you can do print "*" * 5.
Second advice: In order to center the asterisks, you need to find out how many spaces to write before the asterisks. Then you can print a bunch of spaces and asterisks with print " "*1 + "*"*3
The modulo 2 solutions with %2 is good, but that requires a division and a subtraction. Because computers use binary arithmetic, a much more efficient solution is:
# This first solution does not produce a Boolean value.
is_odd_if_zero = value & 1
# or
is_odd = (value & 1) == 1
# or
is_even = (value & 1) == 0
A few of the solutions here reference the time taken for various "is even" operations, specifically n % 2 vs n & 1, without systematically checking how this varies with the size of n, which turns out to be predictive of speed.
The short answer is that if you're using reasonably sized numbers, normally < 1e9, it doesn't make much difference. If you're using larger numbers then you probably want to be using the bitwise operator.
Here's a plot to demonstrate what's going on (with Python 3.7.3, under Linux 5.1.2):
Basically as you hit "arbitrary precision" longs things get progressively slower for modulus, while remaining constant for the bitwise op. Also, note the 10**-7 multiplier on this, i.e. I can do ~30 million (small integer) checks per second.
Here's the same plot for Python 2.7.16:
which shows the optimisation that's gone into newer versions of Python.
I've only got these versions of Python on my machine, but could rerun for other versions of there's interest. There are 51 ns between 1 and 1e100 (evenly spaced on a log scale), for each point I do the equivalent of:
timeit('n % 2', f'n={n}', number=niter)
where niter is calculated to make timeit take ~0.1 seconds, and this is repeated 5 times. The slightly awkward handling of n is to make sure we're not also benchmarking global variable lookup, which is slower than local variables. The mean of these values are used to draw the line, and the individual values are drawn as points.
Simple but yet fast:
>>> def is_odd(a):
... return bool(a - ((a>>1)<<1))
...
>>> print(is_odd(13))
True
>>> print(is_odd(12))
False
>>>
Or even simpler:
>>> def is_odd(a):
... return bool(a & 1)
1) How do I check if it's even or odd? I tried "if number/2 == int" in the hope that it might do something, and the internet tells me to do "if number%2==0", but that doesn't work.
def isEven(number):
return number % 2 == 0
if number%2==0
will tell you that it's even. So odd numbers would be the else statement there. The "%" is the mod sign which returns the remainder after dividing. So essentially we're saying if the number is divisible by two we can safely assume it's even. Otherwise it's odd (it's a perfect correlation!)
As for the asterisk placing you want to prepend the asterisks with the number of spaces correlated to the line it's on. In your example
***** line 0
*** line 1
* line 2
We'll want to space accordingly
0*****
01***
012*
la = lambda x : "even" if not x % 2 else "odd"
I guess the easiest and most basic way is this
import math
number = int (input ('Enter number: '))
if number % 2 == 0 and number != 0:
print ('Even number')
elif number == 0:
print ('Zero is neither even, nor odd.')
else:
print ('Odd number')
Just basic conditions and math. It also minds zero, which is neither even, nor odd and you give any number you want by input so it's very variable.
Regarding the printout, here's how I would do it using the Format Specification Mini Language (section: Aligning the text and specifying a width):
Once you have your length, say length = 11:
rowstring = '{{: ^{length:d}}}'.format(length = length) # center aligned, space-padded format string of length <length>
for i in xrange(length, 0, -2): # iterate from top to bottom with step size 2
print rowstring.format( '*' * i )
there are a lot of ways to check if an int value is odd or even.
I'll show you the two main ways:
number = 5
def best_way(number):
if number%2==0:
print "even"
else:
print "odd"
def binary_way(number):
if str(bin(number))[len(bin(number))-1]=='0':
print "even"
else:
print "odd"
best_way(number)
binary_way(number)
hope it helps
This is simple code. You can try it and grab the knowledge easily.
n = int(input('Enter integer : '))
if n % 2 == 3`8huhubuiiujji`:
print('digit entered is ODD')
elif n % 2 == 0 and 2 < n < 5:
print('EVEN AND in between [2,5]')
elif n % 2 == 0 and 6 < n < 20:
print('EVEN and in between [6,20]')
elif n % 2 == 0 and n > 20:
print('Even and greater than 20')
and so on...
Here's my solution:
def is_even(n):
r=n/2.0
return True if r==int(r) else False
Sample Instruction
Given an integer, n, performing the following conditional actions:
If n is odd, print Weird
If n is even and in the inclusive range of 2 to 5, print Not Weird
If n is even and in the inclusive range of 6 to 20, print Weird
If n is even and greater than 20, print Not Weird
import math
n = int(input())
if n % 2 ==1:
print("Weird")
elif n % 2==0 and n in range(2,6):
print("Not Weird")
elif n % 2 == 0 and n in range(6,21):
print("Weird")
elif n % 2==0 and n>20:
print("Not Weird")
def main():
n = float(input('odd:'))
while n % 2 == 0:
#if n % 2 == 1: No need for these lines as if it were true the while loop would not have been entered.
#break not required as the while condition will break loop
n = float(input('odd:'))
for i in range(int((n+1)/2)):
print(' '*i+'*'*int((n-2*i))+' '*i)
main()
#1st part ensures that it is an odd number that was entered.2nd part does the printing of triangular
Modulus method is the usual method. We can also do this to check if odd or even:
def f(a):
if (a//2)*2 == a:
return 'even'
else:
return 'odd'
Integer division by 2 followed by multiplication by two.
My solution basically we have two string and with the & we get the right index:
res = ["Even", "Odd"]
print(res[x & 1])
Please note that it seems slower than other alternatives:
#!/usr/bin/env python3
import math
import random
from timeit import timeit
res = ["Even", "Odd"]
def foo(x):
return res[x & 1]
def bar(x):
if x & 1:
return "Odd"
return "Even"
la = lambda x : "Even" if not x % 2 else "Odd"
iter = 10000000
time = timeit('bar(random.randint(1, 1000))', "from __main__ import bar, random", number=iter)
print(time)
time = timeit('la(random.randint(1, 1000))', "from __main__ import la, random", number=iter)
print(time)
time = timeit('foo(random.randint(1, 1000))', "from __main__ import foo, random", number=iter)
print(time)
output:
8.05739480999182
8.170479692984372
8.892275177990086
1. another odd testing function
Ok, the assignment was handed in 8+ years ago, but here is another solution based on bit shifting operations:
def isodd(i):
return(bool(i>>0&1))
testing gives:
>>> isodd(2)
False
>>> isodd(3)
True
>>> isodd(4)
False
2. Nearest Odd number alternative approach
However, instead of a code that says "give me this precise input (an integer odd number) or otherwise I won't do anything" I also like robust codes that say, "give me a number, any number, and I'll give you the nearest pyramid to that number".
In that case this function is helpful, and gives you the nearest odd (e.g. any number f such that 6<=f<8 is set to 7 and so on.)
def nearodd(f):
return int(f/2)*2+1
Example output:
nearodd(4.9)
5
nearodd(7.2)
7
nearodd(8)
9
This the function
def oddOrEven(num):
if num%2 == 0:
print("even")
else:
for i in range(num):
for j in range(i+1):
print(" ", end="")
for m in range(num-i, 0, -1):
print("* ", end="")
print()
but there is a catch because it is almost impossible to return a pattern so we have to print instead of return it then use it directly oddOrEven(5) will print:
* * * * *
* * * *
* * *
* *
*
Determining even/odd:
is_odd = num & 1
is_even = (num & 1) == 0 # slowly: bitwise and number comparison
is_even = (num & 1) is 0 # faster: bitwise and pointer comparsion
is_even = ~num & 1 # fastest: two bitwise operations
Using is is faster than the comparisons with double equals, but negation with ~ is even faster.
I'm again working on Project Euler, this time problem #4. The point of this script is to find the largest palindromic product of two three digit numbers. I thought it was fairly straightforward to solve, but I'm getting an answer that is too low. More specifically, I am getting 580085, and the answer is 906609.
Could someone tell me what about this is incorrect?
#!/usr/bin/env python
# encoding: utf-8
"""
P4.py
Created by Andrew Levenson on 2010-06-29.
Copyright (c) 2010 __MyCompanyName__. All rights reserved.
"""
import sys
import os
def main():
for x in range(100, 1000):
for y in range(100, 1000):
z = str( x * y )
s = str( z[::-1] ) # Reverse z
if z == s:
t = z
print t
if __name__ == '__main__':
main()
Your code doesn't make sure it prints the largest product, since there could later be a smaller product which replaces it. To fix it, initialize t to zero, and replace your condition with
if z==s and int(z)>t:
t = int(z)
Or equivalently,
if z==s:
t = max(t,int(z))
Edit: Fixed int/string issues above. It's a bit cleaner to avoid the conversion to string and back to int like this though:
def isPalindrome(x):
s = str(x)
return s == s[::-1]
t = 0
for x in range(100, 1000):
for y in range(100, 1000):
z = x * y
if isPalindrome(z) and z > t:
t = z
print t
Here's a tricky but correct way to do it in a single expression...:
def main():
print max(p for x in range(100, 1000) for y in range(x, 1000)
for p in (x * y,) if str(p) == str(p)[::-1])
The tricky part is the single-item for p clause which plays the role of an assignment (just to stop recomputing that product several times;-).
Note that the accepted answer is wrong (as are several others), because it looks for the string "max", which is different from the int max -- try running it, and you'll see!-)
The problem is to find the largest palindrome. You have nothing here to find the largest, simply the last. You assumed the last one would be the largest, but that isn't so because you are examining the entire ZxZ square of possibilities.
For example, you are considering 200*101 after you've considered 101*999.
Because of the way you're using the 2 for loops you're going to get the number with the largest x value, not the largest product.
906609 = 993 * 913
Then x keeps incrementing and the next palindrome is:
580085 = 995 * 583
You need a variable to keep track of the largest palindrome you've found.
def main():
largest = 0
for x in range(100, 1000):
for y in range(100, 1000):
z = str( x * y )
s = str( z[::-1] ) # Reverse z
if z == s:
t = int(z)
if t > largest:
largest = t
print largest
You need to add a check if the one you found is larger than the one you already have.
I'll add that you can save yourself some time in this test. All 6 digit palindromes must be divisible by 11. Therefore at least one of the factors must be divisible by 11.