//ProjectEulerJava/src/main/java/mattrixwv/ProjectEuler/Problems/Problem11.java
//Matthew Ellison
// Created: 03-03-19
//Modified: 06-27-23
//What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid?
//Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/JavaClasses
/*
Copyright (C) 2023 Matthew Ellison
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
*/
package com.mattrixwv.project_euler.problems;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.List;
import com.mattrixwv.ArrayAlgorithms;
public class Problem11 extends Problem{
//Variables
//Static variables
//This is the grid of numbers that we will be working with
protected static String fileName = "files/Problem11Grid.txt";
protected static ArrayList> grid;
//Instance variables
protected List greatestProduct; //Holds the largest product we have found so far
//Functions
//Constructor
public Problem11(){
super("What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid?");
greatestProduct = new ArrayList<>();
}
//Operational functions
//Read numbers from file into grid
private static void readFile(){
if(grid != null){
return;
}
File file = new File(fileName);
if(file.exists()){
try{
List lines = Files.readAllLines(file.toPath());
grid = new ArrayList<>();
for(String line : lines){
ArrayList row = new ArrayList<>();
for(String num : line.split(" ")){
row.add(Integer.parseInt(num));
}
grid.add(row);
}
}
catch(IOException error){
throw new InvalidParameterException("Error reading file", error);
}
}
else{
throw new InvalidParameterException("Error opening file");
}
}
//Solve the problem
@Override
public void solve(){
//If the problem has already been solved do nothing and end the function
if(solved){
return;
}
//Holds the numbers we are currently working on
ArrayList currentProduct = new ArrayList<>();
//Make sure all elements have at least 4 elements
for(int cnt = 0;cnt < 4;++cnt){
greatestProduct.add(0);
currentProduct.add(0);
}
//Read the file into the number
readFile();
//Start the timer
timer.start();
//Loop through every row and column
for(int row = 0;row < grid.size();++row){
for(int col = 0;col < grid.get(row).size();++col){
//Directional booleans to show whether you can move a certain direction
boolean left = false;
boolean right = false;
boolean down = false;
//Check which direction you will be able to move
if((col - 3) >= 1){
left = true;
}
if((col + 3) < grid.get(row).size()){
right = true;
}
if((row + 3) < 20){
down = true;
}
//Check the direction you are able to go
//Right
if(right){
checkRight(currentProduct, row, col);
}
//Down
if(down){
checkDown(currentProduct, row, col);
}
//LeftDown
if(left && down){
checkLeftDown(currentProduct, row, col);
}
//RightDown
if(right && down){
checkRightDown(currentProduct, row, col);
}
}
}
//Stop the timer
timer.stop();
//Throw a flag to show the problem is solved
solved = true;
}
//Check to the right of the current location
private void checkRight(ArrayList currentProduct, int row, int col){
//Fill the product
currentProduct.set(0, grid.get(row).get(col));
currentProduct.set(1, grid.get(row).get(col + 1));
currentProduct.set(2, grid.get(row).get(col + 2));
currentProduct.set(3, grid.get(row).get(col + 3));
//If the current number's product is greater than the greatest product replace it
if(ArrayAlgorithms.getProd(currentProduct) > ArrayAlgorithms.getProd(greatestProduct)){
greatestProduct.set(0, currentProduct.get(0));
greatestProduct.set(1, currentProduct.get(1));
greatestProduct.set(2, currentProduct.get(2));
greatestProduct.set(3, currentProduct.get(3));
}
}
//Check below the current location
private void checkDown(ArrayList currentProduct, int row, int col){
//Fill the product
currentProduct.set(0, grid.get(row).get(col));
currentProduct.set(1, grid.get(row + 1).get(col));
currentProduct.set(2, grid.get(row + 2).get(col));
currentProduct.set(3, grid.get(row + 3).get(col));
//If the current number's product is greater than the greatest product replace it
if(ArrayAlgorithms.getProd(currentProduct) > ArrayAlgorithms.getProd(greatestProduct)){
greatestProduct.set(0, currentProduct.get(0));
greatestProduct.set(1, currentProduct.get(1));
greatestProduct.set(2, currentProduct.get(2));
greatestProduct.set(3, currentProduct.get(3));
}
}
//Check the left-down diagonal from the current location
private void checkLeftDown(ArrayList currentProduct, int row, int col){
//Fill the product
currentProduct.set(0, grid.get(row).get(col));
currentProduct.set(1, grid.get(row + 1).get(col - 1));
currentProduct.set(2, grid.get(row + 2).get(col - 2));
currentProduct.set(3, grid.get(row + 3).get(col - 3));
//If the current number's product is greater than the greatest product replace it
if(ArrayAlgorithms.getProd(currentProduct) > ArrayAlgorithms.getProd(greatestProduct)){
greatestProduct.set(0, currentProduct.get(0));
greatestProduct.set(1, currentProduct.get(1));
greatestProduct.set(2, currentProduct.get(2));
greatestProduct.set(3, currentProduct.get(3));
}
}
//Check the right-down diagonal from the current location
private void checkRightDown(ArrayList currentProduct, int row, int col){
//Fill the product
currentProduct.set(0, grid.get(row).get(col));
currentProduct.set(1, grid.get(row + 1).get(col + 1));
currentProduct.set(1, grid.get(row + 2).get(col + 2));
currentProduct.set(1, grid.get(row + 3).get(col + 3));
//If the current number's product is greater than the greatest product replace it
if(ArrayAlgorithms.getProd(currentProduct) > ArrayAlgorithms.getProd(greatestProduct)){
greatestProduct.set(0, currentProduct.get(0));
greatestProduct.set(1, currentProduct.get(1));
greatestProduct.set(2, currentProduct.get(2));
greatestProduct.set(3, currentProduct.get(3));
}
}
//Reset the problem so it can be run again
@Override
public void reset(){
super.reset();
greatestProduct.clear();
}
//Gets
//Returns the result of solving the problem
@Override
public String getResult(){
solvedCheck("result");
return String.format("The greatest product of 4 numbers in a line is %d%nThe numbers are %s", ArrayAlgorithms.getProd(greatestProduct), greatestProduct.toString());
}
//Returns the numbers that were being searched
public List getNumbers(){
solvedCheck("numbers");
return greatestProduct;
}
//Returns the product that was requested
public int getProduct(){
solvedCheck("product of the numbers");
return ArrayAlgorithms.getProd(greatestProduct);
}
}
/* Results:
The greatest product of 4 numbers in a line is 70600674
The numbers are [89, 94, 97, 87]
It took an average of 301.209 microseconds to run this problem through 100 iterations
*/