Project Euler 78 - Coin Partition - python

Problem statement:
Let p(n) represent the number of different ways in which n coins can be separated into piles. For example, five coins can be separated into piles in exactly seven different ways, so p(5)=7
Find the least value of n for which p(n) is divisible by one million.
So that's a code i got using recursion to solve this problem. I know that's not the optimal aproach, but should give me the right answer... But for some reason I don't understand it gives me back that n = 2301 has a p(n) = 17022871133751703055227888846952967314604032000000, which is divisible by 1,000,000 and is the least n to do that. So why this is not the correct answer?
I checked the for n<20 and it matches. So what's wrong with my code?
import numpy as np
import sys
sys.setrecursionlimit(3000)
table = np.zeros((10000,10000))
def partition(sum, largestNumber):
if (largestNumber == 0):
return 0
if (sum == 0):
return 1
if (sum < 0):
return 0
if (table[sum,largestNumber] != 0):
return table[sum,largestNumber]
table[sum,largestNumber] = partition(sum,largestNumber-1) + partition(sum-largestNumber,largestNumber)
return table[sum,largestNumber]
def main():
result = 0
sum = 0
largestNumber = 0
while (result == 0 or result%1000000 != 0):
sum += 1
largestNumber += 1
result = int(partition(sum,largestNumber))
print("n = {}, resultado = {}".format(sum,result))
return 0
if __name__ == '__main__':
main()

I believe the NumPy data type used in your np.zeroes declaration is a restricted rather than unlimited number. The number of partitions of 2301 is in fact 17022871133751761754598643267756804218108498650480 and not 17022871133751703055227888846952967314604032000000, which you can see if you run your (correct) program with a regular table declaration like
table = [10000 * [0] for i in xrange(10000)]
and then call on the table appropriately.

Related

How to solve this problem without using recursion? (Number of ways a line can be arranged with restriction)

Good day! I am currently writing a code that solves the way in which a line with n number of people with varying heights can be arranged so that m number of people can see "with no obstruction". A person is "with no obstruction" when all the people in front of that person is shorter than the person itself.
I answered this by using recursion:
def notObstruct(n, m):
if n == 0 and m == 0: return 0
if m == 0 and n >= 1: return 0
if m == n: return 1
if m > n: return 0
return notObstruct(n-1, m-1) + (n-1) * notObstruct(n-1, m)
I used stirling number of the first kind to solve this problem. However, I need to solve this using permutation and combination as a restriction from the problem itself.
notObstruct(5, 3) = 35
notObstruct(7, 2) = 1764
notObstruct(10, 3) = 1172700

Stack overflow in recursion Python

I'm doing the Project Euler problem 78
Let p(n) represent the number of different ways in which n coins can be separated into piles. For example, five coins can be separated into piles in exactly seven different ways, so p(5)=7
Find the least value of n for which p(n) is divisible by one million.
I'm trying to solve this problem using recursion. I know is not the optimal solution neither the fastest one, but I want to make this work if possible. Around n = 6000 it gives me:
MemoryError: Stack overflow
And that is not the only problem. I checked online and the solution is around 53,000. My matrix goes only to 10,000x10,000. If i go to 60,000x60,000 it return a MemoryError.
Here is my code:
import sys
from time import process_time as timeit
sys.setrecursionlimit(100000)
table = [10000 * [0] for i in range(10000)]
def partition(sum, largestNumber):
if (largestNumber == 0):
return 0
if (sum == 0):
return 1
if (sum < 0):
return 0
if (table[sum][largestNumber] != 0):
return table[sum][largestNumber]
table[sum][largestNumber] = partition(sum,largestNumber-1) + partition(sum-largestNumber,largestNumber)
return table[sum][largestNumber]
def main():
result = 0
sum = 0
largestNumber = 0
while (result == 0 or result%100000 != 0):
sum += 1
largestNumber += 1
result = int(partition(sum,largestNumber))
if sum%1000 == 0:
print('{} {}'.format(sum,timeit()))
print("n = {}, resultado = {}".format(sum,result))
print('Tempo = {}'.format(timeit()))
if __name__ == '__main__':
main()

Factors of a number using Python recursive function

I've got an assignment which requires me to use a Python recursive function to output the factors of a user inputted number in the form of below:
Enter an integer: 6 <-- user input
The factors of 6 are:
1
2
3
6
I feel like a bit lost now and have tried doing everything myself for the past 2 hours but simply cannot get there. I'd rather be pushed in the right direction if possible than shown where my code needs to be changed as I'd like to learn
Below is my code:
def NumFactors(x):
for i in range(1, x + 1):
if x == 1:
return 1
if x % i == 0:
return i
return NumFactors(x-1)
x = int(input('Enter an integer: '))
print('The factors of', x, 'are: ', NumFactors(x))
In your code the problem is the for loop inside the method. The loop starts from one and goes to the first if condition and everything terminates there. That is why it only prints 1 as the output this is a slightly modified version of your own code. This should help. If you have any queries feel free to ask.
def factors(x):
if x == 1:
print(1 ,end =" ")
elif num % x == 0:
factors(x-1)
print(x, end =" ")
else:
factors(x-1)
x = num = int(input('Enter an integer: '))
print('The factors of', x, 'are: ',end =" ")
factors(x)
Since this question is almost 3 years old, I'll just give the answer rather than the requested push in the right direction:
def factors (x,c=1):
if c == x: return x
else:
if x%c == 0: print(c)
return factors(x,c+1)
Your recursion is passing down x-1 which will not give you the right value. For example: the number of factors in 6 cannot be obtained from the number of factors in 5.
I'm assuming that you are not looking for the number of prime factors but only the factors that correspond to the multiplication of two numbers.
This would not normally require recursion so you can decide on any F(n) = F(n-1) pattern. For example, you could use the current factor as a starting point for finding the next one:
def NumFactors(N,F=1):
count = 1 if N%F == 0 else 0
if F == N : return count
return count + NumFactors(N,F+1)
You could also optimize this to count two factors at a time up to the square root of N and greatly reduce the number of recursions:
def NumFactors(N,F=1):
count = 1 if N%F == 0 else 0
if N != F : count = count * 2
if F*F >= N : return count
return count + NumFactors(N,F+1)

Sum of all prime numbers between 1 and N in Python

I'm new to programming. While trying to solve this problem, I'm getting the wrong answer. I checked my code a number of times but was not able to figure out the mistake. Please, help me on this simple problem. The problem is as follows:
Given a positive integer N, calculate the sum of all prime numbers between 1 and N (inclusive). The first line of input contains an integer T denoting the number of test cases. T testcases follow. Each testcase contains one line of input containing N. For each testcase, in a new line, print the sum of all prime numbers between 1 and N.
And my code is:
from math import sqrt
sum = 0
test = int(input())
for i in range(test):
max = int(input())
if max==1:
sum = 0
elif max==2:
sum += 2
else:
sum = sum + 2
for x in range(3,max+1):
half = int(sqrt(max)) + 1
for y in range(2,half):
res = x%y
if res==0:
sum = sum + x
break
print(sum)
For input 5 and 10, my code is giving output 6 and 48 respectively, while the correct answer is 10 and 17 respectively. Please, figure out the mistake in my code.
Here, I implemented simple program to find the sum of all prime numbers between 1 to n.
Consider primeAddition() as a function and ip as an input parameter. It may help you to solve your problem.Try it.
Code snippet:
def primeAddition(ip):
# list to store prime numbers...
prime = [True] * (ip + 1)
p = 2
while p * p <= ip:
# If prime[p] is not changed, then it is a prime...
if prime[p] == True:
# Update all multiples of p...
i = p * 2
while i <= ip:
prime[i] = False
i += p
p += 1
# Return sum of prime numbers...
sum = 0
for i in range (2, ip + 1):
if(prime[i]):
sum += i
return sum
#The program is ready... Now, time to call the primeAddition() function with any argument... Here I pass 5 as an argument...
#Function call...
print primeAddition(5)
This is the most broken part of your code, it's doing the opposite of what you want:
res = x%y
if res==0:
sum = sum + x
break
You only increment sum if you get through the entire loop without breaking. (And don't use sum as you're redefining a Python built-in.) This can be checked using the special case of else on a for loop, aka "no break". I've made that change below as well as corrected some inefficiencies:
from math import sqrt
T = int(input())
for _ in range(T):
N = int(input())
sum_of_primes = 0
if N < 2:
pass
elif N == 2:
sum_of_primes = 2
else:
sum_of_primes = 2
for number in range(3, N + 1, 2):
for odd in range(3, int(sqrt(number)) + 1, 2):
if (number % odd) == 0:
break
else: # no break
sum_of_primes += number
print(sum_of_primes)
OUTPUT
> python3 test.py
3
5
10
10
17
23
100
>
A slight modification to what you have:
from math import sqrt
sum = 0
test = int(input())
max = int(input())
for x in range(test,max+1):
if x == 1:
pass
else:
half = int(sqrt(x)) + 1
for y in range(2,half):
res = x%y
if res==0:
break
else:
sum = sum + x
print(sum)
Your biggest error was that you were doing the sum = sum + x before the break rather than outside in an else statement.
PS: (although you can) I'd recommend not using variable names like max and sum in your code. These are special functions that are now overridden.
Because your logic is not correct.
for y in range(2,half):
res = x%y
if res==0:
sum = sum + x
break
here you check for the factors and if there is a factor then adds to sum which is opposite of the Primes. So check for the numbers where there is no factors(except 1).
from math import sqrt
test = int(input())
for i in range(test):
sum = 0
max = int(input())
if max==1:
sum = 0
elif max==2:
sum += 2
else:
sum = sum + 2
for x in range(3,max+1):
half = int(sqrt(x)) + 1
if all(x%y!=0 for y in range(2,half)):
sum = sum + x
print(sum)
First of all, declare sum to be zero at the beginning of the for i loop.
The problem lies in the if statement at almost the very end of the code, as you add x to the sum, if the res is equal to zero, meaning that the number is indeed not a prime number. You can see that this is the case, because you get an output of 6 when entering 5, as the only non-prime number in the range 1 to and including 5 is 4 and you add 2 to the sum at the beginning already.
Last but not least, you should change the
half = int(sqrt(max)) + 1
line to
half = int(sqrt(x)) + 1
Try to work with my information provided and fix the code yourself. You learn the most by not copying other people's code.
Happy coding!
I believe the mistake in your code might be coming from the following lines of code:
for x in range(3,max+1):
half = int(sqrt(max)) + 1
Since you are looping using x, you should change int(sqrt(max)) to int(sqrt(x)) like this:
for x in range(3,max+1):
half = int(sqrt(x)) + 1
Your code is trying to see if max is prime N times, where you should be seeing if every number from 1-N is prime instead.
This is my first time answering a question so if you need more help just let me know.

Hofstadter equation related code in python

There was this question in a university assignment related to Hofstadter sequence. It basically say that it is a integer sequence blah blah and there are two values for a given index n. A male value [M(n)] and a female value [F(n)].
They are defined as:
M(0)=0
F(0)=1
M(n)=n-F(M(n-1))
F(n)=n-M(F(n-1))
And we were asked to write a program in python to find the Male and Female values of the sequence of a given integer.
So the code I wrote was:
def female(num):
if num == 0:
return 1
elif num >0:
return num - male(female(num-1))
def male(num):
if num==0:
return 0
elif num >0:
return num - female(male(num-1))
And when executed with a command like
print male(5)
It works without a fuss. But when I try to find the value of n = 300, the program gives no output.
So I added a print method inside one of the functions to find out what happens to the num value
[ elif num>0:
print num ...]
And it shows that the num value is decreasing until 1 and keeps hopping between 1 and 2 at times reaching values like 6.
I can’t figure out why it happens. Any insight would be nice. Also what should I do to find the values relevant to bigger integers. Thanks in advance. Cheers.
The code is theoretically fine. What you underestimate is the complexity of the computation. Formula
M(n)=n-F(M(n-1))
actually means
tmp = M(n-1)
M(n) = n - F(tmp)
So if you represent this calculation as a tree of necessary calls, you might see that its a binary tree and you should go through all its nodes to calculate the results. Given that M(n) and F(n) are about n/2 I'd estimate the total number of the nodes to be of order 2^(n/2) which becomes a huge number once you put n = 300 there. So the code works but it just will take a very very long time to finish.
The one way to work this around is to employ caching in a form of memoization. A code like this:
femCache = dict()
def female(num):
#print("female " + str(num))
global femCache
if num in femCache:
return femCache[num];
else:
res = 1 # value for num = 0
if num > 0:
res = num - male(female(num-1))
femCache[num] = res
return res
maleCache = dict()
def male(num):
#print("male " + str(num))
global maleCache
if num in maleCache:
return maleCache[num];
else:
res = 0 # value for num = 0
if num > 0:
res = num - female(male(num-1))
maleCache[num] = res
return res
print(male(300))
should be able to compute male(300) in no time.

Categories

Resources