I am working on the Euler problems and found this code online for the third problem.
I used Python 3 to solve the third and fourth problems.
def lpf(c): # largest_prime_factor
i = 2
while i * i <= c:
if c % i:
i += 1
else:
c //= i # c // i returns the integer quotient of c/i
return c
I know that the // returns the integer quotient of a division, but what is happening when an equal sign is put just after it?
c //= i --> Is the integer quotient of c/i affected to the variable c?
Also, I am working on palindromes for problem 4 and I found this operator ::.
For example, here is code using it:
> s = str(12321)
> print(s == s[::-1])
Output : True
(If the number is a palindrome, then output is True, else the output is False.)
Is the operator :: reading the string and changing it with an option? If so, how do you use it?
If you read an operator like ??= with ?? a special operator, that usually (not always), can be replaced by:
c ??= e
into:
c = c ?? e
So the operation is done inplace. So here you have written:
c = c // i # equivalent to c //= i
Note that sometimes inplace operations differ from their non-inplace counterparts. For instance for a list la += lb is not equal to la = la + lb. Since numerical values are immutable however, there is not much we can optimize here, so for numbers the above will (probably) always hold.
Related
Suppose a, b, c, and d hold floating point numbers. Suppose it must hold that a <= b and c <= d. Given these constraints I am trying to find all of the possible orderings using only <, and =. For example a < c = b < d is one possible ordering. b < c < a < d is not, due to the constraint that a <= b.
If you only allow < or = as operators, then the valid expressions will have the following properties
as the constraints only use ≤, whether the expressions use < or = does not matter
the constraints mean a must be before b and c must be before d
You can either generate all permutations and prune those which don't have a before b and c before d in them out, or you can generate based on those constraints, by deducing:
the first variable must be a or c
the second variable can either be the second variable in the constraint of the first, or other option for first
if the second is the same constraint as the first, then the other two must be the other two in order ( [a b c d] or [c d a b] )
if the variables for the constraints are interleaved, the third and forth can be in either order
That should give:
a∙b∙c∙d
a∙c∙b∙d
a∙c∙d∙b
c∙d∙a∙b
c∙a∙d∙b
c∙a∙b∙d
where ∙ can be either < or = in any of the positions.
If you also allow > as an operator, you get some which are always valid and some which can be either valid or not.
a∙b>c∙d
c∙d>a∙b
are valid as the > order doesn't occur between any of the variables that are paired in the constraints. I think any other cases with > it breaks the transitivity so you can't know whether the result obeys the constraints or not.
from itertools import zip_longest
def interleave_strings(a,b):
return ''.join(''.join(x) for x in zip_longest(a, b, fillvalue=''))
VARIABLE_ORDERINGS = ['abcd','acbd','cdab','cadb','cabd']
OPERATOR_COMBINATIONS = ['<<<','=<<','<=<','<<=','<==','=<=','==<','===']
for vars in VARIABLE_ORDERINGS:
for ops in OPERATOR_COMBINATIONS:
# only include a=b not b=a to elide equivalent expressions
if ops[0] == '=' and vars[0] > vars[1]: continue
if ops[1] == '=' and vars[1] > vars[2]: continue
if ops[2] == '=' and vars[2] > vars[3]: continue
print(interleave_strings(vars, ops))
"""karatsuba algo"""
def fast(x,y):
if len(str(x))==1 or len(str(y))==1:
return x*y
else:
n = max(len(str(x)),len(str(y)))
m = n//2
a = x//10**m
b = x%10**m
c = y//10**m
d = y%10**m
k = fast(a,c)
n = fast((a+b),(c+d))
o = fast(b,d)
return (10**2*m*k) +(10**m*(n-k-o))+(o)
print(fast(10515610,5651551460))
python shouldn't have any overflow problem. Then why it's returning minus answer when the input is big ?
Looking at the original algorithm, your code should be
return (10**(2*m)*k) +(10**m*(n-k-o))+(o)
Look at the additional parenthesis around (2*m). Otherwise you're multiplying by m instead of raising to the power.
You could probably make it all more readable and efficient by replacing all the 10**m bits with a new variable
I checked this and found that problem is not in Python overflow. Your value of o in last iteration is way to large in comparison to k or n.
Both k and n got the value 6 while o contains 17487400. So n-k-o caused negative result.
I'm trying to make a function that takes in a number in base 10 and can be changed to any base from 2 though 9. I'm trying to only use the math module and just some simple math.
My code involves strings and I would like to eliminate them, and instead have the function do some math instead of using the numbers in a string. Also I'm trying to make the output integers.
def conver(n,b):
digits = ('0123456789')
ans = ""
while n > 0:
ans = digits[n%b] + ans
n //= b
return ans
For example the user could in put in the values (14,2) and get the output 1110
a simple implementation which can "convert" up to base 9 is as follows:
def conver(n,b):
a = 0
i = 0
while n:
n,r = divmod(n,b)
a += 10**i * r
i += 1
return a
note that n,r = divmod(n,b) could be r = n % b; n //= b
Note that the number you're getting is an integer all right (as a type), but it makes no sense using it as such because the base is wrong: Ex: 1110 is not really 1110. So it's not really different than a string...
Well, that's just for the sake of the exercise.
Is it possible to make the result from len(factors) be assigned as a variable? What I have so far is h = int(len(factors)), however i'm not sure if this actually does anything. My code below is attempting to take an integer 'r' and represent 'r' in the form (2^k)*t+1. This part of the code below is dealing with finding this product of powers of two and some other odd integer (2^k)*t.
It could be that I am going about this the wrong way, but from my research and trial and error, I have finally got this to work so far. But now more issues arise when extracting certain values.
from math import *
def executeproth():
r = input("Number to test:")
n = int(r)-1
d = 2
factors = []
while n % 2 == 0:
factors.append(d)
n = int(n/d)
h = int(len(factors))
print(n, factors, h)
# k = eval(2**h)
return factors
executeproth()
For example an input of 29 yields the following:
Number to test:29
14 [2] 1
7 [2, 2] 2
So in this instance, t=7, k=2, so we would have 29=(2^2)*7+1.
What I want to do is now take the third lines values, namely the '2', and use this for further calculations. But the commented out line # k = eval(2**h) throws the error as follows:
TypeError: eval() arg 1 must be a string, bytes or code object
So from what I can understand, the thing I am trying to evaluate is not in the correct form. I also wonder if the problem arises due to the nature of the while loop that keeps feeding values back in and creating multiples lists, as shown, and hence multiple values of h len(factors).
How would one print only the results of the 'final' iteration in the while loop? i.e. 7 [2,2] 2
Here this should fulfil your requirement,I don't think you really need to evaluate k.
Also this addresses the second part of your question too, to print the final result of the loop.
And it is as Gregory pointed out that convert explicitly to int only when needed and eval is for strings, your expression was already in integer terms.
def executeproth():
r = input("Number to test:")
n = int(r) - 1
d = 2
factors = []
while n % 2 == 0:
factors.append(d)
n = n // d
h = len(factors)
#print(n, factors, h)
else:
print"{} = ( 2 ^ {} ) * {} + 1".format(r,h,n)
return factors
executeproth()
First of all, you don't need to explicitly convert a value to an int just to use it in an expression in general. You do need it when processing the input since input() returns a string.
It is more idiomatic to use integer division a // b instead of int(a/b) in python 3.
Finally, eval is for evaluating strings, not expressions. Expressions are always evaluated.
from math import *
def executeproth():
r = input("Number to test:")
n = int(r)-1
d = 2
factors = []
while n % 2 == 0:
factors.append(d)
n = n // d
h = len(factors)
print(n, factors, h)
k = 2**h
# does the same thing but is less efficient
# k = eval("2**h")
return factors
executeproth()
As others have said you don't need eval here. In fact, you should generally avoid using eval since it can be dangerous. And in most situations where you do need to evaluate an expression in string form you can generally get by with the much safer ast.literal_eval. However, at this stage of your learning it's unlikely that you will encounter many situations where you need to work with such advanced features of the language.
Anyway, here are a few more improvements to your code.
You don't need to import the math module since you aren't using any of the functions or constants defined in it. But when you do need to import a module it's best to avoid the from module_name import * form since that pollutes your namespace with all of the names defined in the module.
You don't need to store those 2s in a list - just count them.
It's better to do your input (and input validation) in the outer layers of your program rather than doing it deep in the functions that perform your calculations.
Python provides various augmented assignment operators that you can use when you want to perform a simple operation on a value and store the result back under the original name. Eg count += 1 adds 1 to count, saving the result in count.
Python allows you to return multiple objects as a tuple, so you can return the final value of n and the count of the number of factors of 2 that you've found.
def executeproth(r):
n = r - 1
count = 0
if r != 0:
while n % 2 == 0:
count += 1
n //= 2
return n, count
r = int(input("Number to test: "))
n, count = executeproth(r)
k = 2 ** count
print("{0} = {1} * 2 ** {2} + 1".format(r, n, count))
#v = n*k + 1
#if v != r:
# print("Error!")
The if r != 0: prevents infinite looping if r is zero.
I've also added a (commented-out) test at the end. It's a good idea to do simple tests like that to make sure we're getting what we expect. Writing useful tests is an important part of program development.
Typical output:
Number to test: 0
0 = -1 * 2 ** 0 + 1
Number to test: 29
29 = 7 * 2 ** 2 + 1
Number to test: 57
57 = 7 * 2 ** 3 + 1
This is a follow-up to my question yesterday:
CMS kindly provided this example of using bitwise operators to add two numbers in C:
#include<stdio.h>
int add(int x, int y) {
int a, b;
do {
a = x & y;
b = x ^ y;
x = a << 1;
y = b;
} while (a);
return b;
}
int main( void ){
printf( "6 + 3 = %d", add(6,3));
printf( "6 - 3 = %d", add(6,-3));
return 0;
}
It works great and I then ported it to Python as follows:
def add(x, y):
while True:
a = x & y
b = x ^ y
x = a << 1
y = b
if a == 0:
break
return b
print "6 + 3 = %d" % add(6,3)
print "6 - 3 = %d" % add(6,-3)
They both work for addition and the C program works for subtraction as well. However, the Python program enters an infinite loop for subtraction. I am trying to get to the bottom of this and have posted the program here for further experimentation: http://codepad.org/pb8IuLnY
Can anyone advise why there would be a difference between the way C handles this and the way CPython handles this?
As I pointed out in my response to CMS' answer yesterday, left-shifting a negative number is undefined behavior in C so this isn't even guaranteed to work in C (the problem is how to handle the signed bit, do you shift it like a value bit or is it not affected by a shift? The standards committee couldn't agree on a behavior so it was left undefined).
When this happens to work in C it relies on fixed bit-width integers so that the leftmost bit gets pushed off the end when you do a shift (it also requires the sign bit to be treated as a value bit for shifting purposes). All integer types in C are fixed-bit but Python numbers can be arbitrarily large. Left-shifting a number in Python just causes it to keep getting larger:
>>> 1 << 100
1267650600228229401496703205376L
You could try something like this:
x = (a << 1) & 0xffffffff
To limit the result to 32-bits, the problem is that the left shift operator in Python doesn't shift the sign bit of a signed number (which is part of what is required to make this particular solution work). There might be a way to change the behavior of the shift operator but I don't know how.
Shifting negative numbers doesn't have consistent interpretation between python and C.
if i, j are two integers:
addition:
printf("%d",(i^j)|((i&j)<<1));
I've noticed that you're assuming that python works with numbers the same way as C does.
Thats not entirely true. Meaning C's int numbers have a fixed length of 16 bits. For detailed info on C datatypes you can refer to C_data_types on en.wikipedia.org
Python, on the other hand, is said to have a virtually infinite length for int numbers.
Adding positive integers may work the same way. But subtracting or adding negative integers shouldn't be a simple mapping translation.
An easy way to understand this is a little example on negative numbers:
Imagine a fixed length integer representation of 3 bits:
#Unsigned#
000 : 0
001 : 1
010 : 2
011 : 3
100 : 4
101 : 5
110 : 6
111 : 7
#Signed:#
000 : 0
001 : 1
010 : 2
011 : 3
100 : -4
101 : -3
110 : -2
111 : -1
This works cool because you can see that 1-3=1+(-3), -3 is 101 that's 5 if unsigned. So 1+5=6, 6 : 110 : -2. This means that 1-3=-2.
it also becomes buggy when overflowing:
-4 + -1 = 3 not -5 because it's out of range!
3 + 1 = -4 not 4 because it's out of range!
As you may see this works for fixed length but it doesn't work this way in Python.
For anyone are still interested, to resolve issue in python, just add a new case and switch the order of x and y inside the function, and return the negative value, though this put "-" in the function, but this presented a way using bit-wise operator. For anyone still wish to argue using operator "-" in the following question, I could argue that for the case of 2 - 6, the right answer is -4 where "-" exists in the answer, so it might be okay to add it when x is smaller than y. Hope this helps.
#A substract to substract two integers using bits operators
#refer to: https://www.geeksforgeeks.org/subtract-two-numbers-without-using-arithmetic-operators/
def subtractBits(x, y):
xRAW = x
yRAW = y
if x < y:
x = y
y = xRAW
# Iterate till there
# is no carry
while (y != 0):
# borrow contains common
# set bits of y and unset
# bits of x
borrow = (~x) & y
# Subtraction of bits of x
# and y where at least one
# of the bits is not set
x = x ^ y
# Borrow is shifted by one
# so that subtracting it from
# x gives the required sum
y = borrow << 1
if xRAW < yRAW:
return -x
else:
return x
print(subtractBits(100, 50))
print(subtractBits(1, 3))
print(subtractBits(40, 0))
print(subtractBits(0, 40))
print(subtractBits(5, 5))