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 Problem15;
|
||||||
pub mod Problem16;
|
pub mod Problem16;
|
||||||
pub mod Problem17;
|
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)]
|
#[derive(PartialEq)]
|
||||||
enum Selections{EMPTY, SOLVE, DESCRIPTION, LIST, EXIT, SIZE}
|
enum Selections{EMPTY, SOLVE, DESCRIPTION, LIST, EXIT, SIZE}
|
||||||
|
|
||||||
static problemNumbers: [u32; 18] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
static problemNumbers: [u32; 19] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
10, 11, 12, 13, 14, 15, 16, 17];
|
10, 11, 12, 13, 14, 15, 16, 17, 18];
|
||||||
|
|
||||||
fn main(){
|
fn main(){
|
||||||
let mut selection = Selections::EMPTY;
|
let mut selection = Selections::EMPTY;
|
||||||
@@ -199,6 +199,10 @@ fn solveProblem(problemNumber: u32){
|
|||||||
println!("{}", Problems::Problem17::getDescription());
|
println!("{}", Problems::Problem17::getDescription());
|
||||||
println!("{}", Problems::Problem17::solve());
|
println!("{}", Problems::Problem17::solve());
|
||||||
}
|
}
|
||||||
|
else if(problemNumber == 18){
|
||||||
|
println!("{}", Problems::Problem18::getDescription());
|
||||||
|
println!("{}", Problems::Problem18::solve());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn descriptionMenu(){
|
fn descriptionMenu(){
|
||||||
//Give some extra space to print the description
|
//Give some extra space to print the description
|
||||||
@@ -275,6 +279,9 @@ fn printDescription(problemNumber: u32){
|
|||||||
else if(problemNumber == 17){
|
else if(problemNumber == 17){
|
||||||
println!("{}", Problems::Problem17::getDescription());
|
println!("{}", Problems::Problem17::getDescription());
|
||||||
}
|
}
|
||||||
|
else if(problemNumber == 18){
|
||||||
|
println!("{}", Problems::Problem18::getDescription());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn getProblemNumber() -> u32{
|
fn getProblemNumber() -> u32{
|
||||||
println!("Enter a problem number: ");
|
println!("Enter a problem number: ");
|
||||||
|
|||||||
Reference in New Issue
Block a user