I'm currently trying to do some of the Project Euler questions. I'm currently on question 8 and I'm using python to solve it.
I made some code and got an answer, which turns out to be incorrect. I'm not sure what the problem is with my code, so I'd be grateful is someone could tell me what the issue is. I'm getting an answer of 56435097600, which is the 13 numbers multiplied together on the 30th column with an offset of 6, so it starts 7894... Here's my code, it's not very efficient or neat, but I just want to know what the issue is, not change my code to make it neater/more effective.
rows = ['73167176531330624919225119674426574742355349194934','96983520312774506326239578318016984801869478851843','85861560789112949495459501737958331952853208805511',
'12540698747158523863050715693290963295227443043557','66896648950445244523161731856403098711121722383113','62229893423380308135336276614282806444486645238749',
'30358907296290491560440772390713810515859307960866','70172427121883998797908792274921901699720888093776','65727333001053367881220235421809751254540594752243',
'52584907711670556013604839586446706324415722155397','53697817977846174064955149290862569321978468622482','83972241375657056057490261407972968652414535100474',
'82166370484403199890008895243450658541227588666881','16427171479924442928230863465674813919123162824586','17866458359124566529476545682848912883142607690042',
'24219022671055626321111109370544217506941658960408','07198403850962455444362981230987879927244284909188','84580156166097919133875499200524063689912560717606',
'05886116467109405077541002256983155200055935729725','71636269561882670428252483600823257530420752963450',]
columns = []
def createcolumns():
global rows,columns
for x in range(0,50):
tempvalue = ''
for j in range(0,20):
tempvalue = tempvalue + rows[j][x]
columns.append(tempvalue)
def multiply(string):
tempvalue = 1
for letters in string:
tempvalue *= int(letters)
return tempvalue
def highestnumber():
global rows,columns
highest = 0
# 37 ways per row * 20 + 7 ways per column * 50
for x in range(0,20):
for g in range(0,37):
tempvalue = ''
for j in range(0,13):
tempvalue = tempvalue + rows[x][j+g]
tempvalue = multiply(tempvalue)
if(tempvalue > highest):
highest = tempvalue
for x in range(0,50):
for g in range(0,7):
tempvalue = ''
for j in range(0,13):
tempvalue = tempvalue + columns[x][j+g]
tempvalue = multiply(tempvalue)
if(tempvalue > highest):
highest = tempvalue
return highest
createcolumns()
print(highestnumber())
Output:
>> 56435097600
Well, the purpose is to solve this yourself.
However, I would like to point out the flaw in your understanding of this question and you can pick up from there.
The question talks about a "1000 digit" number.
That means, all the 20 rows of 50 digits need to be merged into 1 single number of 1000 digits.
It's been given in a matrix form just for good visibility.
So approaching this problem with rows X columns may not help.
Your logic would work well for the 4 digit number since it is all in 1 row.
And since your logic's failing for a 13 digit number, my guess is that the 13 digits do not fall in 1 single row.
If I'm not wrong.
Related
I am trying to improve my run time of my python code.
The code should inputs as the following:
3
5 1
6 1
8 2
4
7
1
7
3
The first number (3) represents the number of following box sizes as well as how many are on hand for each size
The next number (4) tells us the size of each order. We are not allowed to use a box to pack a specific item, if a smaller box can be used or ordered instead and the box has to strictly be bigger than the product.
The code should return:
5 1
I have working code to do this. It is attached. However I want to speed up my run time using binary search and I was wondering if anyone could help me with this as I am running into errors.
def amount_of_boxes_to_order(boxes, orders, orders_to_place):
for order in orders:
for box in orders_to_place:
if box[0] > order:
box[1] += 1
break
final_return = []
for i in range(len(orders_to_place)):
if orders_to_place[i][0] == boxes[i][0]:
diff = orders_to_place[i][1] - boxes[i][1]
if diff > 0:
new_tuple = [orders_to_place[i][0], diff]
final_return.append(new_tuple)
for answer in final_return:
print(str(answer[0]) + ' ' + str(answer[1]))
n = input()
boxes_input = []
orders_to_place_input = []
for q in range(int(n)):
user_input = [int(x) for x in input().split()]
boxes_input.append(user_input)
orders_to_place_input.append([user_input[0], 0])
orders_input = []
x = input()
for p in range(int(x)):
input_from_user = [int(x) for x in input().split()]
orders_input.append(input_from_user[0])
amount_of_boxes_to_order(boxes_input, orders_input, orders_to_place_input)
Any help is greatly appreciated!
I have been coding for around half a year in uni and have done some side projects. This is one of them and although my code works for integers, I would like to know how it could be optimised using less lines of code. Coding at uni has taught me how to create many programs but not really how to optimise code and so any further tips would be greatly appreciated! <3
num = int(1230124013502)
def rem(num):
"""
Rem function separates the thousands in an intiger and converts to
a string. Function takes one input (num) which must be of intiger
form. Rem converts to string with commas separating the thousands
"""
num = str(num)
l = len(num)
remain = l%3
sum = ''
if remain == 0:
remain = 3
new = num[remain:]
pre = num[:remain]
#print(pre,new,remain)
l_new = len(new)
zeros = []
for i in range(3,l_new+3,3):
j = i - 3
post = new[j:i] + ','
zeros.append(post)
for i in range(len(zeros)):
sum += zeros[i]
tot = pre + ',' + sum
endpoint = len(tot) - 1
tot = tot[0:endpoint]
if l < 4:
print(num)
return num
else:
print(tot)
return tot
rem(num)
I have been trying to write code for the activity selection problem. I am not using the greedy algorithm method but I just wrote this code on my own. My cod is able to find the max number of activities possible, but in my code, I am having a problem with the input. Here's my code:
i = int(input("How many activities are there? Please enter as an integer. "))
list_of_lists = [[[]], [], []]
def check(space):
x = space.split(" ")
for b in range(2):
x[b] = int(x[b])
if (x[0] >= x[1]):
space = input("Incorrect start and end times. Please enter a start time which is less than the end time. ")
check(space)
return space
return space
#ab = space
#return ab
for a in range(1, i + 1):
arr = input("Please enter the start time and end time. There should be a space between the two integers. ")
abc = check(arr)
print(abc)
list_of_lists[a].append(list(map(int, abc.split(' '))))
list_of_lists[0].append(list(map(int, abc.split(' '))))
print(list_of_lists)
count = [0] * i
inn = 0
for ii in range(1, i + 1):
for jj in range(1, i + 1):
if (ii != jj):
if (list_of_lists[ii][0][0] <= list_of_lists[0][jj][0]):
a = list_of_lists[ii][0][1]
b = list_of_lists[0][jj][0]
else:
a = list_of_lists[0][jj][1]
b = list_of_lists[ii][0][0]
if (a <= b):
count[inn] += 1
else:
count[inn] += 1
inn += 1
count.sort()
print(count[i - 1])
So there is a problem with the check function. It is working perfectly when I have the correct type of input. But say, if someone inputs the wrong type of input, then there is a problem. Let me describe with an example.
If I input 2 4 to arr = ..., then it is working properly. If I input 6 5 to arr = ... and then if I input 2 4 to space = input(..., it is working properly. However, if say I input 6 5 to arr = ..., then I input 5 4 to space = input(..., and then I input 2 4 to space = input(..., then it is not working properly. check function is returning 5 4. I know the problem is with the return but I really do not know how to solve this issue so that it works in the right way.
I am doing the Project Euler #67 in Python. My program, which worked for Project 18, does not work for Project 67.
Code (excludes the opening of the file and the processing of information):
for i in range(len(temp)):
list1 = temp[i]
try:
list2 = temp[i+1]
trynum1 = list1[lastinput] + max(list2[lastinput],list2[lastinput+1])
try:
trynum2 = list1[lastinput+1] + max(list2[lastinput+1],list2[lastinput+2])
if trynum1 > trynum2:
outputlist.append(list1[lastinput])
else:
outputlist.append(list1[lastinput+1])
lastinput += 1
except IndexError:
outputlist.append(list1[0])
except IndexError:
if list1[lastinput] > list1[lastinput+1]:
outputlist.append(list1[lastinput])
else:
outputlist.append(list1[lastinput+1])
Variables:
temp is the triangle of integers
outputlist is a list which stores the numbers chosen by the program
I know the answer is 7273, but my program finds 6542. I cannot find an error which causes the situation. Please may you help me on it.
Logic
My approach to this program is to find one number (list1[lastinput]) and add it up with the larger number of the two below it (trynum1), compare with the number to the right of the first number (list1[lastinput+1]), adding the larger number of two below it (trynum2). I append the larger one to the output list.
This approach is logically flawed. When you're in row 1, you don't have enough information to know whether moving right or left will lead you to the largest sum, not with only a 2-row lookahead. You would need to look all the way to the bottom to ensure getting the best path.
As others have suggested, start at the bottom and work up. Remember, you don't need the entire path, just the sum. At each node, add the amount of the better of the two available paths (that's the score you get in taking that node to the bottom). When you get back to the top, temp[0][0], that number should be your final answer.
I thought day and night about problem 18 and I solved it, the same way I solved this one.
P.S. 100_triangle.txt is without 1st string '59'.
# Maximum path sum II
import time
def e67():
start = time.time()
f=open("100_triangle.txt")
summ=[59]
for s in f:
slst=s.split()
lst=[int(item) for item in slst]
for i in range(len(lst)):
if i==0:
lst[i]+=summ[i]
elif i==len(lst)-1:
lst[i]+=summ[i-1]
elif (lst[i]+summ[i-1])>(lst[i]+summ[i]):
lst[i]+=summ[i-1]
else:
lst[i]+=summ[i]
summ=lst
end = time.time() - start
print("Runtime =", end)
f.close()
return max(summ)
print(e67()) #7273
Though starting from the bottom is more efficient, I wanted to see if I could implement Dijkstra's algorithm on this one; it works well and only takes a few seconds (didn't time it precisely):
from math import inf
f = open("p067_triangle.txt", "r")
tpyramid = f.read().splitlines()
f.close()
n = len(tpyramid)
pyramid = [[100 - int(tpyramid[i].split()[j]) for j in range(i+1)] for i in range(n)]
paths = [[inf for j in range(i+1)] for i in range(n)]
paths[0][0] = pyramid[0][0]
def mini_index(pyr):
m = inf
for i in range(n):
mr = min([i for i in pyr[i] if i >= 0]+[inf])
if mr < m:
m, a, b = mr, i, pyr[i].index(mr)
return m, a, b
counter = 0
omega = inf
while counter < n*(n+1)/2:
min_weight, i, j = mini_index(paths)
if i != n-1:
paths[i+1][j] = min( paths[i+1][j], min_weight + pyramid[i+1][j])
paths[i+1][j+1] = min( paths[i+1][j+1], min_weight + pyramid[i+1][j+1])
else:
omega = min(omega, min_weight)
paths[i][j] = -1
counter += 1
print(100*n - omega)
Here is my solution. Indeed you have to take the bottom - up approach.
Result confirmed with PE. Thanks!
def get_triangle(listLink):
triangle = [[int(number) for number in row.split()] for row in open(listLink)]
return triangle
listOfLists = get_triangle('D:\\Development\\triangle.txt')
for i in range(len(listOfLists) - 2, -1, -1):
for j in range(len(listOfLists[i])):
listOfLists[i][j] += max(listOfLists[i+1][j], listOfLists[i+1][j+1])
print(listOfLists[0][0])
I have to write a program that proves Benford's Law for two Data lists. I think I have the code down for the most part but I think there are small errors that I am missing. I am sorry if this is not how the site is supposed to be used but I really need help. Here is my code.
def getData(fileName):
data = []
f = open(fileName,'r')
for line in f:
data.append(line)
f.close()
return data
def getLeadDigitCounts(data):
counts = [0,0,0,0,0,0,0,0,0]
for i in data:
pop = i[1]
digits = pop[0]
int(digits)
counts[digits-1] += 1
return counts
def showResults(counts):
percentage = 0
Sum = 0
num = 0
Total = 0
for i in counts:
Total += i
print"number of data points:",Sum
print
print"digit number percentage"
for i in counts:
Sum += i
percentage = counts[i]/float(Sum)
num = counts[i]
print"5%d 6%d %f"%(i,num,percentage)
def showLeadingDigits(digit,data):
print"Showing data with a leading",digit
for i in data:
if digit == i[i][1]:
print i
def processFile(name):
data = getData(name)
counts = getLeadDigitCounts(data)
showResults(counts)
digit = input('Enter leading digit: ')
showLeadingDigits(digit, data)
def main():
processFile('TexasCountyPop2010.txt')
processFile('MilesofTexasRoad.txt')
main()
Again sorry if this is not how I am supposed to use this site. Also, I can only use programming techniques that the professor has showed us so if you could just give me advice to clean up the code as it is I would really appreciate it.
Also, here are a few lines from my data.
Anderson County 58458
Andrews County 14786
Angelina County 86771
Aransas County 23158
Archer County 9054
Armstrong County 1901
Your error is coming from this line:
int(digits)
This doesn't actually do anything to digits. If you want to convert digits to an integer, you have to re-set the variable:
digits = int(digits)
Also, to properly parse your data, I would do something like this:
for line in data:
place, digits = line.rsplit(None, 1)
digits = int(digits)
counts[digits - 1] += 1
Lets walk though one cycle of your code and I think you'll see what the problem is. I'll be using this file here for data
An, 10, 22
In, 33, 44
Out, 3, 99
Now getData returns:
["An, 10, 22",
"In, 33, 44",
"Out, 3, 99"]
Now take a look the first pass though the loop:
for i in data:
# i = "An, 10, 22"
pop = i[1]
# pop = 'n', the second character of i
digits = pop[0]
# digits = 'n', the first character of pop
int(digits)
# Error here, but you probably wanted digits = int(digits)
counts[digits-1] += 1
Depending on how your data is structured, you need to figure out the logic to extract the digits you expect to get from your file. This logic might do better in the getData funciton, but it mostly depends on the specifics of your data.
Just to share here a different (and maybe more step-by-step) code. It's RUBY.
The thing is, Benford's Law doesn't apply when you have a specific range of random data to extract from. The maximum number of the data set that you are extracting random information from must be undetermined, or infinite.
In other words, say, you used a computer number generator that had a 'set' or specific range from which to extract the numbers, eg. 1-100. You would undoubtedly end up with a random dataset of numbers, yes, but the number 1 would appear as a first digit as often as the number 9 or any other number.
**The interesting** part, actually, happens when you let a computer (or nature) decide randomly, and on each instance, how large you want the random number to potentially be. Then you get a nice, bi-dimensional random dataset, that perfectly attains to Benford's Law. I have generated this RUBY code for you, which will neatly prove that, to our fascination as Mathematicians, Benford's Law works each and every single time!
Take a look at this bit of code I've put together for you!
It's a bit WET, but I'm sure it'll explain.
<-- RUBY CODE BELOW -->
dataset = []
999.times do
random = rand(999)
dataset << rand(random)
end
startwith1 = []
startwith2 = []
startwith3 = []
startwith4 = []
startwith5 = []
startwith6 = []
startwith7 = []
startwith8 = []
startwith9 = []
dataset.each do |element|
case element.to_s.split('')[0].to_i
when 1 then startwith1 << element
when 2 then startwith2 << element
when 3 then startwith3 << element
when 4 then startwith4 << element
when 5 then startwith5 << element
when 6 then startwith6 << element
when 7 then startwith7 << element
when 8 then startwith8 << element
when 9 then startwith9 << element
end
end
a = startwith1.length
b = startwith2.length
c = startwith3.length
d = startwith4.length
e = startwith5.length
f = startwith6.length
g = startwith7.length
h = startwith8.length
i = startwith9.length
sum = a + b + c + d + e + f + g + h + i
p "#{a} times first digit = 1; equating #{(a * 100) / sum}%"
p "#{b} times first digit = 2; equating #{(b * 100) / sum}%"
p "#{c} times first digit = 3; equating #{(c * 100) / sum}%"
p "#{d} times first digit = 4; equating #{(d * 100) / sum}%"
p "#{e} times first digit = 5; equating #{(e * 100) / sum}%"
p "#{f} times first digit = 6; equating #{(f * 100) / sum}%"
p "#{g} times first digit = 7; equating #{(g * 100) / sum}%"
p "#{h} times first digit = 8; equating #{(h * 100) / sum}%"
p "#{i} times first digit = 9; equating #{(i * 100) / sum}%"