Home > OS >  Sum the odds numbers of a "number"
Sum the odds numbers of a "number"

Time:12-19

I am trying to sum the odds numbers of a specific number (but excluding itself), for example: N = 5 then 1 3 = 4

a<-5
sum<-function(x){
  k<-0
  for (n in x) {
    if(n %% 2 == 1)
      k<-k 1      
  }
         return(k)
}

sum(a)

# [1] 1

But the function is not working, because it counts the odds numbers instead of summing them.

Thanks in advance.

CodePudding user response:

We may use vectorized approach

a1 <- head(seq_len(a), -1)
sum(a1[a1%%2 == 1])
[1] 4

If we want a loop, perhaps

f1 <- function(x) {
  s <- 0
  k <- 1
  while(k < x) {
    if(k %% 2 == 1) {
      s <- s   k
    }
     k <- k   1
     
     }
s

}
f1(5)

The issue in OP's code is

for(n in x)

where x is just a single value and thus n will be looped once - i.e. if our input is 5, then it will be only looped once and 'n' will be 5. Instead, it would be seq_len(x -1). The correct loop would be something like

f2<-function(x){
  k<- 0
  for (n in seq_len(x-1)) {
    if(n %% 2 == 1) {
     k <- k   n 
    }
    
  }
    k    
}


f2(5)

NOTE: sum is a base R function. So, it is better to name the custom function with a different name

CodePudding user response:

Mathematically, we can try the following code to calculate the sum

((N-1)/2)^2

CodePudding user response:

We could use logical statement to access the values:

a <- 5
a1 <- head(seq_len(a), -1)

sum(a1[c(TRUE, FALSE)])

output:

[1] 4

CodePudding user response:

Fun benchmarking. Does it surprise that Thomas solution is vastly quicker...?

count_odds_thomas <- function(x){
  ((x-1)/2)^2
}

count_odds_akrun <- function(x){
a1 <- head(seq_len(x), -1)
sum(a1[a1%%2 == 1])
}

microbenchmark::microbenchmark(
  akrun = count_odds_akrun(10^6),
  thomas = count_odds_thomas(10^6)
  
)
#> Unit: nanoseconds
#>    expr      min       lq        mean   median       uq      max neval
#>   akrun 21829246 25880187 30571479.45 29317004 32566502 82343305   100
#>  thomas      616      991    35103.54     6574     8450  2928050   100

Moreover, Thomas solution works on really big numbers... (That's probably a matter of your machine too)

count_odds_thomas(10^10)
#> [1] 2.5e 19

count_odds_akrun(10^10)
#> Error: vector memory exhausted (limit reached?)
  •  Tags:  
  • r
  • Related