diff --git a/src/r/R/RcppExports.R b/src/r/R/RcppExports.R index 73cf3cd..d8a3548 100644 --- a/src/r/R/RcppExports.R +++ b/src/r/R/RcppExports.R @@ -31,6 +31,10 @@ largestFactorial <- function(element) { .Call('_projectEuler_largestFactorial', PACKAGE = 'projectEuler', element) } +problem23Cpp <- function() { + .Call('_projectEuler_problem23Cpp', PACKAGE = 'projectEuler') +} + #' Max Palindrome #' #' @description diff --git a/src/r/R/problem-23.R b/src/r/R/problem-23.R index 2d42346..83f4e50 100644 --- a/src/r/R/problem-23.R +++ b/src/r/R/problem-23.R @@ -73,8 +73,9 @@ problem23 <- function() { outerIndex <- 1 twoNumbers <- list() result <- list() + sumOfResults <- 0 - while (outerIndex < total) { + while (outerIndex <= total) { current <- abundant[outerIndex] #sequence <- c() #sequence <- c(current + current, Map(function(item) current + item, tail(abundant, n = -index))) @@ -82,15 +83,15 @@ problem23 <- function() { innerIndex <- outerIndex - while (innerIndex < total) { + while (innerIndex <= total) { sumOfTwo <- current + abundant[innerIndex] - if (sumOfTwo < limit) { - twoNumbers[sumOfTwo] <- sumOfTwo - } else { + if (sumOfTwo > limit) { break } + twoNumbers[sumOfTwo] <- sumOfTwo + innerIndex <- innerIndex + 1 } @@ -100,13 +101,20 @@ problem23 <- function() { for (item in 1:limit) { if (is.null(unlist(twoNumbers[item]))) { result[item] <- item + sumOfResults <- sumOfResults + item } } print('filter done') + print('two numbers') + twoNumbers <- unlist(Filter(Negate(is.null), twoNumbers)) + print(head(twoNumbers, n = 30)) + print(tail(twoNumbers, n = 30)) result <- unlist(result) print('result') print(head(result, n = 30)) - return (sum(result)) + print(tail(result, n = 30)) + + return (sumOfResults) #return (parallelReduce(lessThanLimit, function(acc, cur) acc + cur, 0)) -} +} \ No newline at end of file diff --git a/src/r/R/projectEuler.R b/src/r/R/projectEuler.R index 5fec0c9..e9e0147 100644 --- a/src/r/R/projectEuler.R +++ b/src/r/R/projectEuler.R @@ -123,21 +123,22 @@ enumerate <- function(...) { #' allDivisors <- function(element) { index <- 2 - divisors <- c(1) - limit <- element / 2 + divisors <- list() + limit <- floor(element / 2) increment <- if (0 == element %% 2) 1 else 2 + divisors[1] <- 1 + divisors[element] <- element + while(index <= limit) { if (0 == element %% index) { - divisors <- c(divisors, index) + divisors[index] <- index } index <- index + increment } - divisors <- c(divisors, element) - - return (divisors) + return (unlist(Filter(Negate(is.null), divisors))) } #' @@ -255,4 +256,4 @@ parallelReduce <- function(items, reducer, init) { } return (Reduce(reducer, parallelizeData(items, toParallel), init)) -} +} \ No newline at end of file diff --git a/src/r/src/RcppExports.cpp b/src/r/src/RcppExports.cpp index dd8cb7d..998739f 100644 --- a/src/r/src/RcppExports.cpp +++ b/src/r/src/RcppExports.cpp @@ -34,6 +34,16 @@ BEGIN_RCPP return rcpp_result_gen; END_RCPP } +// problem23Cpp +double problem23Cpp(); +RcppExport SEXP _projectEuler_problem23Cpp() { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + rcpp_result_gen = Rcpp::wrap(problem23Cpp()); + return rcpp_result_gen; +END_RCPP +} // maxPalindrome double maxPalindrome(const double old, const double from, const double limit); RcppExport SEXP _projectEuler_maxPalindrome(SEXP oldSEXP, SEXP fromSEXP, SEXP limitSEXP) { @@ -74,6 +84,7 @@ END_RCPP static const R_CallMethodDef CallEntries[] = { {"_projectEuler_evenFibonacci", (DL_FUNC) &_projectEuler_evenFibonacci, 3}, {"_projectEuler_largestFactorial", (DL_FUNC) &_projectEuler_largestFactorial, 1}, + {"_projectEuler_problem23Cpp", (DL_FUNC) &_projectEuler_problem23Cpp, 0}, {"_projectEuler_maxPalindrome", (DL_FUNC) &_projectEuler_maxPalindrome, 3}, {"_projectEuler_greatestProduct", (DL_FUNC) &_projectEuler_greatestProduct, 2}, {"_projectEuler_erastosthenesSieve", (DL_FUNC) &_projectEuler_erastosthenesSieve, 1}, diff --git a/src/r/src/problem-23.cpp b/src/r/src/problem-23.cpp new file mode 100644 index 0000000..309e6a5 --- /dev/null +++ b/src/r/src/problem-23.cpp @@ -0,0 +1,80 @@ +#include + +using namespace Rcpp; + +const std::list getDivisors(int number) { + int limit = number/2; + std::list divisors = {1}; + + for (int index = 2; index <= limit; index += 1) { + if (0 == number % index) { + divisors.push_back(index); + } + } + + divisors.push_back(number); + + return divisors; +} + +const bool isAbundant(int number) { + int sum = 0; + std::list elements = getDivisors(number); + + elements.pop_back(); + + for (auto i : elements) { + sum += i; + } + + return sum > number; +} + +const std::list getAbundantNumbers(int limit) { + std::list abundantNumbers = {}; + + for (int index = 1; index <= limit; index += 1) { + if (isAbundant(index)) { + abundantNumbers.push_back(index); + } + } + + return abundantNumbers; +} + +// [[Rcpp::export]] +double problem23Cpp() { + int limit = 28123, sum, total, start = 1; + std::list allAbundant = getAbundantNumbers(limit); + std::list sumOfTwo = {}; + auto outerValue = allAbundant.begin(), innerValue = allAbundant.begin(); + + for (int outerIndex = 0; outerIndex < allAbundant.size(); outerIndex += 1) { + std::advance(outerValue, outerIndex); + + for (int innerIndex = outerIndex; innerIndex < allAbundant.size(); innerIndex += 1) { + std::advance(innerValue, outerIndex); + + sum = *outerValue + *innerValue; + + if (sum > limit) { + break; + } + + sumOfTwo.push_back(sum); + } + } + + sumOfTwo.sort(); + sumOfTwo.unique(); + + for (auto element: sumOfTwo) { + for (int index = start; index < element; index++) { + total += index; + } + + start = element + 1; + } + + return total; +} \ No newline at end of file diff --git a/src/r/tests/testthat/test.problem-23.R b/src/r/tests/testthat/test.problem-23.R index f0ea1d0..40932b5 100644 --- a/src/r/tests/testthat/test.problem-23.R +++ b/src/r/tests/testthat/test.problem-23.R @@ -65,13 +65,23 @@ context('Testing problem 23') # # expect_equal(problem23(input), output) #}) +# +#test_that('Wanted example', { +# output <- 4179871 +# result <- problem23() +# +# print('result') +# print(result) +# +# expect_equal(result, output) +#}) test_that('Wanted example', { output <- 4179871 - result <- problem23() + result <- problem23Cpp() print('result') print(result) expect_equal(result, output) -}) +}) \ No newline at end of file