Skip to content

Commit

Permalink
Faster problem 12 cpp solution
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-anders committed Mar 18, 2019
1 parent 90dfb08 commit 5fa7b43
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ The following table summarizes the current project status. The speed of the fast
| 9 | + (0.60s) | - | + (0.01s) | - | + (0.00s) | + (0.01s) |
| 10 | _**+ (19.9s)**_| - | + (0.66s) | - | _**+ (2.04s)**_| + (0.98s) |
| 11 | + (0.00) | - | - | - | - | + (0.00s) |
| 12 | - | - | _**+ (>8min)**_| - | - | _**+ (1.45s)**_|
| 12 | - | - | TBD | - | - | _**+ (1.45s)**_|
| 13 | + (0.00s) | - | - | - | - | + (0.00s) |
| 14 | - | - | + (0.25s) | - | - | + (0.27s) |
| 15 | - | - | - | - | - | + (0.00s) |
Expand Down
41 changes: 32 additions & 9 deletions cpp_src/problem012.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,45 @@
// License: MIT (see ../LICENSE.md)

#include "problem012.hpp"
#include "prime_utils.hpp"
#include <omp.h>
#include <fmt/format.h>
#include <vector>
#include <numeric> // For std::accumulate

// Finds the number of divisors of n via bruteforce
unsigned num_divisors_bruteforce(unsigned n) {
// First find the prime factorization of n,
// then the number of divisors is given by the product
// of the powers of the prime factors + 1
unsigned num_divisors(unsigned n) {
if (n == 1) return 1;
if (n == 2) return 2;
if (is_prime(n)) return 2;
//Stores the powers of the prime factors
std::vector<unsigned> powers;

//Intialize to 2 -> always count 1 and the number itself
unsigned num_divisors = 2;
const int max = sqrt(n);

for (unsigned i = 2; i < n / 2 + 1; i++) {
if (n % i == 0)
num_divisors++;
//Special case: n is even
if (n % 2 == 0) {
unsigned p = 0;
do {
n /= 2;
p++;
} while (n % 2 == 0);
powers.push_back(p + 1);
}
return num_divisors;
for (unsigned i = 3; i <= max; i+=2) {
if (n % i == 0 && is_prime(i)) {
unsigned p = 0;
do {
n /= i;
p++;
} while (n % i == 0);
powers.push_back(p + 1);
}
}

return std::accumulate(powers.begin(), powers.end(), 1, std::multiplies<unsigned>());
}

// Return the nth triangle number using Gauß' formula
Expand All @@ -36,7 +59,7 @@ unsigned triangle_number(unsigned n) {
int main(int argc, char **argv) {
auto start = omp_get_wtime();
unsigned n = 1;
for (n = 1; num_divisors_bruteforce(triangle_number(n)) <= 500; n++) {}
for (n = 1; num_divisors(triangle_number(n)) <= 500; n++) {}
auto solution = triangle_number(n);
auto end = omp_get_wtime();

Expand Down
2 changes: 1 addition & 1 deletion cpp_src/problem012.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#pragma once

unsigned num_divisors_bruteforce(unsigned n);
unsigned num_divisors(unsigned n);

unsigned triangle_number(unsigned n);

0 comments on commit 5fa7b43

Please sign in to comment.