//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 */