Project Euler #11 in python - python

I am attempting to do project euler #11 (http://projecteuler.net/problem=11) , but I keep on incorrectly getting 51267216 as my answer and I can't figure out why. Right now I start by formatting the grid as a 2d array and then I iterate through all of the numbers, excluding the outside 3. Then I iterate through the 8 different directions and test for all of them. If its larger than the current largest then I store it as "top" Any help would be appreciated.
import pprint
def neg(l):
for a in l:
if a<0:
return True
return False
tg="""08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48"""
grid=tg.split("\n")
for a in range(0, len(grid)):
i=grid[a]
i=i.split(" ")
for b in range(0, len(i)):
i[b]=int(i[b])
grid[a]=i
top=0
for y in range(0, 19):
for x in range(0, 19):
for b in range(-1, 2):
for c in range(-1, 2):
if b+c!=0:
try:
factors=[grid[x][y],grid[x+b][y+c],grid[x+(b*2)][y+(c*2)],grid[x+(b*3)][y+(c*3)]]
if not neg(factors):
cur=grid[x][y]*grid[x+b][y+c]*grid[x+(b*2)][y+(c*2)]*grid[x+(b*3)][y+(c*3)]
if cur>top:
top=cur
except IndexError:
pass
print(top)

You have two major problems, first:
except IndexError:
doesn't catch all invalid quadruples, since Python lists allow negative indexing (list[-k] is list[len(list)-k]), so you also check quadruples wrapping around the end of the grid.
Second,
if b+c!=0:
excludes a direction from being considered at all - the direction in which the maximal product is located, at that. Find the correct condition to exclude (0,0).
Third (yes, I know I said two above, but this isn't major, perhaps),
for b in range(-1, 2):
for c in range(-1, 2):
checks the same direction twice, once for (b,c) and once for (-b,-c).

This is too long but it answer in 0.003 second
import time
start_time = time.time()
num = "08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 \
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 \
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 \
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 \
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 \
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 \
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 \
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 \
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 \
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 \
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 \
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 \
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 \
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 \
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 \
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 \
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 \
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 \
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 \
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48"
def product(num):
rightup = 0
right = 0
rightdown = 0
down = 0
if not (17 <= i <= 19 or 37 <= i <= 39 or 57 <= i <= 59 or 77 <= i <= 79 \
or 97 <= i <= 99 or 117 <= i <= 119 or 137 <= i <= 139 or 157 <= i <= 159 \
or 177 <= i <= 179 or 197 <= i <= 199 or 217 <= i <= 219 or 237 <= i <= 239 \
or 257 <= i <= 259 or 277 <= i <= 279 or 297 <= i <= 299 or 317 <= i <= 319 \
or 337 <= i <= 339 or 357 <= i <= 359 or 377 <= i <= 379 or 397 <= i <= 399):
if i <= 339:
rightdown = my_list[i] * my_list[i + 21] * my_list[i + 42] * my_list[i + 63]
right = my_list[i] * my_list[i+1] * my_list[i+2] * my_list[i+3]
if i >= 60:
rightup = my_list[i] * my_list[i-19] * my_list[i-38] * my_list[i-57]
greatest_product = 0
if i <= 339:
down = my_list[i] * my_list[i+20] * my_list[i+40] * my_list[i+60]
greatest_product = greatest_product
return max(rightdown,right,rightup,down)
my_list = []
andis = 0
while andis < len(num):
number = num[andis] + num[andis + 1]
andis += 3
my_list.append(int(number))
m = 0
for i in range(0,400):
if product(i) > m:
m = product(i)
print("the biggest priduct is: ",m)
print("this code took {} seconds".format(time.time()-start_time))

Related

Greatest product of four adjacent numbers in a grid (#11 Euler)

There are already many questions on stackoverlow regarding question 11 of Euler project. However I would like to figure out what is the mistake in my code.
Here is the python code:
a=[['08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08'],
['49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00'],
['81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65'],
['52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91'],
['22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80'],
['24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50'],
['32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70'],
['67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21'],
['24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72'],
['21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95'],
['78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92'],
['16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57'],
['86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58'],
['19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40'],
['04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66'],
['88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69'],
['04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36'],
['20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16'],
['20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54'],
['01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48']]
b=[]
for i in range(len(a)):
b.append(a[i][0].split(' '))
Sum=1
currentSum=1
#Loop for checking horizontally adjacent sum
for x in range(20):
for y in range(16):
for z in range(4):
currentSum*=int(b[x][y+z])
if currentSum>Sum:
Sum=currentSum
currentSum=1
#Loop for checking vertically adjacent sum
for x in range(0, 16):
for y in range(0, 20):
for z in range(0, 4):
currentSum*=int(b[x+z][y])
if currentSum>Sum:
Sum=currentSum
currentSum=1
#Loop for checking diagonally adjacent sum (\)
for x in range(0, 16):
for y in range(0, 16):
for z in range(4):
currentSum*=int(b[x+z][y+z])
if currentSum>Sum:
Sum=currentSum
currentSum=1
#Loop for checking diagonally adjacent sum(/)
for x in range(3, 20):
for y in range(3, 20):
for z in range(4):
currentSum*=int(b[x-z][y-z])
if currentSum>Sum:
Sum=currentSum
currentSum=1
print(Sum)
My approach to the question:
I had manually made the grid provided into a 20 x 1 2D list. However since I need a 20 x 20 2D list, I created a new one wherein the inner list items are the results of split function upon the first list items.
I have four nested loops, each for checking the products in one of the directions mentioned
The final answer yielded is 51267216, which according to Project Euler is wrong.
I would like to know where I am going wrong, and some guidance in this direction without revealing the answer itself.
Another thing to note is I am trying to get this solved without any additional libraries like numpy.
I've finally figured out the mistake - the problem has arisen due to the use of incorrect indexing formula in the last for loop.
The correct code is:
#Loop for checking diagonally adjacent sum
for x in range(0, 16):
for y in range(3, 20):
for z in range(4):
currentSum*=int(b[x+z][y-z]) //originally: b[x-z][x-y]
if currentSum>Sum:
Sum=currentSum
currentSum=1
b[x+z][y-z] instead of b[x-z][y-z]
To add on, here are the pictorial representations of all four loops:
1st Loop:
2nd loop:
3rd Loop:
4th loop:

Unable to return correct output from created function in JES

I am fairly new to jython and I am inquiring about creating a function that is dealing with a list. Basically what I am trying to do with the below function is create a function that will loop through the entirety of my list, then find the lowest value within that list and return the variable with the lowest number. Though, I keep getting a return of function min at 0x26 everytime I execute the main() I receive the same message but it seems as if the function min at 0x26 will count up ex: 0x27, 0x28... Not sure why this is. As my list only contains integers of minimum 0 to max 99.
Here is the sourcecode:
def min(dataset): #defining a function minimum, with input dataset(the list we are using)..
min = dataset[0]
for num in range(0, len(dataset)):
if dataset[num] < min:
min = dataset(num)
return min
minimum = min(dataset)
print(str(minimum))
Here is the code in its entirety. Though, I currently have a way to find the min/max values in the list. I am looking to move towards a function, as I want to know how to correctly use a function.
def main( ):
dataset = [0]
file = open("D:\numbs.dat", "r")
for line in file: #loop for writing over every line to a storage loc.
num = int(float(line)) #converting int to string
dataset.append(num) #appending the data to 'dataset' list
max = dataset[0] #setting an imaginary max initially
low = dataset[0] #setting an imaginary low initially
for i in range(0, len(dataset)): #for loop to scan thru entire list
if dataset[i] > max: #find highest through scan and replacing each max in var max
max = dataset[i]
if dataset[i] < low: #find lowest through scan and replacing each max in var max
low = dataset[i]
#printNow(dataset) #printing the list in its entirety
#printNow("The maximum is " +str(max)) #print each values of lowest and highest
#printNow("The lowest is " +str(low))
def min(dataset): #defining a function minimum..
min = dataset[0]
for num in range(0, len(dataset)):
if dataset[num] < min:
min = dataset(num)
return min
minimum = min(dataset)
print(str(minimum)) #test to see what output is.
As mentioned above, there is the for loop for finding max/min values. Though I tried doing the same exact thing for the function I am trying to create...
the contents of the numbs.dat can be found here (1001 entries):
70
75
76
49
73
76
52
63
11
25
19
89
17
48
5
48
29
41
23
84
28
39
67
48
97
34
0
24
47
98
0
64
24
51
45
11
37
77
5
54
53
33
91
0
27
0
80
5
11
66
45
57
48
25
72
8
38
29
93
29
58
5
72
36
94
18
92
17
43
82
44
93
10
38
31
52
44
10
50
22
39
71
46
40
33
51
51
57
27
24
40
61
88
87
40
85
91
99
6
3
56
10
85
38
61
91
31
69
39
74
9
17
80
96
49
0
47
68
12
5
6
60
81
51
62
87
70
66
50
30
30
22
45
35
2
39
23
63
35
69
83
84
69
6
54
74
3
29
31
54
45
79
21
74
30
77
77
80
26
63
84
21
58
54
69
2
50
79
90
26
45
29
97
28
57
22
59
2
72
1
92
35
38
2
47
23
52
77
87
34
84
15
84
13
23
93
19
50
99
74
59
4
73
93
29
61
8
45
10
20
15
95
58
43
75
19
61
39
68
47
69
58
88
82
33
30
72
21
74
12
18
0
52
50
62
21
66
26
56
84
16
12
7
45
58
22
26
95
82
6
74
12
16
2
61
58
22
39
0
53
88
79
71
13
54
25
31
93
48
91
90
45
23
54
42
39
78
25
95
58
2
41
61
72
98
91
48
97
93
11
12
1
35
80
81
86
38
70
67
55
55
87
73
79
31
43
97
79
3
51
17
58
70
34
59
61
28
46
13
42
18
0
18
75
75
62
50
62
85
49
83
71
63
32
27
59
42
46
8
13
39
25
13
94
17
48
73
40
31
31
86
23
81
40
92
24
94
67
30
18
74
78
62
89
1
27
95
99
33
53
74
5
84
88
8
52
0
24
21
99
1
74
84
94
29
25
83
93
98
40
21
66
93
28
72
63
77
9
71
18
87
50
77
48
68
88
22
33
16
79
68
69
94
64
5
28
33
22
21
74
44
62
68
47
93
69
9
42
44
87
64
97
42
34
90
70
91
12
18
84
65
23
99
1
55
6
1
23
92
50
96
96
68
27
17
98
42
10
27
26
20
13
94
73
75
12
12
25
33
1
33
67
61
0
98
71
35
75
68
56
45
11
1
69
57
9
15
96
69
2
0
65
44
86
78
97
17
4
81
23
4
43
24
72
70
57
21
91
84
94
40
96
40
78
46
67
6
7
16
49
24
14
12
82
73
60
42
76
62
10
84
49
75
89
43
47
31
68
15
11
32
37
98
72
40
25
69
30
64
60
48
21
11
74
54
24
60
10
96
29
39
53
48
24
68
4
52
12
6
91
15
86
77
65
68
22
91
36
72
82
81
9
77
0
5
83
27
88
17
35
66
76
78
81
19
51
87
66
26
59
65
2
37
37
73
34
98
37
78
92
17
52
62
40
50
84
34
22
25
42
90
19
86
76
68
42
9
89
57
78
64
89
12
34
94
9
77
58
32
27
97
93
79
35
32
75
97
79
65
90
53
43
98
4
99
5
79
38
99
60
78
64
90
2
39
42
52
2
21
77
15
8
87
13
0
4
7
43
76
31
74
16
87
50
73
49
14
35
10
37
91
44
88
71
95
75
98
7
17
23
13
16
77
20
50
50
74
78
58
30
21
74
76
93
5
74
94
83
23
67
18
5
50
47
56
79
26
84
78
48
71
43
41
8
91
23
7
11
96
87
12
42
32
44
99
67
99
64
96
52
19
79
60
66
52
62
17
61
54
24
25
36
4
78
3
94
91
62
65
76
94
2
52
25
61
55
49
88
85
96
5
46
56
48
17
25
3
70
62
3
50
45
47
58
12
41
27
42
90
91
71
53
4
79
47
68
43
87
35
63
10
49
4
81
45
88
80
6
92
47
70
40
7
33
70
61
30
9
55
42
83
26
72
57
77
91
13
15
33
13
62
49
43
65
73
98
59
56
77
62
12
25
33
53
78
73
1
17
44
56
95
10
33
89
33
20
56
69
66
60
53
83
58
43
33
25
21
8
28
65
51
70
53
78
49
30
64
17
76
9
2
32
87
77
39
25
21
66
65
54
81
49
15
27
7
14
4
11
94
9
84
23
13
95
45
67
57
20
3
58
50
97
35
68
47
41
84
59
46
34
19
25
77
29
41
89
80
61
70
40
1
18
32
70
86
76
25
98
99
40
43
92
43
4
70
78
72
71
85
14
84
73
92
60
23
57
44
56
6
96
39
91
63
43
39
71
80
18
93
54
1
4
46
68
93
74
74
88
52
88
55
24
19
92
53
59
1
91
48
47
Let me know what the heck I am doing wrong. Thanks!
#ohGosh welcome to stack overflow. You are almost there with the solution. There are few problems with your program
1) Nums.dat file contains just one line with numbers separated by spaces, not a new line(\n). In order to get the read the numbers from the file do the following
dataset = [] #Create an empty list
file = open("D:\numbs.dat", "r") #Open the file
for line in file:
tempData = line.split(" ") #Returns a list with space used as delimiter
dataset = map(int, tempData) #Convert string data to int
2) Wrong way to get data from a list in the min function
Use
min = dataset[num]
Instead of
min = dataset(num)
Fix this and your program will work. Cheers.

How to trace what cause "IndexError: list index out of range" and how to find prod(column)?

Here is the list and I have already convert it to 20 x 20 list.. ?
import numpy as np
a = \
'08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 '\
'49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 '\
'81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 '\
'52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 '\
'22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 '\
'24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 '\
'32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 '\
'67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 '\
'24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 '\
'21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 '\
'78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 '\
'16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 '\
'86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 '\
'19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 '\
'04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 '\
'88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 '\
'04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 '\
'20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 '\
'20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 '\
'01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48'
Here how I convert the list to 20x20 matrix;
# rearrange a
a = a.split(' ')
# map a.str to a.int
a = [int(x) for x in a]
# create b = 20x20 matrix
b = [[ 0 for x in range(20)]for y in range(20)]
# assign b[i][j] = a[i] and set k = i for a[i]
k = 0
for i in range(20):
for j in range(20):
b[i][j] = a[k]
k += 1
I got this error :
Traceback (most recent call last):
File "C:/Users/Me/PycharmProjects/SEMUA/Euler/Euler11.py", line 55, in <module>
if np.product(b[i:i+4][j]) > largest:
IndexError: list index out of range
which refer to this part;
#column
for j in range(0,20):
for i in range(0, 17):
if np.product(b[i:i+4][j]) > largest:
largest = np.product(b[i:i+4][j])
Why there is no same error here even though I use the same numbering;
#row
for i in range(0,20):
for j in range(0,17):
if np.product(b[i][j:j+4]) > largest:
largest = np.product(b[i][j:j+4])
I notice that it work if it is a row but not if it is a column.
How can I fix this?
How can I extract a column from my 2-D list?
First, your initialization of the array could be done much easier:
aa = np.array(list(map(int, a.split())), dtype = np.int)
aa.shape = [20, 20]
You used ][, which means that first you create a view of 4 rows, then you try to select the 19th row from this -- obviously not possible. Use ,, then your indices will refer to different axes. I don't know what do you want to do, but if you want to find the consecutive 4 elements with the highest product in your array, this gonna do for you:
largest = 0
for i in range(0, 20):
for j in range(0, 17):
if np.product(aa[i, j:j+4]) > largest:
largest = np.product(aa[i, j:j+4])
Same for columns:
largest = 0
for i in range(0, 20):
for j in range(0, 17):
if np.product(aa[j:j+4, i]) > largest:
largest = np.product(aa[j:j+4, i])

Project Euler 11 [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm having some trouble with my Project Euler code in Python -- When I run through the code in my head everything seems to check out, but I'm still getting the wrong answer. I'm really new to Python, so it could be any number of things. Any suggestions? Thanks in advance!
nums = '\
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08\n\
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00\n\
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65\n\
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91\n\
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80\n\
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50\n\
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70\n\
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21\n\
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72\n\
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95\n\
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92\n\
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57\n\
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58\n\
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40\n\
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66\n\
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69\n\
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36\n\
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16\n\
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54\n\
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48'
grid = []
diag = []
for line in nums.split('\n'):
grid.append(map(int, line.split(' ')))
i=0
j=0
while i<17:
l = grid[i][j]*grid[i+1][j+1]*grid[i+2][j+2]*grid[i+3][j+3]
diag.append(l)
i+=1
if i==17:
j+=1
i=0
l = grid[i][j]*grid[i+1][j+1]*grid[i+2][j+2]*grid[i+3][j+3]
diag.append(l)
if j==16:
break
print max(diag)
My comments are more along the lines of code review, but culminating in a full solution:
You can get rid of those ugly endline escapes with the textwrap module (implicit string concatenation would work too, but it would mean more repetitious typing and clutter):
import textwrap
nums = textwrap.dedent('''\
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48''')
grid = []
Use the string builtin method, splitlines, and list comprehensions are somewhat more readable than map (as well as not needing to be wrapped with a list call to be forward compatible with Python 3):
for line in nums.splitlines():
grid.append([int(i) for i in line.split(' ')])
Now we have our data, and we can begin our search algorithm. Since the horizontals are already in rows together, we can easily search by row, and since zip stops on the shortest iterable, we can safely zip up slices of the same string starting at increasing points from the beginning without getting index errors:
def max_horizontal(grid):
return max(w * x * y * z
for r in grid
for w, x, y, z in zip(r, r[1:], r[2:], r[3:]))
Vertical is not much more tricky, but we want to transpose it like it was a matrix, and then we can use the same code around it. Expanding an iterable of iterables into zip is the same as transposing such a matrix that we can iterate over:
def max_vertical(grid):
return max(w * x * y * z
for c in zip(*grid)
for w, x, y, z in zip(c, c[1:], c[2:], c[3:]))
Diagonals are a bit more difficult, but if we get one definition right, we just reverse it. Here, we need to go row by row over a window across the matrix, so we treat the matrix like we treated the row with zip. So we step over the matrix one row at a time, looking at 4 rows each time. Next, using the slash semantic to indicate the diagonal running from bottom left to top right, in our first row, we start at the fourth element (keeping in mind, Python starts indexing at 0, so that corresponds to the [3:] slice notation below), second row, 3rd element, third row, second element, 4th row, the first element. Again, since zip stops at the end of the shortest iterable, our window doesn't run out of range of the matrix:
def max_slashdiag(g=grid):
return max(w * x * y * z
for r1, r2, r3, r4 in zip(g, g[1:], g[2:], g[3:])
for w, x, y, z in zip(r1[3:], r2[2:], r3[1:], r4))
To get the other diagonal, just reverse the corresponding row starting points:
def max_backdiag(g=grid):
return max(w * x * y * z
for r1, r2, r3, r4 in zip(g, g[1:], g[2:], g[3:])
for w, x, y, z in zip(r1, r2[1:], r3[2:], r4[3:]))
And we take the maximum of all of these functions:
max(max_horizontal(grid),
max_vertical(grid),
max_slashdiag(g=grid),
max_backdiag(g=grid))
which returns 70600674

Create Grids in Python

Question : I want to create a grid like this.
08 06 78 56 96
45 63 68 23 51
63 78 45 08 37
56 73 92 73 83
43 22 67 98 55
Once I created this grid, I want to find the product of four adjacent numbers in the same direction (up, down, left, right, or diagonally)?
How can I do this?
I searched a lot and found an answer. They suggested to use N-dimensional array. But I don't know how to do that?
When you specify a backslash at the end of the string, it will allow you to continue the current string along to the next line. So let's first think about the simplest way we can stuff that grid of numbers into our code, a simple string with lines separated by newline characters!
Try doing something like this:
nums = '\
08 06 78 56 96\n\
45 63 68 23 51\n\
63 78 45 08 37\n\
56 73 92 73 83\n\
43 22 67 98 55'
grid = []
for line in nums.split('\n'):
grid.append(map(int, line.split(' ')))
And then you can print your grid with:
>>> print grid
[[8, 6, 78, 56, 96], [45, 63, 68, 23, 51], [63, 78, 45, 8, 37], [56, 73, 92, 73,
83], [43, 22, 67, 98, 55]]
The grid will be a two-dimensional list which can be queried by first specifying the row, then the column. For example if you wish to get an element from 4th row and the 2nd column, you could do:
>>> print grid[3][1] # it's 3, 1 because lists are 0-indexed
73
And that would correctly give you 73 because if you look at your original grid:
08 06 78 56 96
45 63 68 23 51
63 78 45 08 37
56 73 92 73 83
43 22 67 98 55
73 is on row 4 and column 2. Good luck with Project Euler.
Edit:
You might lack a nice source code editor so here is the Problem 11 grid from Project Euler nicely laid out in string format for you to parse and do what you please with it. :)
nums = '\
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08\n\
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00\n\
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65\n\
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91\n\
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80\n\
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50\n\
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70\n\
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21\n\
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72\n\
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95\n\
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92\n\
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57\n\
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58\n\
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40\n\
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66\n\
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69\n\
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36\n\
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16\n\
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54\n\
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48'

Categories