OverflowError in a for loop - python-2.7

I'm working on problem 3 of Project Euler using Python, but I can't seem to solve the problem without running into the following error: "OverflowError: range() result has too many items"
I'm wondering if there's a way to increase the allowed range? My code looks as follows:
target = 600851475143
largest_prime_factor = 1
#find largest prime factor of target
for possible_factor in range(2,(target/2)+1):
if target % possible_factor == 0:
is_prime = True
for i in range(2,(possible_factor/2)+1):
if possible_factor % i == 0:
is_prime = False
break
if is_prime:
largest_prime_factor = possible_factor
print largest_prime_factor

If you run into limitations of your computer or language while trying to solve a puzzle problem, or if it takes too long, it is an indication that probably there exists a better way (read: algorithm) to solve the problem. In your case, you do not need to loop to target / 2 + 1 (though that is a good educated upper bound). You only need to go as far as ceil(sqrt(target)).
And, as a sidenote, you can overcome this limitation by using xrange, which will create a generator, instead of range for Python 2, which creates a list. In Python 3, range will return a sequence type instead of a list by default.
Thanks to #Fernando for the clarification in the comments.

Related

How do programs calculate square roots?

I understand that this is a pretty math-y question, but how do programs get square roots? From what I've read, this is something that is usually native to the cpu of a device, but I need to be able to do it, probably in c++ (although that's irrelevant).
The reason I need to know about this specifically is that I have an intranet server and I am getting started with crowdsourcing. For this, I am going to start with finding a lot of digits of a certain square root, like sqrt(17) or something.
This is the extent of what python provides is just math.sqrt()
I am going to make a client that can work with other identical clients, so I need complete control over the processes of the math. Heck, this question might not even have an answer, but thanks for your help anyway.
[edit]
I got it working, this is the 'final' product of it: (many thanks to #djhaskin987)
def square_root(number):
old_guess = 1
guess = 2
guesssquared = 0
while round(guesssquared, 10) != round(number, 10):
old_guess = guess
guess = ((number / guess) + guess ) / 2
print(guess)
guesssquared = guess * guess
return guess
solution = square_root(7) #finds square root of 7
print(solution)
Computers use a method that people have actually been using since babylonian times:
def square_root(number):
old_guess = 1
guess = 2
while old_guess != guess:
old_guess = guess
guess = ((number / guess) + guess ) / 2
return guess
x86 has many sqrt in registry, starting with FSQRT for float.
In general, if your function is too complicated or has no implementation, and is C^\infty ("infinitely" differentiable), you can expand it into a polynom via Taylor expansion. This is extremely common in HPC.

How to call function from external library in C/C++

I want to find the symmetry group of an integer linear program. I think there is a function in skip called SCIPgetGeneratorsSymmetry . I how I can use this function?
You are right, to access symmetry information in SCIP, you have to call the function SCIPgetGeneratorsSymmetry() via C/C++. Note that you need to link SCIP against the external software bliss, because otherwise, SCIP is not able to compute symmetries of your (mixed-integer) linear program.
If you set up your (mixed-integer) linear program using a C/C++ project, you have several options for computing symmetries.
If you set the "recompute" parameter to FALSE, SCIP will return the currently available symmetry information - if symmetries have not been computed yet, SCIP will compute symmetries to give you access to this information.
If you set "recompute" to TRUE, SCIP will discard the available symmetry information and you get access to the generators of the current symmetry group. Moreover, you can control the kind of symmetries that are computed via the parameters "symspecrequire" and "symspecrequirefixed", e.g., to only compute symmetries of binary variables that fix continuous variables.
Edit:
If you have no experience with coding in C/C++ and you are only interested in printing the generators of the symmetry group, the easiest way is probably to modify SCIP's source code in presol_symmetry.c as follows:
Add two integer paramaters int i and int p at the very beginning of determineSymmetry().
Search within determineSymmetry() for the line in which computeSymmetryGroup() is called.
Add the following code snippet right after this function call:
for (p = 0; p < presoldata->nperms; ++p)
{
printf("permutation %d\n", p);
for (i = 0; i < presoldata->npermvars; ++i)
{
if ( TRUE )
printf("%d ", presoldata->perms[p][i]);
else
printf("%s ", SCIPvarGetName(presoldata->permvars[presoldata->perms[p][i]]));
}
printf("\n");
}
This code prints the generators of the symmetry group as a list of variable indices, e.g., 1 2 0 is the permutation that maps 0 -> 1, 1 -> 2, and 2 -> 0. If you change TRUE to FALSE, you get the same list but variable indices are replaced by their names.
Do not forget to recompile SCIP.
If you solve an instance with SCIP and symmetry handling is enabled, SCIP will print the generators in the above format whenever it computes the symmetry group. If you are interested in the symmetry group of the original problem, you should use the parameter setting presolving/symbreak/addconsstiming = 0 and propagating/orbitalfixing/symcomptiming = 0. If you are fine with symmetries of the presolved problem, change the zeros to ones.

Python Error - Google Foobar

To anyone who has done Google's Foobar challenge before, have you ever encountered an error like this?
Verifying solution...
{
"bytes" : "CAAaIgogQ291bGQgbm90IGZpbmQgJ2Fuc3dlcicgZnVuY3Rpb24"
}
I've tested my solution in Visual Studio, and it works fine, and it gives accurate output. I only have 36 hours remaining to submit my solution, and this is the final challenge, so I would really like to get credit for completing it. Here's the code I'm trying to verify:
from fractions import *
from math import factorial as fac
def cycle_index(n):
return [(coeff(term), term) for term in foo(n, n)]
def foo(n, lim):
soln_set = []
if n > 0:
for x in range(lim, 0, -1):
if x == 1:
soln_set.append([(1, n)])
else:
for y in range(int(n / x), 0, -1):
recurse = foo(n - x * y, x - 1)
if len(recurse) == 0:
soln_set.append([(x, y)])
for soln in recurse:
soln_set.append([(x, y)] + soln)
return soln_set
def coeff(term):
val = 1
for x, y in term:
val *= fac(y) * x ** y
return Fraction(1, val)
def cross(cycle_a, cycle_b):
term = []
for len_a, freq_a in cycle_a:
for len_b, freq_b in cycle_b:
lcm = len_a * len_b / gcd(len_a, len_b)
term.append((lcm, int(len_a * freq_a * len_b * freq_b / lcm)))
return term
def answer(w, h, s):
total = 0
cycidx_cols = cycle_index(w)
cycidx_rows = cycle_index(h)
for col_coeff, col_cycle in cycidx_cols:
for row_coeff, row_cycle in cycidx_rows:
coeff = col_coeff * row_coeff
cycle = cross(col_cycle, row_cycle)
value = 1
for _, power in cycle:
value *= s ** power
total += coeff * value
return total
I found someone else's solution last week and verified it through Foobar, but I wanted to write my own to get a deeper understanding. I've compared results side-by-side, and they are exact, so I know my code gives accurate results.
Out of curiosity, I just retried verifying the other person's solution again, and now I am getting the same error with a slightly different output even though it worked just fine when I tried last week:
Verifying solution...
{
"bytes" : "CAEQARABEAEQARABEAEQARABEAEQAQ"
}
I'm not sure where else to go. I was so excited that I had come up with my own solution to the challenge, but now I'm panicking that it won't matter. Any suggestions?
UPDATE - June 29, 2018, 6:00pm CST
The deadline passed for me last night, and I was unable to submit my code in time. I made sure to use the recruitme command before time ran out just in case I got booted out. However, I am still able to view my current status, and it let me request another Level 5 challenge. So, I will be checking periodically to see if the test cases start showing up again, and I will be sure to update this when they do. I would highly recommend that anyone on lower levels wait until I confirm that this issue is fixed before attempting to request another challenge.
UPDATE - June 30, 2018, 5:00am CST
According to the pattern found by #RobertAnsel, I have completed the challenge. I confirmed this pattern by hardcoding the answer function to output solutions to the test cases given in the instructions. The resulting errors matched exactly with the predicted output. I also found an interesting thread on Google's Support Forum (linked here) where something similar happened to a bunch of Foobar challengers. It seems like their error was fixed by Google after about three days, but unfortunately, it also looks like a lot of people who timed out were not given another chance. Nevertheless, this will probably resolve itself within the next day or two. I will continue trying to verify and submit my solution until I am successful.
UPDATE - July 4, 2018, 12:00am CST
This issue seems to have been more or less resolved. Refer to the chosen answer for more details. Thanks a ton to #RobertAnsel for all the help! Some additional info: I was able to verify my current challenge, but upon submission, I was told that my time for the problem had expired. After logging in again, I was able to request a new challenge. I noticed I was also able to use the recruitme command again. I am not sure if this means they did not receive the first request or if you are allowed to use that command multiple times. Regardless, I am relieved that I am able to continue forward with Foobar. Best of luck to the rest of you!
This may not be the answer you're looking for, but that first "bytes" string is a base64 encoding of the following error message:
"Could not find 'answer' function".
I've done the Foobar challenge myself, and that should only happen if you are trying to verify a file that is missing a defined "answer" function, which obviously you are not. Are you certain that the spec they provide has 3 arguments vs an array with 3 items?
The second message (CAEQARABEAEQARABEAEQARABEAEQAQ), while valid base64, doesn't map to ASCII or UTF-8. After some closer analysis of some of the other strings others have posted, I've concluded that this is the base64 encoded version of the test output. It isn't very human readable, but I believe it is 11 2-byte chunks, the first of which is unhelpful, but the following 10 are the test result for each of the corresponding test cases. In the case of this message it converts to binary as:
0000100000000001 <- unknown pre-pended info
0001000000000001 <- passing test 1
0001000000000001 <- passing test 2
0001000000000001 <- passing test 3
0001000000000001 <- passing test 4
0001000000000001 <- passing test 5
0001000000000001 <- passing test 6
0001000000000001 <- passing test 7
0001000000000001 <- passing test 8
0001000000000001 <- passing test 9
0001000000000001 <- passing test 10
The '1's at the end of each of these lines indicates that all 10 tests are passing.
A failing test case is represented by the following string:
0001000000000000 <- failing test case
This should help you (and others) continue testing to achieve fully passing tests (you can complete your own analysis with tools like this one: https://cryptii.com/base64-to-binary), but unfortunately this will not help you move forward with your final submission until Google remediates the issue on their end.
UPDATE: July 2, 8PM PDT
After reaching out to a couple of Google recruiters about the issue they were able to confirm that the issue was identified and is believed to be resolved today.
If you re-save your code after making a change to it (whitespace should be fine), you should be able to test and submit correctly. Alternatively, you may now be able to request a new challenge anyway.
There will be nothing for you to solve this issue, it is a issue on Google's site, as the Google Foobar API is responding with this message as I've found out.
Notherless your best bet will be to use the feedback command and give Google Foobar a feedback and mark it as a bug. This will be more likely to reach their attention and helping them to fix this issue!

Declaring variables in Python 2.7x to avoid issues later

I am new to Python, coming from MATLAB, and long ago from C. I have written a script in MATLAB which simulates sediment transport in rivers as a Markov Process. The code randomly places circles of a random diameter within a rectangular area of a specified dimension. The circles are non-uniform is size, drawn randomly from a specified range of sizes. I do not know how many times I will step through the circle placement operation so I use a while loop to complete the process. In an attempt to be more community oriented, I am translating the MATLAB script to Python. I used the online tool OMPC to get started, and have been working through it manually from the auto-translated version (was not that helpful, which is not surprising). To debug the code as I go, I use the
MATLAB generated results to generally compare and contrast against results in Python. It seems clear to me that I have declared variables in a way that introduces problems as calculations proceed in the script. Here are two examples of consistent problems between different instances of code execution. First, the code generated what I think are arrays within arrays because the script is returning results which look like:
array([[ True]
[False]], dtype=bool)
This result was generated for the following code snippet at the overlap_logix operation:
CenterCoord_Array = np.asarray(CenterCoordinates)
Diameter_Array = np.asarray(Diameter)
dist_check = ((CenterCoord_Array[:,0] - x_Center) ** 2 + (CenterCoord_Array[:,1] - y_Center) ** 2) ** 0.5
radius_check = (Diameter_Array / 2) + radius
radius_check_update = np.reshape(radius_check,(len(radius_check),1))
radius_overlap = (radius_check_update >= dist_check)
# Now actually check the overalp condition.
if np.sum([radius_overlap]) == 0:
# The new circle does not overlap so proceed.
newCircle_Found = 1
debug_value = 2
elif np.sum([radius_overlap]) == 1:
# The new circle overlaps with one other circle
overlap = np.arange(0,len(radius_overlap), dtype=int)
overlap_update = np.reshape(overlap,(len(overlap),1))
overlap_logix = (radius_overlap == 1)
idx_true = overlap_update[overlap_logix]
radius = dist_check(idx_true,1) - (Diameter(idx_true,1) / 2)
A similar result for the same run was produced for variables:
radius_check_update
radius_overlap
overlap_update
Here is the same code snippet for the working MATLAB version (as requested):
distcheck = ((Circles.CenterCoordinates(1,:)-x_Center).^2 + (Circles.CenterCoordinates(2,:)-y_Center).^2).^0.5;
radius_check = (Circles.Diameter ./ 2) + radius;
radius_overlap = (radius_check >= distcheck);
% Now actually check the overalp condition.
if sum(radius_overlap) == 0
% The new circle does not overlap so proceed.
newCircle_Found = 1;
debug_value = 2;
elseif sum(radius_overlap) == 1
% The new circle overlaps with one other circle
temp = 1:size(radius_overlap,2);
idx_true = temp(radius_overlap == 1);
radius = distcheck(1,idx_true) - (Circles.Diameter(1,idx_true)/2);
In the Python version I have created arrays from lists to more easily operate on the contents (the first two lines of the code snippet). The array within array result and creating arrays to access data suggests to me that I have incorrectly declared variable types, but I am not sure. Furthermore, some variables have a size, for example, (2L,) (the numerical dimension will change as circles are placed) where there is no second dimension. This produces obvious problems when I try to use the array in an operation with another array with a size (2L,1L). Because of these problems I started reshaping arrays, and then I stopped because I decided these were hacks because I had declared one, or more than one variable incorrectly. Second, for the same run I encountered the following error:
TypeError: 'numpy.ndarray' object is not callable
for the operation:
radius = dist_check(idx_true,1) - (Diameter(idx_true,1) / 2)
which occurs at the bottom of the above code snippet. I have posted the entire script at the following link because it is probably more useful to execute the script for oneself:
https://github.com/smchartrand/MarkovProcess_Bedload
I have set-up the code to run with some initial parameter values so decisions do not need to be made; these parameter values produce the expected results in the MATLAB-based script, which look something like this when plotted:
So, I seem to specifically be having issues with operations on lines 151-165, depending on the test value np.sum([radius_overlap]) and I think it is because I incorrectly declared variable types, but I am really not sure. I can say with confidence that the Python version and the MATLAB version are consistent in output through the first step of the while loop, and code line 127 which is entering the second step of the while loop. Below this point in the code the above documented issues eventually cause the script to crash. Sometimes the script executes to 15% complete, and sometimes it does not make it to 5% - this is due to the random nature of circle placement. I am preparing the code in the Spyder (Python 2.7) IDE and will share the working code publicly as a part of my research. I would greatly appreciate any help that can be offered to identify my mistakes and misapplications of python coding practice.
I believe I have answered my own question, and maybe it will be of use for someone down the road. The main sources of instruction for me can be found at the following three web pages:
Stackoverflow Question 176011
SciPy FAQ
SciPy NumPy for Matlab users
The third web page was very helpful for me coming from MATLAB. Here is the modified and working python code snippet which relates to the original snippet provided above:
dist_check = ((CenterCoordinates[0,:] - x_Center) ** 2 + (CenterCoordinates[1,:] - y_Center) ** 2) ** 0.5
radius_check = (Diameter / 2) + radius
radius_overlap = (radius_check >= dist_check)
# Now actually check the overalp condition.
if np.sum([radius_overlap]) == 0:
# The new circle does not overlap so proceed.
newCircle_Found = 1
debug_value = 2
elif np.sum([radius_overlap]) == 1:
# The new circle overlaps with one other circle
overlap = np.arange(0,len(radius_overlap[0]), dtype=int).reshape(1, len(radius_overlap[0]))
overlap_logix = (radius_overlap == 1)
idx_true = overlap[overlap_logix]
radius = dist_check[idx_true] - (Diameter[0,idx_true] / 2)
In the end it was clear to me that it was more straightforward for this example to use numpy arrays vs. lists to store results for each iteration of filling the rectangular area. For the corrected code snippet this means I initialized the variables:
CenterCoordinates, and
Diameter
as numpy arrays whereas I initialized them as lists in the posted question. This made a few mathematical operations more straightforward. I was also incorrectly indexing into variables with parentheses () as opposed to the correct method using brackets []. Here is an example of a correction I made which helped the code execute as envisioned:
Incorrect: radius = dist_check(idx_true,1) - (Diameter(idx_true,1) / 2)
Correct: radius = dist_check[idx_true] - (Diameter[0,idx_true] / 2)
This example also shows that I had issues with array dimensions which I corrected variable by variable. I am still not sure if my working code is the most pythonic or most efficient way to fill a rectangular area in a random fashion, but I have tested it about 100 times with success. The revised and working code can be downloaded here:
Working Python Script to Randomly Fill Rectangular Area with Circles
Here is an image of a final results for a successful run of the working code:
The main lessons for me were (1) numpy arrays are more efficient for repetitive numerical calculations, and (2) dimensionality of arrays which I created were not always what I expected them to be and care must be practiced when establishing arrays. Thanks to those who looked at my question and asked for clarification.

ThinkPython Exercise 5.4 Koch Curve

I do not understand how the Koch Curve is drawn from using this function.
def koch(t, n):
"""Draws a koch curve with length n."""
if n<3:
fd(t, n)
return
m = n/3.0
koch(t, m)
lt(t, 60)
koch(t, m)
rt(t, 120)
koch(t, m)
lt(t, 60)
koch(t, m)
The fd(t, n) command means object 't' will move forward by amount 'n'.
The rt(t, 120) and lt(t, 60) commands means object 't' will turn right or left by the given angles.
So I gather that the author uses recursion in the function but I do not understand how it reiterates so many times with itself as I am a beginner and have very limited logic skills.
As an example say I called koch(t, 100) the if clause is by passed as n > 3 which leads to the next line of code which is m/3.0 so 100/3.0 is 33.3. This then leads to koch(t, 33.3) and as n > 3 still holds it reiterates again to produce koch(t, 11.1) and so forth until we reiterate it until we come to koch(t, 1.23).
Now as n = 1.23 and the if clause activates as soon as n < 3 we can run through the if conditionals block of code replacing all the koch(t, m) statements with fd(t, 1.23). As I see it fd(), lt(), fd(), rt(), fd, lt(), fd() should be activated only one time as n < 3 as soon as n = 1.23 or does it reiterate again with 1.23 / 3.0 and the code is ran again with koch(t, 0.41)? Maybe because an else clause does not exists to cancel the function, however the function does end and if I choose a higher value for n the koch curve is also larger making me more confused as there I can see no line in the code which tells me to reiterate this function n number of times.
I apologize for the lack of clarity as I do not understand how to explain this clearly.
I think you may be looking at this from the wrong end to try to work it out. Consider first what happens if you call koch(t,1). The if statement evaluates to false, and you can see that something like this is drawn:
_/\_
Now what if you call koch(t,3)? Try on a piece of paper and you'll see that each of the straight lines in the picture above is replaced by similar shape...
I found out my problem after reading about recursion and testing some print statements in my console. What I did not understand was why choosing a larger n (length) produced a larger fractal. Basically because choosing a larger n produces more nodes (children) on a recursive tree so choosing a larger n will produce more children nodes and only the last nodes (null nodes) when n < 3 occurs will the turtle t begin to draw and by this time there will be many null nodes if n is large.
To understand recursion even further including how recursion works when there are two or more recursive functions in the block of code as posed by this question I have included a link to a helpful thread and hopes it helps anybody else who is stuck on this question and needs help in understanding recursion.
Understanding recursion