I have to write a program that given the number below, s, finds the maximum product of a given length of consecutive numbers within the larger number. I have the framework of the code but in the line preceded by the three "#"s i keep getting an error that I cant call string 's' even though I'm turning it into an integer. I kind of understand why but I'm not quite sure. Also, if mathematically there is a better way t do that line, what would it be? Thanks so much for the help!
s=""\
"73167176531330624919225119674426574742355349194934"\
"96983520312774506326239578318016984801869478851843"\
"858615670789112949495459501737958331952853208805511"\
"12540698747158523863050715693290963295227443043557"\
"66896648950445244523161731856403098711121722383113"\
"62229893423380308135336276614282806444486645238749"\
"30358907296290491560440772390713810515859307960866"\
"70172427121883998797908792274921901699720888093776"\
"65727333001053367881220235421809751254540594752243"\
"52584907711670556013604839586446706324415722155397"\
"53697817977846174064955149290862569321978468622482"\
"83972241375657056057490261407972968652414535100474"\
"82166370484403199890008895243450658541227588666881"\
"16427171479924442928230863465674813919123162824586"\
"17866458359124566529476545682848912883142607690042"\
"24219022671055626321111109370544217506941658960408"\
"07198403850962455444362981230987879927244284909188"\
"84580156166097919133875499200524063689912560717606"\
"05886116467109405077541002256983155200055935729725"\
"71636269561882670428252483600823257530420752963450"
def findMaxProduct(n):
"""
>>> findMaxProduct(1)
9
>>> findMaxProduct(2)
81
>>> findMaxProduct(22)
3556892570112000
>>> findMaxProduct(60)
130883609235662685781298144870400000000
>>> findMaxProduct(70)
2412446685431734624320887406251212800000000
>>> findMaxProduct(80)
2412446685431734624320887406251212800000000
"""
largest = 0
for digit in range(len(s)-n):
product = 1
for k in range (n):
###product = product * int(s(digit + k))
if product > largest:
largest = product
return largest
You have s(...) which attempts to call a function named s. What you want instead is s[...] which will index into the string and return a subset of it.
Related
I have just started with Python programming language. I tried to write a function which takes input either a list or multiple integers to find their product. I am trying to find the product of first million natural numbers but its displaying an MemoryError.
def product(*arg):
answer=1
if type(arg) == tuple:
arg=str(arg)
arg=arg.lstrip('[(')
arg=arg.rstrip('],)')
arg=arg.split(',')
for i in arg:
answer*=int(i)
return answer
else:
for i in arg:
answer*=int(i)
return answer
j=range(1,1000000,1)
j=list(j)
print(product(j))
Steps:
I convert the range object into list object if i am to pass a list as
argument
Now, within the function, i try to split the tuple by converting it
string.
I convert the resultant string into a list and then loop over the
elements to find the product
Q1: How to avoid the memory error as i try to find the product of first Million natural numbers?
Q2 How to improve this code?
You can use a Generator in Python.
def generate_product():
r = 1
for i in range(1,1000000):
r *= i + 1
yield r
list(generate_product())[0]
It is more memory efficient and better in terms of performance.
To calculate the product of all numbers from 1 to 1 million use a simple loop:
r = 1
for l in range(1,1000000):
r*=(i+1)
print(res)
But keep in mind that the result will be a pretty big number.
That means that your calculation might take long and the resulting number will need a lot memory.
EDIT Then i missread your question a little. This is a function that multiplies the elements in a list:
def multiply_list_elements(_list):
result = 1
for element in _list:
result*=element
return result
multiply_list_elements([1,2,3,4])
>>> 24
The memory error probably came from the huge number as #ZabirAlNazi calculated so nicely.
All of the solution is fine, but one point to make - your question is equivalent to find the factorial of 1 million.
The number of digits of n! = log10(1) + log10(2) + ... log10(n)
import math
num_dig = 1
for i in range(1,1000000):
num_dig += math.log10(i)
print(num_dig)
So, the number of digits in your answer is 5565703 (approx.).
That's only the final n, if you also want the intermediate results it will require squared memory O(m^2).
import math
ans = 1
for i in range(2,1000001):
ans *= i
print(ans)
N.B: You can approximate with logarithms and Stirling numbers with faster run-time.
A very simple solution would be:
def prod_of():
p=1
for i in range(1,1000000):
p* = i
print(p)
The code is to find the largest possible product of 13 consecutive digits of a 1000 digit number. When I tried to run it on IDLE, it just gave RESTART and the directory where I saved the .py file. When I tried this on Pycharm(I know its not the IDE's problem, but I just had to try), no output. Am I doing something wrong?
n=7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
s=[]
j=13
def product(j):
p = 1
for i in range(j,j+13):
p=p*s[i]
return(p)
for i in range(0,1000):
s=s+[n%10]
n=n//10
k = product(0)
c=k
while j<1000:
if s[j]==0:
j=j+1
c=product(j)
while c==0:
j=j+13
c=product(j)
else:
c=(c*s[j+13])/s[j]
if c>k:
k=c
print(k)
Try this:
>>> n=7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
>>> digits = str(n)
>>> from numpy import prod
>>> products = [prod( map( int, digits[i:i+13])) for i in range(len(digits)-13)]
>>> max(products)
23514624000
Here's the quick explanation. First line -- this is your number. Second line -- I convert the number (like, 123) into the string "123", so I can take it digit by digit, hence the name of the variable digits.
I'm lazy to write multiplication routine, so I use a ready-made from numpy package, it's called prod and computes a product of the list, for example, prod( [1,2,3] ) = 6.
The next line is kind of complicated, but all it does -- going over your digits, selecting 13 of them at at time (digits[i:i+13]) and multiply them, saving the results in products.
Finally, the last line finds the maximum number in the products.
Your original code can be simplified to the following.
n=7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
def product(j):
p = 1
for i in range(j,j+13):
p=p*s[i]
return(p)
s=[]
for i in range(0,1000):
s=s+[n%10]
n=n//10
k = 0
N = len(s)
j = 0
while j<N-13: #need to 13 elements before end
c = product(j)
if c>k:
k=c
j = j + 1
print(k)
Result: 23514624000
This can be generated more easily even without resorting to Numpy by:
digits = str(n) # generates digits of number
products = [product(j) for j in range(1000-13)] # list comprehension
# uses you product function
print(max(products))
I am making a program where I can count the number of a in a string. This is my Code:
def repeatedString(s, n):
converged = s*n
got_it = converged[0:n]
count = 0
for x in got_it:
if "a" in x:
count += 1
return count
s = input()
n = int(input())
result = repeatedString(s, n)
print(result)
The variable s is where the string is entered, and variable n is for upto how long the string will repeat. My Code works OK, but for some reason when I give a bigger integer, it falls apart and gives me a Memory Error. For example, my input is:
a
1000000000000
It gives me this error:
Traceback (most recent call last):
File "programs.py", line 11, in <module>
result = repeatedString(s, n)
File "programs.py", line 2, in repeatedString
converged = s*n
MemoryError
How can I fix this Memory Error? If there's a better way to do it, it would also be helpful.
The problem with your code is where you do converged = s*n. In that line, you are asking the program to take the string s and allocate enough memory to fit the number of bytes in s * n, which, as you have seen, has a limit because your computer has a finite amount of free memory available (most modern-day computers only carry 4 - 16 gigabytes of RAM).
One way you can fix the memory error is by exploiting one aspect of your function - you are simply checking how many "a"'s fit in a string s repeated up to a length of n. So, instead of doing converged = s*n and subsequent modifications that require a lot of memory to store such a large string, you can instead use simple math to get the answer you are looking for.
Also, another optimization you could do is that you do not have to convert your string into an array to loop over it. Instead of doing for x in got_it, you could do for c in s.
Here is a working example of how you can accomplish what you need:
import math
def repeatedString(s, n):
if len(s) == 0:
return 0
reps = float(n) / len(s)
count = 0
for c in s:
if c == "a":
count += 1
# After testing the code, it turns out that Python does not play nicely
# with rounding UP from 0.5, so this is necessary to get the correct answer
result = count * reps
if result - math.floor(result) < 0.5:
return math.floor(result)
return math.ceil(result)
s = input()
n = int(input())
result = repeatedString(s, n)
print(result)
this program
takes a input string named s
repeats this string concatenated n times
takes only the first n charactes in the concatenated
counts how many times the letter "a" appears
you
you give the string "a"
you give the number 1000000000000
then the program should count and return 1000000000000
memmory problem
I guess this string with 1000000000000 letters "a" is too big
for the type in the python language
or for the computer memmory
the way it is
given that the program searches for the fixed occurrences of letter "a"
you passed exactly the letter "a" and the number 1000000000000
the better way is that it's not necessary a program
if you want to know how many times there is the letter "a"
in a string with 1000000000000 letters "a"
the answer is obviously 1000000000000
extra:
it would be complicated:
to rewrite the program
to search for a pattern
given as input parameter,
with variable length
AND
avoid the memmory problem
I guess I would write a program that
concatenates the "s" input just to have a length bigger than the searched pattern (if already not is)
check if the pattern occurs
after that multiply by "n"
ajust the how many times it will 'fit' in the final
one-line solution: find no of 'a' in string s, multiply with floor division of no.of repetition with the length of s + finding 'a' in the remaining length of s
s.count("a") * (n // len(s)) + s[:n % len(s)].count("a")
Thanks for all the help guys, I managed to solve the problem by handling the exception using try and except MemoryError
So I'm trying to make a program to find the thirteen adjacent digits in the 1000-digit number that have the greatest product. This is a problem for the Euler project and i keep running into error message:
TypeError: can't multiply sequence by non-int of type 'list'
here is the code though i shortend the 1000 digit number down for this post:
import operator
from functools import reduce
allDigits = 73167176531330624919225119674426574742355349194934969835203127745063262395783180169848018694788518438586156078911294949545950173795833195285320880551112540698747158
d = [int(d) for d in str(allDigits)]
digits = d[:13]
products = []
del d[:13]
while len(d) > 0:
tempProd = 1
for i in digits:
tempProd *= i
products.append(tempProd)
nextDigit = d[:1]
del digits[:1]
digits.append(nextDigit)
del d[:1]
products.sort()
print(products)
I am running into the problem in the line where it says:
tempProd *= i
This is really confusing me as neither of the values should be a list, i have tried using the numpy product function aswell as creating my own function which runs into the same problem and looks like this:
def prod(x):
return reduce(operator.mul, int(x), 1)
Any help would be much apreciated you can find more information about the problem im trying to solve here:
https://projecteuler.net/problem=8
The problem is these two lines:
nextDigit = d[:1] # returns a list
digits.append(nextDigit)
d[:1] returns a list which is then appended to the digits list so when you read it in the for loop you are multiplying i by a list value.
One way to fix this is to simply just do
nextDigit = d[:1][0]
Whenever I use permutations, I have to create a list of the permutations because it returns a 'itertools.permutations object at 0x0190A5D0'. Then after I create the list, I have to combine the strings in each list so that I have the permutation I wanted originally. If it is a number, then I have to make them all integers again.
Two part question:
1) Is there an easier way to do a permutation and create the list of numbers?
2) Below I've created a permutation of a number with 5 digits. However, where I have '12345', I want the user to input their own number. Thus the formatting string b=['s%s%s...] will have to be n %s and n x. Anyone know how to do this?
(FYI my program is trying to find the next largest number with the same digits given a user's input so 12345 next largest is 12354)
Both questions were answered below please see both responses. Thanks!!!
def nexthighest():
from itertools import permutations
numb = str(12345)
a = list(permutations(numb))
b = ['%s%s%s%s%s' % xxxxx for xxxxx in a] #<-- this is where the n length problem occurs
c = list(map(int,b))
for i in c:
if i >12345:
print(i)
break
You don't need to build all those lists. Just loop over the return value from permutations, joining and parsing as an integer each permutation as it comes by:
def nexthigher(n):
for p in permutations(sorted(str(n))):
i = int("".join(p))
if i > n:
return i
I can answer part two for you:
b = ["".join(x) for x in a]