Finding the closest pentagonal number, given a positive integer, S where S ≥ 1

Viewed 390

I need to create a function in R that takes as input an integer, S ≥ 1 and returns as output the pentagonal number which is closest to S.The output of my function should be the pentagonal number which satisfies |−|≤|−| for all positive integers m.

However if I could get two different pentagonal numbers which happens when the integer, s is literally in the middle of them. Then it doesn't matter which one it takes (greater or lesser value) which is like when S is 17 and the pentagonal number closest to 17 is 12 and 22 so it can take either one.

Here is the following code that I have created which is used to find the pentagonal number for a given positive integer, n:

P_n=function(n){
x=(3*n^2-n)/2
if(n == 0){
return (0)
}else{
return(x)
}
}

After writing the code to find pn, I am now stuck with finding the closest pentagonal number for integer, s. I know that the main idea is to distinguish Pm and Pn using ceiling and floor function but I don't really know how to link it to the equation |−|≤|−|.

2 Answers

You can try the code below

P_n <- Vectorize(function(n)   max((3 * n^2 - n) / 2, 0))
k <- floor((1 + sqrt(1 + 24 * x)) / 6)
(n <- k - 1 + which.min(abs(P_n(c(k,k+1)) - x)))

Example 1

> x <- 18

> k <- floor((1 + sqrt(1 + 24 * x)) / 6)

> (n <- k - 1 + which.min(abs(P_n(c(k,k+1)) - x)))
[1] 4

Example 2

> x <- 17

> k <- floor((1 + sqrt(1 + 24 * x)) / 6)

> (n <- k - 1 + which.min(abs(P_n(c(k,k+1)) - x)))
[1] 3

You don't need loops, just solve following problem:

For input S find minimum n such that: 3n^2-n-2S >= 0

By doing that you get your two candidates:

n <- (1 + sqrt(1 + 24 * S)) / 6
p1 <- P_n(floor(n))
p2 <- P_n(ceiling(n))

c(p1, p2)[which.min(c(S - p1, p2 - S))]

In the case when the difference is same this will prefer lower pentagonal number (because of the way which.min works in case of equal numbers).

Related