Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sum the odds numbers of a "number"

Tags:

r

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.

like image 747
DrJS Avatar asked Dec 18 '21 18:12

DrJS


People also ask

What is the sum of odd numbers from 1 to 50?

∴ The sum of odd numbers between 1 to 50 is 624.

What is the sum of the first 10 odds numbers?

if we apply odd number theorem: sum of first 10 odd numbers = n * n = 10 * 10 = 100.

How do you find the sum of odd numbers from 1 to 100?

Numbers that are not even numbers, are odd numbers. The sum of all the odd numbers from 1 to 100 is 2500. The average or mean of all odd numbers 1 to 100 is 50.

How do you find the odd factor sum of N?

Given a number n, the task is to find the odd factor sum. Recommended: Please try your approach on {IDE} first, before moving on to the solution. Let p 1, p 2, … p k be prime factors of n. Let a 1, a 2, .. a k be highest powers of p 1, p 2, .. p k respectively that divide n, i.e., we can write n as n = (p1a1)* (p2a2)* … (pkak) .

How to print sum of all odd digits present in a number?

Today, we’ll write a program to Print Sum of all Odd Digits present in a Number and the Sum of all odd digits in a given number can be found by separating each digit from the number and checking whether the digit is odd or not if odd then add that digit if even ignore that.

How to sum a number in Excel?

1 Get the number 2 Declare a variable to store the sum and set it to 0 3 Repeat the next two steps till the number is not 0 4 Get the rightmost digit of the number with help of remainder ‘%’ operator by dividing it with 10 and add it to sum. 5 Divide the number by 10 with help of ‘/’ operator to remove the rightmost digit. 6 Print or return the sum

How to generate random numbers between 1 and 100?

Lets you pick 5 numbers between 1 and 100. Pick unique numbers or allow duplicates. Select odd only, even only, half odd and half even or custom number of odd/even. Generate numbers sorted in ascending order or unsorted. Separate numbers by space, comma, new line or no-space. Click on Start to engage the random number spinner.


Video Answer


5 Answers

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

like image 152
akrun Avatar answered Oct 23 '22 22:10

akrun


Mathematically, we can try the following code to calculate the sum (N could be odd or even)

(ceiling((N - 1) / 2))^2
like image 6
ThomasIsCoding Avatar answered Oct 23 '22 21:10

ThomasIsCoding


It's simple and it does what it says:

sum(seq(1, length.out = floor(N/2), by = 2))

The multiplication solution is probably gonna be quicker, though.

NB - an earlier version of this answer was

sum(seq(1, N - 1, 2))

which as @tjebo points out, silently gives the wrong answer for N = 1.

like image 3
dash2 Avatar answered Oct 23 '22 21:10

dash2


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
like image 2
TarJae Avatar answered Oct 23 '22 21:10

TarJae


Fun benchmarking. Does it surprise that Thomas' simple formula is by far the fastest solution...?

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

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

count_odds_dash2 <- function(x){
  sum(seq(1, x - 1, 2))
}

m <- microbenchmark::microbenchmark(
  akrun = count_odds_akrun(10^6),
  dash2 = count_odds_dash2(10^6),
  thomas = count_odds_thomas(10^6)
)
m
#> Unit: nanoseconds
#>    expr      min         lq        mean   median       uq      max neval
#>   akrun 22117564 26299922.0 30052362.16 28653712 31891621 70721894   100
#>   dash2  4016254  4384944.0  7159095.88  4767401  8202516 52423322   100
#>  thomas      439      935.5    27599.34     6223     8482  2205286   100

ggplot2::autoplot(m)
#> Coordinate system already present. Adding new coordinate system, which will replace the existing one.

Moreover, Thomas solution works on really big numbers (also no surprise)... on my machine, count_odds_akrun stuffs the memory at a “mere” 10^10, but Thomas works fine till Infinity…

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

count_odds_akrun(10^10)
#> Error: vector memory exhausted (limit reached?)
like image 2
6 revs Avatar answered Oct 23 '22 21:10

6 revs