Files
euler-project/problems/011_problem/011_problem.py
2020-08-02 21:06:44 -04:00

237 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# # Problem 11:
#
# [Euler Project #11](https://projecteuler.net/problem=11)
#
#
# > In the 20×20 grid below, four numbers along a diagonal line have been marked in red.
# >
# > 08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 <br>
# > 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 <br>
# > 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 <br>
# > 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 <br>
# > 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 <br>
# > 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 <br>
# > 32 98 81 28 64 23 67 10 **26** 38 40 67 59 54 70 66 18 38 64 70 <br>
# > 67 26 20 68 02 62 12 20 95 **63** 94 39 63 08 40 91 66 49 94 21 <br>
# > 24 55 58 05 66 73 99 26 97 17 **78** 78 96 83 14 88 34 89 63 72 <br>
# > 21 36 23 09 75 00 76 44 20 45 35 **14** 00 61 33 97 34 31 33 95 <br>
# > 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 <br>
# > 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 <br>
# > 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 <br>
# > 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 <br>
# > 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 <br>
# > 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 <br>
# > 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 <br>
# > 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 <br>
# > 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 <br>
# > 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48 <br>
# >
# > The product of these numbers is 26 × 63 × 78 × 14 = 1788696.
# >
# > What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid?
#
#
# ---
import os
import pprint
import time # Typically imported for sleep function, to slow down execution in terminal.
import typing
import decorators # Typically imported to compute execution duration of functions.
import math
import numpy
def check_horizontal(table,solution):
'''
Args:
table: list of lists representing the input table
solution: a dictionary storing the product, and three tuples of cell coordinates
'''
# Let's scan the horizontals first.
# Acceptable cells would have a root position (on the LHS) which may reside anywhere in the table,
# except for the last three columns.
# create a list of tuples to store cell coordinates while generating the products
cells=[(0,0),(0,0),(0,0),(0,0)]
# loop over row dimension
for row in range(len(table)):
# loop over column dimension
for column in range(len(table[row])-4):
# calculate product
product = 1
for i in range(4):
product *= table[row][column+i]
cells[i]=(row,column+i)
#print("product=",product)
if product>solution['product']:
solution['product']=product
solution['cella']=cells[0]
solution['cellb']=cells[1]
solution['cellc']=cells[2]
solution['celld']=cells[3]
return solution
def check_vertical(table,solution):
'''
Args:
table: list of lists representing the input table
solution: a dictionary storing the product, and three tuples of cell coordinates
'''
# Let's scan the verticals next.
# Acceptable cells would have a root position (at the top of column) which may reside anywhere in the table,
# except for the last three rows.
# create a list of tuples to store cell coordinates while generating the products
cells=[(0,0),(0,0),(0,0),(0,0)]
# loop over row dimension
count = 0
for row in range(len(table)-4):
# loop over column dimension
for column in range(len(table[row])):
# convert data type from string to int
product = 1
for i in range(4):
product *= table[row+i][column]
cells[i]=(row,column+i)
#print("product=",product)
count+=1
#print("count=",count)
if product>solution['product']:
solution['product']=product
solution['cella']=cells[0]
solution['cellb']=cells[1]
solution['cellc']=cells[2]
solution['celld']=cells[3]
return solution
def check_upwards_diagonals(table,solution):
'''
Args:
table: list of lists representing the input table
solution: a dictionary storing the product, and three tuples of cell coordinates
'''
# Let's scan the upward (left to right) diagonals next.
# Acceptable cells would have a root position (at the bottom-left of the diagonal) which may reside anywhere in the table,
# except for the first three rows, and the last three columns.
# create a list of tuples to store cell coordinates while generating the products
cells=[(0,0),(0,0),(0,0),(0,0)]
# loop over row dimension
count = 0
for row in range(len(table)-3):
# loop over column dimension
#print("row=",row)
for column in range(len(table[row])-3):
# convert data type from string to int
product = 1
for i in range(4):
product *= table[row+3-i][column+i]
cells[i]=(row+3-i,column+i)
#print("cell=[",row+3-i,"][",column+i,"]")
#print("product=",product)
count += 1
if product>solution['product']:
solution['product']=product
solution['cella']=cells[0]
solution['cellb']=cells[1]
solution['cellc']=cells[2]
solution['celld']=cells[3]
return solution
def check_downwards_diagonals(table,solution):
'''
Args:
table: list of lists representing the input table
solution: a dictionary storing the product, and three tuples of cell coordinates
'''
# Let's scan the downward (left to right) diagonals next.
# Acceptable cells would have a root position (at the top-left of the diagonal) which may reside anywhere in the table,
# except for the last three rows, and the last three columns.
# create a list of tuples to store cell coordinates while generating the products
cells=[(0,0),(0,0),(0,0),(0,0)]
# loop over row dimension
count = 0
for row in range(len(table)-3):
# loop over column dimension
#print("row=",row)
for column in range(len(table[row])-3):
# convert data type from string to int
product = 1
for i in range(4):
product *= table[row+i][column+i]
cells[i]=(row+i,column+i)
#print("cell=[",row+i,"][",column+i,"]")
#print("product=",product)
count += 1
#print("count=",count)
if product>solution['product']:
solution['product']=product
solution['cella']=cells[0]
solution['cellb']=cells[1]
solution['cellc']=cells[2]
solution['celld']=cells[3]
return solution
table = [ ['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']
]
# Firstly, this data input creates a list-of-lists which have cells of the ```string``` data type.
# loop over row dimension
for row in range(len(table)):
# loop over column dimension
for column in range(len(table[row])):
# convert data type from string to int
table[row][column] = int(table[row][column])
# create a dictionary that stores information about the solution
solution = {
'product':1,
'cella':(0,0),
'cellb':(0,0),
'cellc':(0,0),
'celld':(0,0)
}
# We know brute force will work...
# Can we can scan through this list-of-lists, following the accepted pattern, and store the largest product?
solution = check_horizontal(table,solution)
print(solution)
solution = check_vertical(table,solution)
print(solution)
solution = check_upwards_diagonals(table,solution)
print(solution)
solution = check_downwards_diagonals(table,solution)
print('Final Answer!')
print(solution)