Gauss Trick

Introduction

When Carl Friedrich Gauss was a little boy his teacher asked the class to sum up all numbers from 1 to 100. Immediately he came up with the answer. How did he do this? We will find out.

  • Objectives: vector operations, functions, and how Gauss learned to calculate numbers from 1 to 100
  • Requirements: none

Intuitive Solution

Today everybody using R can solve this immediately. You need to create a vector from 1 to 100 and calculate the sum. The vector can be created by creating a sequence with seq. As parameters from and to are defined. Implicitely step size from one number to the next is 1. This could be changed with paramter by. In the next step sum is used to calculate the sum of all elements in this vector.

x <- seq(from = 1, to = 100)
sum(x)
## [1] 5050

This is the intuitive way to solve it, but it is very costly with written addition. So he used a trick.

Gauss’ Solution

He found out that if you sum the first and last number (1 + 100) you have 101. The same for second and second to last value (2 + 98), and so on. You can see a visualisation in the graph. You have an increasing vector with half of all values (red points) and a decreasing vector with the second half of all values (black). Their sum (blue) is always the same.

plot of chunk gauss_plot

Let’s try to do the same. We have our vector x with numbers from 1 to 100. Next, we split this vector in a first and second half. With brackets we can access elements of a vector. 1:50 implicitely is a sequence and the same as seq(1, 50). So for the first half we access elements 1 to 50, and for the second half 51 to 100.

x_first_half <- x[1 : 50]
x_first_half
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
## [24] 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
## [47] 47 48 49 50
x_sec_half <- x[51 : 100]
x_sec_half
##  [1]  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67
## [18]  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84
## [35]  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100

The second half needs decreasing order. Function order is used. Its parameter -x_sec_half refers to decreasing order.

x_sec_half <- x_sec_half[order(-x_sec_half)]
x_sec_half
##  [1] 100  99  98  97  96  95  94  93  92  91  90  89  88  87  86  85  84
## [18]  83  82  81  80  79  78  77  76  75  74  73  72  71  70  69  68  67
## [35]  66  65  64  63  62  61  60  59  58  57  56  55  54  53  52  51

Now, we add x_first_half and x_sec_half elementwise.

y <- x_first_half + x_sec_half
y
##  [1] 101 101 101 101 101 101 101 101 101 101 101 101 101 101 101 101 101
## [18] 101 101 101 101 101 101 101 101 101 101 101 101 101 101 101 101 101
## [35] 101 101 101 101 101 101 101 101 101 101 101 101 101 101 101 101

How many elements does y have? Function length can tell us.

length(y)
## [1] 50

So there is 50 times the value 101 – a total of

length(y) * y[1]
## [1] 5050

Extension: Handling of odd Numbers

This code so far only works for even numbers. How to deal with odd numbers, e.g. 1 to 99? An easy solution is to add a Zero at the beginning. Next quest, how can you find out if a number is odd or even. You can use modulo operator %%. If biggest number modulo 2 is zero, it is an even number, otherwise odd. We will use max() function to find maximum number. Then we use ifelse to handle two different cases. If max number mod 2 is 0, then variable x_odd_even is even, otherwise odd.

Attention: ifelse requires a logical value True or False as its first argument. For our comparison it is important to use == instead =. The latter form is used only for assignments, but not for comparisons. This is a very typical source of error.

max_nr <- max(x)
x_odd_even <- ifelse(max_nr %% 2 == 0, "even", "odd")
x_odd_even
## [1] "even"

Hint: You could avoid modulo (%%) if you use function is.odd() or is.even().

At this point we know if max number is odd or even and have to extend x vector by a Zero at the beginning if x is odd, otherwise not.

x <- ifelse(x_odd_even == "odd",
        cbind(0, x), 
        x)

Extension: Writing a Function

This is the right answer, but what about the sum of 1 to 200, or 1 to 400? To answer this you need to see that 101 is the (maximum number+1) and 50 is just maximum number divided by 2. So you end up with the sum formula 1 + 2 + … n = n/2 * (n+1).

We can use this to write a small function. Writing functions is very easy. You need to define a name, here GaussSum. Then you need magic word function and in brackets our parameter n. In this case I defined n=100. This means if you call GaussSum without further parameters, the default parameter n=100 is used. But you are free to define any other number for n. Within curly braces calculation is performed. The result has to be returned from the function to the calling program. This is defined in return.

GaussSum <- function (n = 100) {
    gauss <- n/2 * (n+1) 
    return (gauss)
}

Let’s give it a try and call the function without and with default parameter.

GaussSum()
## [1] 5050
GaussSum(n=100)
## [1] 5050

You see that passing no parameters and passing n=100 has the same result. But any other number works as well.

GaussSum(n=200)
## [1] 20100

Bibliography

More information on Gauss Sum Formula https://betterexplained.com/articles/techniques-for-adding-the-numbers-1-to-100/

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close