division of very large integers in Python using SageMath - python

I'm implementing Wiener's Exponent Attack using Python and SageMath.
My code is as follows
from sage.all import *
# constants
b = some_very_large_number
n = some_very_large_number
b_over_n = continued_fraction(b/n)
while True:
t_over_a = b_over_n.convergent(i+1)
t = t_over_a.numerator()
a = t_over_a.denominator()
# check if t divides ab-1
if ((t != 0) and (gcd(a*b-1, t)== t)):
print("Found i: ", i)
break
i += 1
I found out that the loop would not end forever and added this line of code before the while loop.
print(b_over_n.convergent(5))
And I found that b_over_n was always returning 0 no matter what.
I also printed out type(b_over_n) and checked it was of 'long' type.
I have checked SageMath manuals but haven't found anything useful yet.
Is there something I'm doing wrong here?

It turns out I was using Python2, where int/int would return int.
Thus since b was smaller than n in my case, b/n automatically returned 0.

Related

Could someone show me a good factorial code?

I just started to study Python. I must use Python3.7.
Could someone show me a working factorial code?
i tried some i found here but i always get this error:
=================== RESTART: C:\programozás\pytutorial.py ===================
Code:
def factorial(n):
result = 1
for i in range(1, n + 1):
result *= i
return result
Your code is working, even though you could simply use the math library:
import math
print(math.factorial(5))
The problem does not come from your script, so maybe you should try to reinstall your python, and avoid paths with special characters as Adam Toth pointed out.
Update: to get the input and return a factorial as asked in comments
import math
print(math.factorial(int(input(">>"))))
The problem is most likely caused because you have a special character in the path to the .py file. So should use a folder like C:\programming, or anything without a special character, like 'á'.
It's very important to do like this, even if it does not solve your current problem, it can prevent many more in the future.
Ps.: Jó kiszúrni magyar programozót is :)
I see a related (older) thread here about this error
For the logic:
We have to consider:
Negative numbers
Zero
Positive numbers
So one way to write it will be:
def factorial(n):
if n < 0:
result = "Factorial doesn't exist for negative numbers"
elif n == 0:
result = 1
else:
result = 1
for i in range(1, n + 1):
result *= i
return result
You can try the concept of recursion as well.
To get the factorial of a number "num":
print(factorial(num))
Make sure you indent the code properly, indentation is important in python.
Hope it helps!
Python Code of Factorial Using Recursive Function:
def factorial(n):
if n <= 1:
return 1
else:
return n * factorial(n-1)
factorial(5)
Note: The First Condition will only meet when the input is 0 or 1 and in else block n will be recursively multiplying n * n - 1.

[Python]what's wrong with my recursions?

I want to performe
[√(1/2+1/2*√1/2)] ---------(P1)
[√(1/2+1/2*√(P1)] ----------(P2)
[√(1/2+1/2*√(P2)]
etc.
to find out the P(nth)term
I have this for now
from math import *
n=eval(input('fjeowijo'))
i=sqrt(1/2+1/2*(sqrt(1/2)))
def P(n):
for i in range(n):
g=sqrt(1/2+1/2*i)
i=sqrt(1/2+1/2*i)
print(g)
P(n)
When I enter 1 for n, the result is 0.7071067811865476, which is only equal to the part " sqrt(1/2) ". Why?
In case you want to make it recursive do
def P(n):
if n <= 0:
return 0.5
else:
return sqrt(0.5*(1+sqrt(P(n-1))))
which works out as
>>> P(1)
0.9238795325112867
>>> P(2)
0.9902490907008235
>>> P(3)
0.9987774031336784
>>> P(4)
0.9998471169658009
As #JoshRomRock points out, python generally limits the maximum depth of the recursion (the default max depth is platform-dependent).
In case of CPython, the default limit is 1000.
In case you want to alter such limit do:
import sys
sys.setrecursionlimit(5000)
Note: in this case, the precision offered by the floating point representation may well be the biggest hurdle to the calculation. Please see the official docs for further info on what to expect using floats.
Second note: in case the P function is going to be used several times and/or in multiple points of the code of a program, as a library function, it would make sense to implement it using Memoization.
Please see here for a few examples in python.
def P(n):
i = 0
g = sqrt(0.5+.5*sqrt(0.5)
while(i < n):
g = sqrt(0.5+0.5*g)
print(g)
Could it be what you're looking for ?

Python memory error for integer and math

When I run my code below I get Memory Error
import math
X = 600851475143
halfX = math.trunc(int(X / 2))
countFactors = 0
for i in range(halfX):
if i >0 and X % i:
countFactors += 1
print countFactors
I understand because of math calcs here but I do not know how to correct it.
I'm going to guess you're using Python 2.7 (or 2.x, at any rate).
If that's the case, you should use xrange instead of range.
In python 3.x, range creates an iterator that only uses a few bytes of memory regardless of how large it is. In python 2.x, range always creates a list containing numbers counting up (or down) over the specified range. Calling range(some_large_number) can cause you to run out of memory in 2.x.
Therefore, Python 2.x has xrange which creates an iterator identical to range in 3.x.
Also, you can simplify your math somewhat. For example:
x = 600851475143
half_x = x // 2
count_factors = 0
for i in xrange(half_x):
if i > 0 and x % i == 0:
count_factors += 1
print count_factors
However, there are much more efficient ways to do this.
As a simple example, if the number is divisible by two, you can iterative over every other number, cutting the number of tests in half. Similarly, if it's divisible by 3, 5, etc.
I'll leave it to you to figure out the generalization. It's a fun problem :)

Make the biggest number in python

I'm looking for a Python object which is guaranteed to compare greater than any given int. It should be portable, platform-independent and work on both Python 2.7+ and 3.x.
For example:
x = float('inf')
while True:
n = next(my_gen)
if my_calc(n):
x = min(n, x)
if my_cond(x):
break
Here I've used float('inf') for this purpose because it seems to behave correctly. But this feels dirty, because I think it relies on some underlying float specification and I don't know whether that's going to be platform dependent or break in unexpected ways.
I'm aware that I could create my own class and define the comparison operators, but I thought there might be an existing built-in way.
Is it safe to use float('inf') like this? Is there a less ugly way of creating this "biggest integer"?
float('inf') is guaranteed to test as larger than any number, including integers. This is not platform specific.
From the floatobject.c source code:
else if (!Py_IS_FINITE(i)) {
if (PyInt_Check(w) || PyLong_Check(w))
/* If i is an infinity, its magnitude exceeds any
* finite integer, so it doesn't matter which int we
* compare i with. If i is a NaN, similarly.
*/
j = 0.0;
Python integers themselves are only bounded by memory, so using 10 ** 3000 is not going to be big enough, probably.
float('inf') is always available; Python will handle underlying platform specifics for you to make this so.
Why don't just use:
x = float('inf')
instead of:
x = 1e3000
Read this post for more information.
In the following I remove the need for that first sentinel x value by using an outer while loop to capture the first valid x then using it on the preserved inner while loop:
while True:
n = next(my_gen)
if my_calc(n):
x = n
if my_cond(x):
break
else:
while True:
n = next(my_gen)
if my_calc(n):
x = min(n, x)
if my_cond(x):
break
break
It is more code. Usually the removal of sentinel values is good but the above would have to be assessed for maintainability.
Further factoring of the code gives the following, but the code above preserves more of the original conditionals.
while True:
n = next(my_gen)
if my_calc(n):
x = n
if not my_cond(x):
while True:
n = next(my_gen)
if my_calc(n):
x = min(n, x)
if my_cond(x):
break
break

Generate and Enter Value for OEIS Sequence in Python?

This is a rather difficult challenge for me as I am new to Python. How would I write a program in python based off this sequence function:
http://oeis.org/A063655
and does the following:
It asks for the value of the sequence and returns the corresponding number. For example, the number corresponding to the 10th value of the sequence is 7. I'd like to be able to do this for values over 300,000,000.
So, the final product would look like this:
Enter a value: 4
[7]
Any ideas where to start? I have a framework to generate sequences where (x) would be to put a mathematical equation or numbers, but I'm not exactly sure how to go from here or how to implement the "Enter a value" portion:
import math
def my_deltas():
while True:
yield (x)
yield (x)
def numbers(start, deltas, max):
i=start
while i<=max:
yield i
i+=next(deltas)
print(','.join(str(i) for i in numbers((x), my_deltas(),(x))))
If you're looking to have your computer keep track of over 300,000,000 elements of a sequence, if each is a 4 byte integer, you'll need at least 300,000,000 * 4bytes, or over 1.1GB of space to store all the values. I assume generating the sequence would also take a really long time, so generating the whole sequence again each time the user wants a value is not quite optimal either. I am a little confused about how you are trying to approach this exactly.
To get a value from the user is simple: you can use val = input("What is your value? ") where val is the variable you store it in.
EDIT:
It seems like a quick and simple approach would be this way, with a reasonable number of steps for each value (unless the value is prime...but lets keep the concept simple for now): You'd need the integer less than or equal to the square root of n (start_int = n ** .5), and from there you test each integer below to see if it divides n, first converting start_int to an integer with start_int = int(start_int) (which gives you the floor of start_int), like so: while (n % start_int) != 0: start_int = start_int - 1, decrement by one, and then set b = start_int. Something similar to find d, but you'll have to figure that part out. Note that % is the modulus operator (if you don't know what that is, you can read up on it, google: 'modulus python'), and ** is exponentiation. You can then return a value with the return statement. Your function would look something like this (lines starting with # are comments and python skips over them):
def find_number(value):
#using value instead of n
start_int = value ** .5
start_int = int(start_int)
while (n % start_int) != 0:
#same thing as start_int = start_int - 1
start_int -= 1
b = start_int
#...more code here
semiperimeter = b + d
return semiperimeter
#Let's use this function now!
#store
my_val = input("Enter a value: ")
my_number = find_number(my_val)
print my_number
There are many introductory guides to Python, and I would suggest you go through one first before tackling implementing a problem like this. If you already know how to program in another language you can just skim a guide to Python's syntax.
Don't forget to choose this answer if it helped!
from math import sqrt, floor
def A063655(n):
for i in range(floor(sqrt(n)), 0, -1):
j = floor(n / i)
if i * j == n:
return i + j
if __name__ == '__main__':
my_value = int(input("Enter a value: "))
my_number = A063655(my_value)
print(my_number)
USAGE
> python3 test.py
Enter a value: 10
7
> python3 test.py
Enter a value: 350000
1185
>

Categories