Python - Simple expression to find greatest odd number below n - python

As the title already states I'm searching for a simple expression to find the greatest odd number below some n:
I want to inline this code into an arithmetic expression and don't want to use the ternary operator. Is there an arithmetic way to find this odd number?

How about this where testNumber is your variable
(testNumber - 1 >> 1 << 1) | 1 # LESS THAN OR EQUAL TO
(testNumber - 2 >> 1 << 1) | 1 # LESS THAN

The following is a purely arithmetic solution:
def greatest_odd_number_below(n): return (n//2)*2 - 1
EDIT 1: For floating point inputs:
# python 2 solution
from math import ceil
def greatest_odd_number_below_floats(n): return (int(ceil(n))//2)*2 - 1
EDIT 2: As #PM 2Ring pointed out in the comments, math.ceil returns an int in python 3, so you can remove the additional casting to int.
# python 3 solution
from math import ceil
def greatest_odd_number_below_floats(n): return (ceil(n)//2)*2 - 1

Another way:
n - n%2 - 1
Demo:
>>> for n in range(10):
print(n, '->', n - n%2 - 1)
0 -> -1
1 -> -1
2 -> 1
3 -> 1
4 -> 3
5 -> 3
6 -> 5
7 -> 5
8 -> 7
9 -> 7

babygameOver is right. There is no such built-in function, so you should implement it by yourself.
Just to put my 2 cents, you can use lambda expressions. Looks pretty simple.
>>> odd = lambda n: n-1 if n % 2 == 1 else n - 1
>>> odd(3)
3
>>> odd(744)
743

Without conditional you can't solve the scenario.
but you can do this way as you have done in yours.
def odd(n):
if n%2==0:
return n-1
return n
print(odd(3))
Hope this helps

Related

Precise math.log(x, 2) in Python

In python, I need to get the rounded down logarithm of positive integers for base 2, including big numbers.
However, since floating point math is used, I might get bad results, for example:
>>> import math
>>> int(math.log(281474976710655, 2))
48
However:
>>> 2 ** 48
281474976710656
So the correct result, rounded down, should be 47.
How can I get the correct value?
In Python 3, integers have a .bit_length method, so you should use that to get your rounded down base 2 logarithm.
Here's a short demo:
m = 2 ** 1000
for n in (281474976710655, m-1, m, m+1):
a = n.bit_length() - 1
b = 2 ** a
print(a, b <= n < 2 * b)
output
47 True
999 True
1000 True
1000 True
In python 3 ints even have an efficient .bit_length() method!
>>> (281474976710655).bit_length()
48
>>> (281474976710656).bit_length()
49
In python 2, instead of using floating point math, count the number of bits:
def log2(n):
assert n >= 1
return len(bin(n)) - 3 # bin() returns a string starting with '0b'
(Edited following this comment)

calculate catalan numbers up to a billion

I'm new to python (and programming in general), I was asked in my class to calculate Catalan numbers up to a billion but the program I wrote for it is not working as intended.
from numpy import division
C=1
n=0
while C<=10000000000:
print (C)
C=(4*n+2)/(n+2)*C
n=n+1
This is what it prints
1,
1,
2,
4,
8,
24,
72,
216,
648,
1944,
5832,
17496,
52488,
157464,
472392,
1417176,
4251528,
12754584,
38263752,
114791256,
344373768,
1033121304,
3099363912,
9298091736,
As you can see from my fourth iteration onwards, I get the wrong number and I don't understand why.
EDIT:
The mathematical definition I used is not wrong! I know the Wiki has another definition but this one is not wrong.
Co=1, Cn+1 = (4*n+2)/(n+2)*Cn
C=(4*n+2)/(n+2)*C
This applies the calculation in the wrong order. Because you are using integer arithmetic, (4*n+2)/(n+2) loses information if you have not already factored in C. The correct calculation is:
C=C*(4*n+2)/(n+2)
Try this:
from scipy.special import factorial
C = 1
n = 0
while C <= 10000000000:
print(C)
C = factorial(2*n, exact=True)/(factorial((n+1), exact=True)*factorial(n, exact=True))
n = n + 1
It works for me :)
This is solved using recursion:
def catalan(n):
if n <=1 :
return 1
res = 0
for i in range(n):
res += catalan(i) * catalan(n-i-1)
return res
for i in range(10000000000):
print (catalan(i))
you can read more about Catalan numbers here or here
Based on this expression for Catalan Numbers:
from math import factorial
C = 1
n = 0
while C <= 10000000000:
print(C)
C = (factorial(2 * n)) / (factorial(n + 1) * factorial(n))
n = n + 1
Returns:
1
1.0
1.0
2.0
5.0
14.0
42.0
132.0
429.0
1430.0
4862.0
16796.0
58786.0
208012.0
742900.0
2674440.0
9694845.0
35357670.0
129644790.0
477638700.0
1767263190.0
6564120420.0
The problem
Your mathematical definition of Catalan numbers is incorrect when translated into code.
This is because of operator precedence in programming languages such as Python.
Multiplication and division both have the same precedence, so they are computed left to right. What happens is that the division operation (4*n+2)/(n+2) happens before the multiplication with C. When n is 2, 2*(2*n+2)/(n+2) becomes 10/4 which is 2 in integer arithmetic. 1*C which is 2 at this stage, gives 4 instead of giving the expected 5.
Once a number in the series is incorrect, being computed iteratively is incorrect.
A possible work around
Here's the definition Catalan Numbers
Which means, the nth Catalan number is given by:
import operator as op
def ncr(n, r):
r = min(r, n-r)
if r == 0: return 1
numer = reduce(op.mul, xrange(n, n-r, -1))
denom = reduce(op.mul, xrange(1, r+1))
return numer//denom
def catalan(n):
return ncr(2*n, n)/(n+1)
This is not very efficient, but it is at least correct.
The right fix
To compute the series, you can do, using the recursive formula.
N=1000000 # limit
C=1
for i in xrange(0, N+1):
print i,C
C = (2*(2*i +1)*C)/(i+2)
For the first few, it looks like this:
0 1
1 1
2 2
3 5
4 14
5 42
6 132
7 429
8 1430
9 4862
10 16796

Writing a simple function using while

A Python HOMEWORK Assignment asks me to write a function “that takes as input a positive whole number, and prints out a multiplication, table showing all the whole number multiplications up to and including the input number.”(Also using the while loop)
# This is an example of the output of the function
print_multiplication_table(3)
>>> 1 * 1 = 1
>>> 1 * 2 = 2
>>> 1 * 3 = 3
>>> 2 * 1 = 2
>>> 2 * 2 = 4
>>> 2 * 3 = 6
>>> 3 * 1 = 3
>>> 3 * 2 = 6
>>> 3 * 3 = 9
I know how to start, but don’t know what to do next. I just need some help with the algorithm. Please DO NOT WRITE THE CORRECT CODE, because I want to learn. Instead tell me the logic and reasoning.
Here is my reasoning:
The function should multiply all real numbers to the given value(n) times 1 less than n or (n-1)
The function should multiply all real numbers to n(including n) times two less than n or (n-2)
The function should multiply all real numbers to n(including n) times three less than n or (n-3) and so on... until we reach n
When the function reaches n, the function should also multiply all real numbers to n(including n) times n
The function should then stop or in the while loop "break"
Then the function has to print the results
So this is what I have so far:
def print_multiplication_table(n): # n for a number
if n >=0:
while somehting:
# The code rest of the code that I need help on
else:
return "The input is not a positive whole number.Try anohter input!"
Edit: Here's what I have after all the wonderful answers from everyone
"""
i * j = answer
i is counting from 1 to n
for each i, j is counting from 1 to n
"""
def print_multiplication_table(n): # n for a number
if n >=0:
i = 0
j = 0
while i <n:
i = i + 1
while j <i:
j = j + 1
answer = i * j
print i, " * ",j,"=",answer
else:
return "The input is not a positive whole number.Try another input!"
It's still not completely done!
For example:
print_multiplication_table(2)
# The output
>>>1 * 1 = 1
>>>2 * 2 = 4
And NOT
>>> 1 * 1 = 1
>>> 1 * 2 = 2
>>> 2 * 1 = 2
>>> 2 * 2 = 4
What am I doing wrong?
I'm a little mad about the while loop requirement, because for loops are better suited for this in Python. But learning is learning!
Let's think. Why do a While True? That will never terminate without a break statement, which I think is kind of lame. How about another condition?
What about variables? I think you might need two. One for each number you want to multiply. And make sure you add to them in the while loop.
I'm happy to add to this answer if you need more help.
Your logic is pretty good. But here's a summary of mine:
stop the loop when the product of the 2 numbers is n * n.
In the mean time, print each number and their product. If the first number isn't n, increment it. Once that's n, start incrementing the second one. (This could be done with if statements, but nested loops would be better.) If they're both n, the while block will break because the condition will be met.
As per your comment, here's a little piece of hint-y psuedocode:
while something:
while something else:
do something fun
j += 1
i += 1
where should original assignment of i and j go? What is something, something else, and something fun?
This problem is better implemented using nested loops since you have two counters. First figure out the limits (start, end values) for the two counters. Initialize your counters to lower limits at the beginning of the function, and test the upper limits in the while loops.
The first step towards being able to produce a certain output is to recognize the pattern in that output.
1 * 1 = 1
1 * 2 = 2
1 * 3 = 3
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
3 * 1 = 3
3 * 2 = 6
3 * 3 = 9
The number on the right of = should be trivial to determine, since we can calculate it by multiplying the other two numbers on each row; obtaining those is the core of the assignment. Think of the two operands of * as two counters, let's call them i and j. We can see that i is counting from 1 to 3, but for each i, j is counting from 1 to 3 (resulting in a total of 9 rows; more generally there will be n2 rows). Therefore, you might try using nested loops, one to loop i (from 1 to n) and another to loop j (from 1 to n) for each i. On each iteration of the nested loop, you can print the string containing i, j and i*j in the desired format.

Exercise on Summing Digits | What's with n // = 10 [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the reason for having ‘//’ in Python?
While trying to do an exercise on summing digits, I stumbled on this solution:
def sum_digits(n):
import math
total = 0
for i in range(int(math.log10(n)) + 1):
total += n % 10
n //= 10
return total
My question is, what does the second to last line do? How is that proper syntax?
That implements what is called floor division. Floor division (indicated by // here) truncates the decimal and returns the integer result, while 'normal' division returns the answer you may 'expect' (with decimals). In Python 3.x, a greater distinction was made between the two, meaning that the two operators return different results. Here is an example using Python 3:
>>> 10 / 3
3.3333333333333335
>>> 10 // 3
3
Prior to Python 3.x, there is no difference between the two, unless you use the special built-in from __future__ import division, which then makes the division operators perform as they would in Python 3.x (this is using Python 2.6.5):
In [1]: 10 / 3
Out[1]: 3
In [2]: 10 // 3
Out[2]: 3
In [3]: from __future__ import division
In [4]: 10 / 3
Out[4]: 3.3333333333333335
In [5]: 10 // 3
Out[5]: 3
Therefore when you see something like n //= 10, it is using the same +=/-=/*=/etc syntax that you may have seen, where it takes the current value of n and performs the operation before the equal sign with the following variable as the second argument, returning the result into n. For example:
In [6]: n = 50
In [7]: n += 10
In [8]: n
Out[8]: 60
In [9]: n -= 20
In [10]: n
Out[10]: 40
In [11]: n //= 10
In [12]: n
Out[12]: 4
// is the floor division operator. It always truncates the return value to the largest integer smaller than or equal to the answer.
The second to last line is a combination of operators, in a way, including an uncommon one, which is why it's a little confusing.
Let's piece it apart.
First, // in Python is floor division, which basically is division rounded down to the nearest whole number. Thus,
>>> 16//5
3
>>> 2//1
2
>>> 4//3
1
>>> 2//5
0
Finally, the = is there because of a Python syntax that allows one to perform an operation on a variable, and then immediately reassign the result to the variable. You've probably seen it most commonly in +=, as:
>>> a = 5
>>> a += 7
>>> a
12
In this case, //= means "perform floor division, floor dividing the variable by the second argument, then assign the result to the original input variable." Thus:
>>> a = 10
>>> a //= 6
>>> a
1
for the assignment in Python A += B equals to A = A + B ,A *= B equals to A = A * B
same thing applies to "Floor Divide" as well , A //= B equals to A = A // B
Floor Division means return the truncated integer number
>>> 5 // 3 # 1.6
1 # 0.6 will be throw off

List comprehension in Haskell, Python and Ruby

I have started looking at the project Euler site as a way to learn Haskell, and improve my Python and Ruby. I think the Haskell and Python versions are ok, but I'm sure there must be a cleaner way for Ruby.
This is not about how can I make one language look like another one.
This is Problem 1:
Q: Add all the natural numbers below one thousand that are multiples of 3 or 5.
Haskell:
sum [ x | x <- [1..999], mod x 3 == 0 || mod x 5 == 0 ]
Python:
sum ( [ x for x in range(1,1000) if x % 3 == 0 or x % 5 == 0 ] )
Ruby:
(1..999) . map {|x| x if x % 3 == 0 || x % 5 == 0 } . compact . inject(:+)
They all give the same answer.
OK, so Python can become:
sum ( x for x in range(1,1000) if x % 3 == 0 or x % 5 == 0 )
it is now a generator (a good thing as we are not storing the list)
but even more fun is:
sum( set(range(0,1000,3)) | set(range(0,1000,5)) )
For some reason I was looking at this again and tried a summation approach which should be constant time. In Python 3:
def step_sum(mn,mx,step):
amax = mx - (mx - mn) % step
return (mn + amax) * ((1 + ((amax - mn) / step)) / 2)
step_sum(3,999,3) + step_sum(5,999,5) - step_sum(15,999,15)
Ruby can become:
(1..999) . select {|x| x % 3 == 0 || x % 5 == 0} . inject(:+)
or
(1..999) . select {|x| x % 3 == 0 or x % 5 == 0} . reduce(:+)
I am presuming as unlike map, select doesn't produce 'nul' and therefore there is no need to call compact. nice.
Haskell can also be:
let ƒ n = sum [0,n..999] in ƒ 3 + ƒ 5 - ƒ 15
or to be clearer:
let ƒ n = sum [ 0 , n .. 999 ] in ƒ 3 + ƒ 5 - ƒ (lcm 3 5)
as a function that lets us provide the two numbers ourselves:
ƒ :: (Integral a) => a -> a -> a
ƒ x y = let ƒ n = sum [0,n..999] in ƒ x + ƒ y - ƒ (lcm x y)
For Haskell I like
let s n = sum [0,n..999] in s 3 + s 5 - s 15
or
sum $ filter ((>1).(gcd 15)) [0..999]
For fun the Rube-Goldberg version:
import Data.Bits
sum $ zipWith (*) [1..999] $ zipWith (.|.) (cycle [0,0,1]) (cycle [0,0,0,0,1])
Okay, explanation time.
The first version defines a little function s that sums up all multiples of n up to 999. If we sum all multiples of 3 and all multiples of 5, we included all multiples of 15 twice (once in every list), hence we need to subtract them one time.
The second version uses the fact that 3 and 5 are primes. If a number contains one or both of the factors 3 and 5, the gcd of this number and 15 will be 3, 5 or 15, so in every case the gcd will be bigger than one. For other numbers without a common factor with 15 the gcd becomes 1. This is a nice trick to test both conditions in one step. But be careful, it won't work for arbitrary numbers, e.g. when we had 4 and 9, the test gdc x 36 > 1 won't work, as gcd 6 36 == 6, but neither mod 6 4 == 0 nor mod 6 9 == 0.
The third version is quite funny. cycle repeats a list over and over. cycle [0,0,1] codes the "divisibility pattern" for 3, and cycle [0,0,0,0,1] does the same for 5. Then we "or" both lists together using zipWith, which gives us [0,0,1,0,1,1,0,0,1,1,0,1...]. Now we use zipWith again to multiply this with the actual numbers, resulting in [0,0,3,0,5,6,0,0,9,10,0,12...]. Then we just add it up.
Knowing different ways to do the same thing might be wasteful for other languages, but for Haskell it is essential. You need to spot patterns, pick up tricks and idioms, and play around a lot in order to gain the mental flexibility to use this language effectively. Challenges like the project Euler problems are a good opportunity to do so.
Try this for Ruby:
(1..999).select {|x| x % 3 == 0 or x % 5 == 0}.reduce(:+)
Or a little different approach:
(1..999).reduce(0) {|m, x| (x % 3 == 0 or x % 5 == 0) ? m+x : m }
Not a list comprehension, I know, but to solve that I would use:
3*((999/3)**2+999/3)/2+5*((999/5)**2+999/5)/2-15*((999/15)**2+999/15)/2
Faster then any list comprehension one might come up with, and works in any language ;)
Only posting to show another way of looking at the same problem using http://en.wikipedia.org/wiki/Summation.
I think the following is a better Ruby one:
(1..999).select{|x| x % 3 == 0 || x % 5 == 0}.reduce(:+)
Try something like this:
(1...1000).inject(0) do |sum, i|
if (i % 3 == 0) or (i % 5 == 0)
sum + i
else
sum
end

Categories

Resources