diff --git a/src/Problems.rs b/src/Problems.rs
index 5f1d867..b3024eb 100644
--- a/src/Problems.rs
+++ b/src/Problems.rs
@@ -40,3 +40,4 @@ pub mod Problem14;
pub mod Problem15;
pub mod Problem16;
pub mod Problem17;
+pub mod Problem18;
diff --git a/src/Problems/Problem18.rs b/src/Problems/Problem18.rs
new file mode 100644
index 0000000..c308690
--- /dev/null
+++ b/src/Problems/Problem18.rs
@@ -0,0 +1,178 @@
+//ProjectEulerRust/src/Problems/Problems18.rs
+//Matthew Ellison
+// Created: 06-17-20
+//Modified: 06-17-20
+//Find the maximum total from top to bottom
+/*
+75
+95 64
+17 47 82
+18 35 87 10
+20 04 82 47 65
+19 01 23 75 03 34
+88 02 77 73 07 63 67
+99 65 04 28 06 16 70 92
+41 41 26 56 83 40 80 70 33
+41 48 72 33 47 32 37 16 94 29
+53 71 44 65 25 43 91 52 97 51 14
+70 11 33 28 77 73 17 78 39 68 17 57
+91 71 52 38 17 14 91 43 58 50 27 29 48
+63 66 04 68 89 53 67 30 73 16 69 87 40 31
+04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
+*/
+//This is done using a breadth first search
+//Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/RustClasses
+/*
+ Copyright (C) 2020 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 .
+*/
+
+
+extern crate myClasses;
+use crate::Problems::Answer::Answer;
+
+pub fn getDescription() -> String{
+ "Find the maximum total from top to bottom".to_string()
+}
+
+#[derive(Copy, Clone, Debug)]
+struct Location{
+ pub xLocation: i32,
+ pub yLocation: i32,
+ pub total: i32,
+ pub fromRight: bool
+}
+impl Location{
+ pub fn new(x: i32, y: i32, t: i32, r: bool) -> Location{
+ let location = Location{xLocation: x, yLocation: y, total: t, fromRight: r};
+ return location;
+ }
+}
+impl PartialEq for Location{
+ fn eq(&self, other: &Self) -> bool{
+ if((self.xLocation == other.xLocation) && (self.yLocation == other.yLocation)){
+ return true;
+ }
+ else{
+ return false;
+ }
+ }
+}
+
+pub fn solve() -> Answer{
+ let NUM_ROWS = 15;
+ //Start the timer
+ let mut timer = myClasses::Stopwatch::Stopwatch::new();
+ timer.start();
+
+ //Setup the list you are trying to find a path through
+ let mut list = Vec::>::new();
+ for _ in 0..15{
+ list.push(Vec::::new());
+ }
+ list[0].push(75);
+ list[1].extend_from_slice(&[95, 64]);
+ list[2].extend_from_slice(&[17, 47, 82]);
+ list[3].extend_from_slice(&[18, 35, 87, 10]);
+ list[4].extend_from_slice(&[20, 04, 82, 47, 65]);
+ list[5].extend_from_slice(&[19, 01, 23, 75, 03, 34]);
+ list[6].extend_from_slice(&[88, 02, 77, 73, 07, 63, 67]);
+ list[7].extend_from_slice(&[99, 65, 04, 28, 06, 16, 70, 92]);
+ list[8].extend_from_slice(&[41, 41, 26, 56, 83, 40, 80, 70, 33]);
+ list[9].extend_from_slice(&[41, 48, 72, 33, 47, 32, 37, 16, 94, 29]);
+ list[10].extend_from_slice(&[53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14]);
+ list[11].extend_from_slice(&[70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57]);
+ list[12].extend_from_slice(&[91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48]);
+ list[13].extend_from_slice(&[63, 66, 04, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31]);
+ list[14].extend_from_slice(&[04, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 04, 23]);
+
+ //Invert the list
+ invert(&mut list);
+
+ let mut foundPoints = Vec::::new(); //For the points that I have already found the shortest distance to
+ foundPoints.push(Location::new(0, 0, list[0][0], false)); //Add the first row as a found point because you have to go through the tip
+ let mut possiblePoints = Vec::::new(); //For the locations you are checking this round
+ //Add the second row as possible points
+ possiblePoints.push(Location::new(0, 1, list[0][0] + list[1][0], true));
+ possiblePoints.push(Location::new(1, 1, list[0][0] + list[1][1], false));
+ let mut foundBottom = false; //Used when you find a point at the bottom of the list
+
+ //Loop until you find the bottom of the list
+ while(!foundBottom){
+ //Check which possible point gives us the lowest number. If more than one has the same number simply keep the first one
+ let mut minLoc = possiblePoints[0];
+ for loc in 1..possiblePoints.len(){
+ if(possiblePoints[loc].total < minLoc.total){
+ minLoc = possiblePoints[loc];
+ }
+ }
+
+ //Remove it from the list of possible points
+ removeHelper(&mut possiblePoints, minLoc);
+
+ //Add that point to the list of found points
+ foundPoints.push(minLoc);
+
+ //Add to the list of possible points from the point we just found and
+ //If you are at the bottom raise the flag to end the program
+ let mut xLoc = minLoc.xLocation;
+ let yLoc = minLoc.yLocation + 1;
+ if(yLoc >= NUM_ROWS){
+ foundBottom = true;
+ }
+ else{
+ possiblePoints.push(Location::new(xLoc, yLoc, minLoc.total + list[yLoc as usize][xLoc as usize], true));
+ xLoc += 1; //Advance the x location to simulate going right
+ //Check if x is out of bounds
+ if(xLoc < list[yLoc as usize].len() as i32){
+ possiblePoints.push(Location::new(xLoc, yLoc, minLoc.total + list[yLoc as usize][xLoc as usize], false));
+ }
+ }
+ }
+
+ //Stop the timer
+ timer.stop();
+
+ //Get the correct total which will be the inversion of the current one
+ let actualTotal = ((100 * NUM_ROWS) - foundPoints[foundPoints.len() - 1].total);
+
+ //Return the results
+ return Answer::new(format!("The value of the longest path is {}", actualTotal), timer.getString());
+}
+//This function turns every number in the array into (100 - num) to allow you to find the largest numbers rather than the smallest
+fn invert(list: &mut Vec::>){
+ //Loop through every row in the list
+ for rowCnt in 0..list.len(){
+ //Loop through every column in the list
+ for colCnt in 0..list[rowCnt].len(){
+ //The current element gets the value of 100 - value
+ list[rowCnt][colCnt] = 100 - list[rowCnt][colCnt];
+ }
+ }
+}
+//This function helps be removing th eelement that is the same as the minumum location
+fn removeHelper(possiblePoints: &mut Vec, minLoc: Location){
+ for loc in 0..possiblePoints.len(){
+ if(possiblePoints[loc] == minLoc){
+ possiblePoints.remove(loc);
+ break;
+ }
+ }
+}
+
+/* Results:
+The value of the longest path is 1074
+It took 195.800 microseconds to solve this problem
+*/
diff --git a/src/main.rs b/src/main.rs
index 3685fc9..b7044a0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -33,8 +33,8 @@ mod Problems;
#[derive(PartialEq)]
enum Selections{EMPTY, SOLVE, DESCRIPTION, LIST, EXIT, SIZE}
-static problemNumbers: [u32; 18] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17];
+static problemNumbers: [u32; 19] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18];
fn main(){
let mut selection = Selections::EMPTY;
@@ -199,6 +199,10 @@ fn solveProblem(problemNumber: u32){
println!("{}", Problems::Problem17::getDescription());
println!("{}", Problems::Problem17::solve());
}
+ else if(problemNumber == 18){
+ println!("{}", Problems::Problem18::getDescription());
+ println!("{}", Problems::Problem18::solve());
+ }
}
fn descriptionMenu(){
//Give some extra space to print the description
@@ -275,6 +279,9 @@ fn printDescription(problemNumber: u32){
else if(problemNumber == 17){
println!("{}", Problems::Problem17::getDescription());
}
+ else if(problemNumber == 18){
+ println!("{}", Problems::Problem18::getDescription());
+ }
}
fn getProblemNumber() -> u32{
println!("Enter a problem number: ");