mirror of
https://bitbucket.org/Mattrixwv/projecteulerrust.git
synced 2025-12-06 17:43:58 -05:00
Added solution to problem 18
This commit is contained in:
@@ -40,3 +40,4 @@ pub mod Problem14;
|
||||
pub mod Problem15;
|
||||
pub mod Problem16;
|
||||
pub mod Problem17;
|
||||
pub mod Problem18;
|
||||
|
||||
178
src/Problems/Problem18.rs
Normal file
178
src/Problems/Problem18.rs
Normal file
@@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
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::<Vec::<i32>>::new();
|
||||
for _ in 0..15{
|
||||
list.push(Vec::<i32>::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::<Location>::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::<Location>::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::<Vec::<i32>>){
|
||||
//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<Location>, 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
|
||||
*/
|
||||
11
src/main.rs
11
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: ");
|
||||
|
||||
Reference in New Issue
Block a user