Skip to content

Commit

Permalink
Add fast problem 18 cpp solution
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-anders committed Mar 19, 2019
1 parent 2f797b5 commit afedeae
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ The following table summarizes the current project status. The speed of the fast
| 15 | - | - | - | - | - | + (0.00s) |
| 16 | + (0.00s) | - | - | - | - | + (0.00s) |
| 17 | - | - | - | - | - | + (0.01s) |
| 18 | - | - | - | - | - | + (0.00s) |
| 18 | - | - | TBD | - | - | + (0.00s) |
| 19 | + (0.00s) | - | + (0.00s) | - | - | - |
| 20 | - | - | - | - | - | - |
| 21 | - | - | - | - | - | - |
Expand Down
52 changes: 38 additions & 14 deletions cpp_src/problem018.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//
// Problem statement: By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.<p style="text-align:center;font-family:'courier new';font-size:12pt;"><span style="color:#ff0000;"><b>3</b></span><br /><span style="color:#ff0000;"><b>7</b></span> 4<br />2 <span style="color:#ff0000;"><b>4</b></span> 6<br />8 5 <span style="color:#ff0000;"><b>9</b></span> 3That is, 3 + 7 + 4 + 9 = 23.Find the maximum total from top to bottom of the triangle below:<p style="text-align:center;font-family:'courier new';">75<br />95 64<br />17 47 82<br />18 35 87 10<br />20 04 82 47 65<br />19 01 23 75 03 34<br />88 02 77 73 07 63 67<br />99 65 04 28 06 16 70 92<br />41 41 26 56 83 40 80 70 33<br />41 48 72 33 47 32 37 16 94 29<br />53 71 44 65 25 43 91 52 97 51 14<br />70 11 33 28 77 73 17 78 39 68 17 57<br />91 71 52 38 17 14 91 43 58 50 27 29 48<br />63 66 04 68 89 53 67 30 73 16 69 87 40 31<br />04 62 98 27 23 09 70 98 73 93 38 53 60 04 23<p class="note"><b>NOTE:</b> As there are only 16384 routes, it is possible to solve this problem by trying every route. However, Problem 67, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o)
//
// Solution description: Brute force, smart algorithm coming soon
// Solution description: Brute force solution and a faster solution that will iterate over the rows and only keep the paths with the higher sum
//
// Author: Tom Praschan
// 2019/03/18
Expand All @@ -14,40 +14,64 @@
#include <fstream>
#include <sstream>
#include <iostream>
#include <functional>

Matrix getTriangle(const std::string &file) {
Triangle getTriangle(const std::string &file) {
std::ifstream ifs(file);
Matrix mat;
Triangle tri;
std::string line;
while (std::getline(ifs, line)) {
std::istringstream iss(line);
mat.emplace_back(std::istream_iterator<unsigned>(iss), std::istream_iterator<unsigned>());
tri.emplace_back(std::istream_iterator<unsigned>(iss), std::istream_iterator<unsigned>());
}
return mat;
return tri;
}

unsigned bruteforce_solution(const Matrix &mat, unsigned hor, unsigned ver, unsigned sum) {
unsigned triangle_sum_bruteforce(const Triangle &tri, unsigned hor, unsigned ver, unsigned sum) {
static std::vector<unsigned> finalSums;
sum += mat.at(ver).at(hor);
if (ver == mat.size() - 1) {
sum += tri.at(ver).at(hor);
if (ver == tri.size() - 1) {
finalSums.emplace_back(sum);
return 0;
} else {
bruteforce_solution(mat, hor, ver + 1, sum);
bruteforce_solution(mat, hor + 1, ver + 1, sum);
triangle_sum_bruteforce(tri, hor, ver + 1, sum);
triangle_sum_bruteforce(tri, hor + 1, ver + 1, sum);
}
return *std::max_element(finalSums.begin(), finalSums.end());
}

unsigned triangle_sum_fast(const Triangle &tri) {
Triangle partialSum(tri.size());

for (unsigned i = 0; i < tri.size(); i++)
partialSum.at(i).reserve(tri.at(i).size());
partialSum.at(0).push_back(tri.at(0).at(0));

for (unsigned ver = 1; ver < tri.size(); ver++) {
partialSum.at(ver).push_back(tri.at(ver).at(0) + partialSum.at(ver-1).at(0));
unsigned horSize = tri.at(ver).size();
for (unsigned hor = 1; hor < horSize - 1; hor++) {
partialSum.at(ver).push_back(tri.at(ver).at(hor)
+ std::max(partialSum.at(ver-1).at(hor-1), partialSum.at(ver-1).at(hor)));
}
partialSum.at(ver).push_back(tri.at(ver).at(horSize - 1) + partialSum.at(ver-1).at(horSize - 2));
}
return *std::max_element(partialSum.back().begin(),partialSum.back().end());
}

#ifndef TESTING
int main(int argc, char **argv) {
auto start = omp_get_wtime();
auto mat = getTriangle("../input_files/problem018.txt");
auto solution = bruteforce_solution(mat);
auto solution = triangle_sum_bruteforce(getTriangle("../input_files/problem018.txt"));
auto end = omp_get_wtime();

fmt::print("Solution: {} \n", solution);
fmt::print("Bruteforce Solution: {} \n", solution);
fmt::print("Elapsed time: {}s \n", end - start);

start = omp_get_wtime();
solution = triangle_sum_fast(getTriangle("../input_files/problem018.txt"));
end = omp_get_wtime();

fmt::print("Fast Solution: {} \n", solution);
fmt::print("Elapsed time: {}s \n", end - start);
}
#endif
8 changes: 5 additions & 3 deletions cpp_src/problem018.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
#include <vector>
#include <string>

typedef std::vector<std::vector<unsigned>> Matrix;
typedef std::vector<std::vector<unsigned>> Triangle;

Matrix getTriangle(const std::string &file);
Triangle getTriangle(const std::string &file);

unsigned bruteforce_solution(const Matrix &mat, unsigned hor = 0, unsigned ver = 0, unsigned sum = 0);
unsigned triangle_sum_bruteforce(const Triangle &tri, unsigned hor = 0, unsigned ver = 0, unsigned sum = 0);

unsigned triangle_sum_fast(const Triangle &tri);
8 changes: 5 additions & 3 deletions cpp_src/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ TEST_CASE( "Testing collatz_len (Problem 14)") {
REQUIRE(collatz_len(13) == 10);
}

TEST_CASE( "Testing Problem 18 brute_force_solution") {
REQUIRE(bruteforce_solution(getTriangle("../input_files/test018.txt")) == 23);
REQUIRE(bruteforce_solution(getTriangle("../input_files/problem018.txt")) == 1074);
TEST_CASE( "Testing Problem 18/67 fst and bruteforce solution") {
REQUIRE(triangle_sum_bruteforce(getTriangle("../input_files/test018.txt")) == 23);
REQUIRE(triangle_sum_bruteforce(getTriangle("../input_files/problem018.txt")) == 1074);
REQUIRE(triangle_sum_fast(getTriangle("../input_files/test018.txt")) == 23);
REQUIRE(triangle_sum_fast(getTriangle("../input_files/problem018.txt")) == 1074);
}

0 comments on commit afedeae

Please sign in to comment.