35  35. while loops

A “while loop” in R is one of several ways to get R to do something over and over again (we’ll discuss other ways later). A relatively straight forward example of code that could be written with a “while loop” is the factorial function (see below). Now, since R has a built-in version of the factorial function, you don’t actually have to write the factorial function yourself. However, it will be instructive to reproduce this function with our own code that uses a while loop - which we do below. In order to understand the example code below, let’s first understand what a factorial is.

35.1 What is the “factorial” of a number?

In math, the factorial of a number is the product of that number and all the positive whole numbers below it. For example:
The factorial of 5 is: 5 × 4 × 3 × 2 × 1 = 120
Mathematicians write factorials using an exclamation point.
For example a mathematician would write 5! to mean 5 × 4 × 3 × 2 × 1 = 120
However, 5! is NOT valid R code. Rather, R has a builtin function, factorial(SOME_NUMBER) that calculates factorials. For example:

factorial(3)  # same as 3*2*1 which is 6
[1] 6
factorial(5)  # same as 5*4*3*2*1 which is 120
[1] 120

35.1.1 factorial is not defined for negative numbers

The concept of a factorial is not defined for negative numbers. When given a negative number, R’s factorial function returns NaN (i.e. R’s special value meaning “not a number”)

factorial(-1)  # NaN
[1] NaN

35.1.2 factorial(0) and factorial(1) are both 1

The factorial of 0 and the factorial of 1 are both defined to be 1.

factorial(0)  # defined by mathematicians to be 1
[1] 1
factorial(1)  # defined by mathematicians to be 1
[1] 1

To learn more about factorials, see this page: https://www.mathsisfun.com/numbers/factorial.html

35.2 Let’s rewrite the factorial function - we’ll use a while loop.

Let’s write a function called myFactorial that reproduces the results of R’s builtin factorial function that was shown above.

The code introduces a new concept - the “while loop”. We’ll explain all of the code below, but first let’s see the full definition of the function and make sure that it works:

myFactorial <- function(num){
  if(!is.numeric(num) || trunc(num) != num || length(num) != 1) {
    stop("num must be a single positive whole number")
  }
  
  if (num < 0) {
    return(NaN)
  }

  answer = 1
  
  while(num > 1) {
    answer <- answer * num
    num <- num - 1
  }
  
  return(answer)
}

Some examples of using the myFactorial function:

myFactorial(0)   # factorial of 0 is defined to be 1
[1] 1
myFactorial(1)   # factorial of 1 is defined to be 1
[1] 1
myFactorial(3)   # 6, ie. 3 * 2 * 1
[1] 6
myFactorial(5)   # 120 i.e. 5*4*3*2*1
[1] 120
myFactorial(10)  # 3628800 - i.e. 10*9*8*7*6*5*4*3*2*1
[1] 3628800
myFactorial(100) # 9.332622e+157   -  this is a VERY VERY large number (see section on "scientific notation")
[1] 9.332622e+157
myFactorial(c(1,2,3,4))  # ERROR - only one number in our version of myFactorial
Error in !is.numeric(num) || trunc(num) != num: 'length = 4' in coercion to 'logical(1)'
myFactorial(-1)          # NaN
[1] NaN

35.2.1 Explanation of the code

Let’s go through the myFactorial function in detail. Portions of the code are highlighted with numbers and explained below.

myFactorial <- function(num){
1  if(!is.numeric(num) || trunc(num) != num || length(num) != 1) {
    stop("num must be a single positive whole number")
  }
  
2  if (num < 0) {
    return(NaN)
  }

3  answer = 1
  
4  while(num > 1) {
    answer <- answer * num
    num <- num - 1
  }
  
5  return(answer)
}
1
make sure that num is just one whole number
2
make sure that num is not negative
3
setup the answer variable - this is necessary to do before the while loop starts
4
the while loop (explinaed in detail below)
5
return the answer

35.2.2 How the while loop works

A while loop looks similar to an if, except that a while loop starts with the word “while” and an if starts with the word “if”.

  • Similar to an “if”, a “while” has a logical condition in parentheses followed by some code in {curly braces}. (The code in the {curly braces} is called the “body” of the while loop.)

  • Similar to an “if”, the condition must evaluate to TRUE or FALSE.

  • Similar to an “if” - when the condition for the while is TRUE - the code in the {curly braces} is executed and when the condition is FALSE, the code in the {curly braces} is NOT executed.

  • What makes a while different from an if is the following:

    o if : when the code in the {curly braces} (i.e. the “body” of the if) finishes, the execution of the code continues with the first line after the body of the “if”

    o while : when the code in the {curly braces} (i.e. the “body” of the while) finishes, the entire “while” is repeated - i.e. the condition is checked and if it is still TRUE - the body of the while is done again. This keeps happening as long as the condition is TRUE (i.e. “while” the condition is TRUE). If/when the condition eventually becomes FALSE, the execution of the code continues with the first line after the body of the “while”.

35.3 Terminology: “iteration” , “iterate”

As a while loop executes, the code in the “body” of the while loop may be executed (i.e. run) several times. Each time the code of the body is executed is known as a single “iteration” of the while loop. In general we say that the while loop “iterates over” the code in the body of the loop.

35.4 Using the debugger to understand the code

It is often helpful to use R’s debugger to help understand the code for a loop. Information about how to use R’s debugger is above in the debugger section.

As a quick refresher - to use the debugger, you should first run the code shown above that defines the function myFactorial. Then type the command debugonce(myFactorial) and finally call the function, e.g. myFactorial(5). At that point the debugger should start. To see how the code works, you can repeatedly press the “next” button (or type n). Every time you do so, the code will advance one line. You can use this technique to see what “path” the code takes through ifs and loops. You should pay attention to how the values of the variables in the “Environment” pane change as the code is executed. Tracing through code in this way is one of the best ways to understand how the code works.

35.5 Things to keep in mind when writing while loops

When writing while loops, keep the following in mind:

  1. The condition, which appears in the parentheses, should depend on at least one variable.

    In this example, the condition is (num > 1). This particular condition contains one variable, i.e. num. It is very possible for a condition to be more complicated than this and contain more than one variable.

  2. The condition must be true for the code in the body to be executed. The condition must be false for the code in the body to NOT be executed.

  3. The value of the variable(s) in the condition must be setup in the code that appears BEFORE the while.

    In this example, the value of num was passed into the function, therefore its value was set before the while loop started.

  4. The code inside the {curly braces} is known as the “body” of the loop.

  5. The code in the body should eventually cause the condition to become false. The most common way to do that is for the body to change the value of a variable in the condition in some way.

    In this example, the line : num <- num - 1 changes the value of num by subtracting one from it. If this happens enough times, the value of num will eventually become 1, thus making the condition FALSE.

35.6 Infinite loop - press the STOP button (and/or ESC key)

#########################################################################
#
# *** IMPORTANT ***
#
# Writing code with loops can be tricky, especially if you're new at it.
# Watch out for potential coding errors ... be CAREFUL!!!
#########################################################################

#....................................................................
# Infinite loops
#....................................................................
# IMPORTANT ... When writing code with while loops it is possible to 
# introduce errors in which the loop will "never end". 
# This is called an "infinite loop". If your code enters an "infinite loop",
# RStudio will become unresponsive. If you don't know what to do it can be
# very frustrating!!  When this happens, either: 
#
#   - a little red "stop sign" button usually appears above the console
#     window pane in RStudio. Pressing the "stop sign" will stop the function
#     from running and let you once again use RStudio normally.
#
#   - If you don't see the stop sign, try pressing the ESC key. This can 
#     happen if you while loop is running with a call to readline() or a
#     similar function inside the loop. 
#
# In the following code, I purposely introduced an "infinite loop". You 
# will not be able to move on until you press the "stop sign" button that
# is above the console window pane in RStudio.
#....................................................................

# The following version of myFactorial has a bug that 
# causes an infinite loop.

badMyFactorial <- function(num){
 if (num <0 || !is.numeric(num) || trunc(num) != num || length(num) != 1) {
  stop("num must be a single positive whole number")
 }
 
 answer = 1
 
 # A while loop is similar to an if in that if the condition is true
 # then the code in the body runs. If the condition is false the body does not run
 # and the next line of the program after the body runs.
 
 # For every while loop you must keep in mind the following
 # 1. The condition must depend on SOME variable
 # 2. The body must eventually cause the condition to become false.
 #    The most common way to do that is for the body to change
 #    the value of a variable in the condition in some way.
 
 while(num > 1) {
  answer <- answer * num
  #   num <- num - 1       (I purposely "commented out" this line to cause an infinite loop)
 }
 
 return(answer)
}

# The following calls actually work correctly.
# This is becuase the while loop never even starts since the condition, (num > 1), 
# is FALSE even before the first "iteration" of the while loop.


badMyFactorial(0)
[1] 1
badMyFactorial(1)
[1] 1
# The following calls to badMyFactorial cause an infinite loop.

# badMyFactorial(2)
# badMyFactorial(5)

# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
# inifinite loop - press the "stop sign button" (above the console window pane)
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
badFunction = function (num){

  # This is an infinite loop  
  while (TRUE) {
    cat ('You are in an "infinite loop".\n')
    cat('Press the "stop sign" button (above the console window pane) to ',
        'stop the infinite loop\n\n')
    
    Sys.sleep(0.9)  # this causes R to "go to sleep" for 0.9 seconds
  }
}

# badFunction(1)  # This will result in an "infinite loop". Press the "stop button".


# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
# Another inifinite loop - there is no stop sign button.
#
# If you enter an infinite loop while the computer is waiting for the user
# to type something, you will NOT see a "stop sign button". Instead to 
# get out of the loop
# 
#   - click on the console window pane
#   - then click on the ESC key
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
anotherBadFunction = function() {
  
  # This is an infinite loop. You will NOT see a stop sign button.
  # Instead press ESC to get out of the loop.
  while(TRUE){
    x = readline("What's your name? (to stop looping, click console window, then press ESC)")    
  }

}


# The following will cause another infinite loop
# Click console window then press ESC key to stop the loop and get back the prompt.
#
#
# anotherBadFunction() # another infinite loop -

35.7 Practice with finding errors in loops

# The following is the same exact code as above, without all the 
# comments. There are many different subtle errors that can pop up
# when writing while loops. Think about what would happen in each of the
# following situations ..
#
# What would happen in each of the situations listed below?
# To find out, change the code and try it.
#
# For each of the following questions, try to figure out what will happen
# before actually running the code. Then change the code and run it.
# To help you figure out what will happen, keep track of the values of all
# the variables and arguments on a piece of paper.
# Then, every time you "run a line of code in your head" keep track of any
# changes to the variables on the piece of paper.
#
# You can also use the debugger ...
#
# What would happen if ...
#    1. ... instead of "answer=1"     the programmer typed "answer=0" ?
#    2. ... instead of "while(num>1)" the programmer typed "while(num<1)" ?
#    3. ... instead of "num<-num+1"   the programmer typed "num<-num-1"
#    4. ... the programmer forgot to type the line "num<-num-1" and just left it out?
#    5. ... the programmer wrote the lines "answer<-answer*num" and "num<-num-1"
#           in the opposite order, i.e. "num<-num-1" and then "answer<-answer*num"

myFactorial <- function(num){
  if (num <0 || !is.numeric(num) || trunc(num) != num || length(num) != 1) {
    stop("num must be a single positive whole number")
  }
  
  answer = 1
  
  while(num > 1) {  
    answer <- answer * num
    num <- num - 1
  }
  
  return(answer)
}

myFactorial(4)
[1] 24
#debugonce(myFactorial)

myFactorial(4)  # The result SHOULD BE 24
[1] 24
myFactorial(100)
[1] 9.332622e+157

35.8 Another example: is.prime(num)

#--------------------------------------
# Another example ...
#--------------------------------------

# The following function 
# returns TRUE if num is a prime number and
# returns FALSE is num is not a prime number
#
# A prime number is a whole number (2 or more) that is 
# divisible by only 1 and itself.
#
# Technically 1 is NOT a prime number
# https://blogs.scientificamerican.com/roots-of-unity/why-isnt-1-a-prime-number/
 

is.prime <- function( num ) {

  if (num < 2){
    return(FALSE)
  }
  
  divisor <- 2
  
  # if at any point you find that num is divided
  # evenly by some divisor, return FALSE
  
  while ( divisor < num ) {
    if (num %% divisor == 0){
      return(FALSE)   
    }
    divisor <- divisor + 1    
  }
  
  return(TRUE)
}

is.prime(7) # TRUE
[1] TRUE
is.prime(35) # FALSE
[1] FALSE
is.prime(37) # TRUE
[1] TRUE
is.prime(77) # FALSE
[1] FALSE
## Making the code "more efficient"
#----------------------------------------------------
# Making the code "more efficient"
#----------------------------------------------------

# When the number gets large the while loop will need to "loop" many times.
# This can take some time even on a computer.

is.prime(181) # TRUE
[1] TRUE
#is.prime(15485867)   # TRUE  (takes a few seconds to run)

#is.prime(236887699)  # TRUE  (takes some time to run) - press "stop button" to cancel

is.prime(236887695)  # FALSE - very fast ... why?
[1] FALSE
#---------------------------------------------------------------------------
# Making a program more "efficient"
#---------------------------------------------------------------------------
# Do you really need to check all of the divisors from 2 through num-1 ?
#
# Obvious improvements:
#   - if a num is even you know that result is FALSE
#   - if num ends in 5 or 0 you know it is divisible by 5 so result is FALSE
#
# Non-obvious improvment:
#   - you only need to check the divisors from 2 through the sqrt(num) ... not through num
#     This speeds up the code A LOT.
#
# "Computer science" classes focus a lot on how to improve the "efficiency" of
# programs. We will NOT focus on efficiency. However, you should be familiar
# with the general issue.
#---------------------------------------------------------------------------

# With the knowledge of the above "non-obvious improvement"
# let's write a "more efficient" version of the function. 
# The following version also works but is "faster", i.e. it doesn't need to 
# check as many numbers. 
# 
# The code is the same as the previous version except for the 
# line below that says "#This line changed"

better.is.prime <- function( num ) {
  
  if (num < 2){
    return(FALSE)
  }
  
  divisor <- 2
  
  while ( divisor <= sqrt(num) ) {     # This line changed
    
    if (num %% divisor == 0){
      return(FALSE)   
    }
    divisor <- divisor + 1
  }
  
  return(TRUE)
}

better.is.prime(181) # TRUE
[1] TRUE
better.is.prime(15485867)   # TRUE  - returns right away
[1] TRUE
better.is.prime(236887699)  # TRUE  - returns right away
[1] TRUE

35.9 More practice finding errors in loops

# The following is the same function again, this time without the comments.
#
# For each of the following questions, try to figure out what will happen
# before actually running the code. Then change the code and run it.
# To help you figure out what will happen, keep track of the values of all the variables
# and arguments on a piece of paper. Every time you "run a line of code in
# your head" keep track of any changes to the variables on the piece
# of paper. You can also use the debugger ...
#
# What would happen if ...
# 1. ... instead of "divisor <- 2"        the programmer typed "divisor <- 1" ?
# 2. ... instead of "while(divisor<num)"  the programmer typed "while(divisor>num)" ?
# 3. ... instead of "while(divisor<num)"  the programmer typed "while(divisor<=num)" ?
# 4. ... the line   "divisor<-divisor+1"  was mistakenly left out?
# 5. ... the line   "divisor<-divisor+1"  was inside the body of the if?
# 6. ... the line   "divisor<-divisor+1"  was before the if instead of after the if?
# 7. ... the line   "divisor<-divisor+1"  was before the if instead of after the if ...
#        and instead of "divisor <- 2"    the programmer typed "divisor <- 1" ?
# 8. ... the programmer forgot to type the last line "return(TRUE)".
# 9. ... instead of "while(divisor<num)"  the programmer typed "while(divisor<num/2)" ?
# 10. ... instead of "while(divisor<num)"  the programmer typed "while(divisor<sqrt(num))" ?

is.prime <- function( num ) {
  if (num < 2){
    return(FALSE)
  }

  divisor <- 2
  while ( divisor < num ) {       
    if (num %% divisor == 0){
      return(FALSE)   
    }
    divisor <- divisor + 1
  }
  return(TRUE)
}

is.prime(35)
[1] FALSE
is.prime(37)
[1] TRUE

35.10 There are MANY ways to write the same function

#----------------------------------------------------
# Another way to write the same function.
#
# This version has a single return statement at the end of the function.
# Some people argue that this style is "cleaner" and
# easier to understand when reading the code.
#----------------------------------------------------

is.prime2 <- function( num ) {
  answer <- TRUE   # assume answer is TRUE unless we find out otherwise
  
  if (num < 2){
    answer <- FALSE
    
  } else {
  
    divisor <- 2
    while ( divisor < num ) {
      if (num %% divisor == 0){
        answer <- FALSE
      }
      divisor <- divisor + 1
    }
  }
  
  return(answer)
}

is.prime2(35)  # FALSE
[1] FALSE
is.prime2(37)  # TRUE
[1] TRUE
# check to make sure that both versions return the same values

#all(sapply(1:100,is.prime) == sapply(1:100,is.prime2))   # TRUE

35.11 another example - divisors(num)

#--------------------------------------------------
# Write a function to find all divisors of a number
# (assume that num is a positive whole number)
#--------------------------------------------------

divisors <- function(num){
  if (!is.numeric(num) || trunc(num)!=num || num<1 || length(num)!=1){
    stop("num must be a single positive whole number")
  }
  
  # This is the variable we will return at the end of the function.
  answer <- 1  # 1 is a divisor of all positive whole numbers
  
  divisor <- 2              
  while(divisor <= num){
    if (num %% divisor == 0){
      answer <- c(answer, divisor)  # add another number to the answer
    }
    divisor <- divisor + 1
  }
  
  return(answer)
}

#debugonce(divisors)
divisors(12)
[1]  1  2  3  4  6 12
divisors(15)
[1]  1  3  5 15
divisors(36)
[1]  1  2  3  4  6  9 12 18 36
divisors(100)
[1]   1   2   4   5  10  20  25  50 100
divisors(101)  # this is prime, only divisors are 1 and 101
[1]   1 101
#divisors(15485863)  # This will take a few seconds.
#divisors(67867979)  # This will take a few seconds.
#divisors(67867970)  # This will take a few seconds.

35.12 more efficient version

#-------------------------------------
# a more efficient version
#-------------------------------------

divisors.faster <- function(num){
  if (!is.numeric(num) || trunc(num)!=num || num<1 || length(num)!=1){
    stop("num must be a single positive whole number")
  }
  
  answer <- c(1,num)                    # changed this line
  
  divisor <- 2
  while(divisor <= sqrt(num)){          # changed this line (why?)
    if (num %% divisor == 0){
      answer <- c(answer, divisor)
      answer <- c(answer, num/divisor)  # added this line  (why?)
    }
    divisor <- divisor + 1
  }
  
  answer <- sort(unique(answer))        # added this line  (why?)
  return(answer)
}

#debugonce(divisors.faster)
divisors.faster(36)
[1]  1  2  3  4  6  9 12 18 36
divisors.faster(12)
[1]  1  2  3  4  6 12
divisors.faster(10)
[1]  1  2  5 10
divisors.faster(97)
[1]  1 97
divisors.faster(100)
[1]   1   2   4   5  10  20  25  50 100
divisors.faster(15485863)  # much faster now!!!
[1]        1 15485863
divisors.faster(15485864)  # much faster now!!!
 [1]        1        2        4        8       31       41       62       82
 [9]      124      164      248      328     1271     1523     2542     3046
[17]     5084     6092    10168    12184    47213    62443    94426   124886
[25]   188852   249772   377704   499544  1935733  3871466  7742932 15485864
divisors.faster(67867979)  # much faster now!!!
[1]        1 67867979
divisors.faster(67867970)  # much faster now!!!
[1]        1        2        5       10  6786797 13573594 33933985 67867970
# check to see that both functions are equivalent

#all ( divisors.faster(15485864) == divisors(15485864) )  # TRUE if all nums are the same

35.13 More practice - mysum(NUMS)      blastoff(SECONDS)

###############################################################################
# The next two "QUESTIONS" (i.e. to write the "mysum" and "blastoff" functions)
# do not present any new concepts. They are just additional examples. 
###############################################################################


#----------------------------------------------------------
# QUESTION
# Write a function that simulates the sum function
#
#    mysum = function( nums )
#
# nums is expected to be a numeric vector
# mysum should return the sum of all the numbers in nums
# DO NOT USE THE SUM FUNCTION
#----------------------------------------------------------

mysum = function( nums ){

  theSum = nums[1]
  position = 2
  
  while(position <= length(nums)){
    theSum = theSum + nums[position]
    position = position + 1
  }
    
  theSum  # return the answer
}

mysum(c(10,20,5)) # 35
[1] 35
mysum(10) # 10
[1] 10
# Note that the following returns NA, which makes sense because a sum
# is not applicable (i.e. Not Available) if there are no numbers specified.
mysum( numeric(0) ) 
[1] NA
# You should use the debugger to understand why we get NA. 
#
# debugonce(mysum)
mysum( numeric(0) ) 
[1] NA
#-------------------------------------------------------------------
# The following is a SLIGHTLY different version of the function.
# In this version we returned a sum of 0 when the numeric vector
# is an empty vector. This is also a reasonable answer. 
#-------------------------------------------------------------------

mysum = function( nums ){
  
  theSum = 0                             # this line changed
  position = 1                           # this line changed   
  
  while(position <= length(nums)){
    theSum = theSum + nums[position]
    position = position + 1
  }
  
  theSum  # return the answer
}

mysum(c(10,20,5))    # 35
[1] 35
mysum(character(0))  # 0
[1] 0
#---------------------------------------------------------
# QUESTION
#
# Write a function
#
#    countdown = function(from)
#
# that counts down as shown below. There should be 1 second
# pause between each line of output HINT: use Sys.sleep(1)
# 
# > countdown(5)
# T minus 5 seconds
# T minus 4 seconds
# T minus 3 seconds
# T minus 2 seconds
# T minus 1 second
# BLASTOFF!!!
#
# > countdown(3)
# T minus 3 seconds
# T minus 2 seconds
# T minus 1 second
# BLASTOFF!!!
#
# > countdown(0)
# BLASTOFF!!!
#-----------------------------------------------------------

###########.
# ANSWER
###########.
countdown = function(from){
  
  while(from > 0){
    
    if(from == 1){
      cat("T minus", from, "second\n")
    } else {
      cat("T minus", from, "seconds\n")
    }
    
    Sys.sleep(1)
    from = from - 1
    
  }
  
  cat("BLASTOFF!!!")
  
}

countdown(5)
T minus 5 seconds
T minus 4 seconds
T minus 3 seconds
T minus 2 seconds
T minus 1 second
BLASTOFF!!!
#countdown(3)
#countdown(0)

35.14 Random numbers : runif()

####################################################################
####################################################################
##
## Generating random numbers
##
##   - runif                       : returns a random number
##   - set.seed(SOME_WHOLE_NUMBER) : resets the random number generator
##   - sample
##
####################################################################
####################################################################

# There are several different functions that are built into R for
# generating "random numbers". These are useful for "simulations"
# e.g. to generate random 


# View the help pages by typing: 
#
#    ?runif
#    ?set.seed
#    ?sample

#--------------------------------------------------------------
#
# runif  
#
# runif stands for "Random number from a UNIForm distribution
#
#--------------------------------------------------------------

runif(1)   # one random number between 0 and 1  (not including 0.0 or 1.0)
[1] 0.5955975
runif(1)   # another random number between 0 and 1  (not including 0.0 or 1.0)
[1] 0.6974013
runif(3)   # three random numbers between 0 and 1
[1] 0.08113108 0.80810731 0.20745448
runif(3, min=0, max=100)   # three random numbers between 0 and 100
[1] 19.26440 38.41008 45.59523
runif(3, min=500, max=505)   # three random numbers between 500 and 505
[1] 502.9197 502.5152 504.1375
trunc(runif(25, min=1, max=11))   # 25 random whole numbers between 1 and 10
 [1]  9  9  8  4 10  6  7  2  1  8  4  7  9  2  4 10  7  4  5 10  2  8  1  7  4
trunc(runif(25, min=1, max=11))   # another 25 random whole numbers between 1 and 10
 [1]  1  5  5 10  8  7  1  2  6  3  8  4  9  7  1  7  5  5  6  9  9  7  1  3  4
#-----------------------------
# set.seed(SOME_WHOLE_NUMBER)
#-----------------------------
set.seed(1)
trunc(runif(3, min=1, max=10))   # 5 random whole numbers between 1 and 9
[1] 3 4 6
trunc(runif(3, min=1, max=10))   # another 5 random whole numbers between 1 and 9
[1] 9 2 9
trunc(runif(3, min=1, max=10))   # another 5 random whole numbers between 1 and 9
[1] 9 6 6
set.seed(1)
trunc(runif(3, min=1, max=10))   # start again with same numbers
[1] 3 4 6
set.seed(1)
trunc(runif(3, min=1, max=10))   # start again with same numbers
[1] 3 4 6
trunc(runif(3, min=1, max=10))   # continue in with the same numbers as when seed was 1
[1] 9 2 9
trunc(runif(3, min=1, max=10))   # continue in with the same numbers as when seed was 1
[1] 9 6 6
set.seed(99)  # different seed starts again with different numbers
trunc(runif(3, min=1, max=10))   #
[1] 6 2 7
trunc(runif(3, min=1, max=10))   #
[1] 9 5 9
set.seed(99)  # start again with same seed
trunc(runif(3, min=1, max=10))   #
[1] 6 2 7
trunc(runif(3, min=1, max=10))   #
[1] 9 5 9
set.seed(1)   # back to first sequence of numbers  
trunc(runif(3, min=1, max=10))   # start again with same numbers
[1] 3 4 6
trunc(runif(3, min=1, max=10))   # continue in with the same numbers as when seed was 1
[1] 9 2 9

35.15 Random numbers : sample()

#-----------------------------------------------------------------------------
# sample  
# 
# NOTE: This is review. We already covered the sample function in an earlier class.
#-----------------------------------------------------------------------------
# View the help page by typing: 
#
#   ?sample

sample(c(10,20,30,40,50,60,70,80,90,100), 3)  # sample 3 items from the set
[1] 70 20 30
sample(c(10,20,30,40,50,60,70,80,90,100), 7)  # sample 7 items from the set
[1]  30  10  50  80  20  60 100
sample(c(10,20,30,40,50,60,70,80,90,100), 10)  # sample 10 items from the set
 [1]  90  50 100  10  70  80  60  20  30  40
sample(c(10,20,30,40,50,60,70,80,90,100))  # sample 10 items from the set
 [1]  90  10  40  30  60  20  50  80 100  70
# with replacement
sample(c(10,20,30,40,50,60,70,80,90,100), 7, replace=TRUE)  # allow same item more than once
[1]  40 100  90  70  60  90  80
sample(c(10,20,30,40,50,60,70,80,90,100), 25, replace=TRUE)  # allow same item more than once
 [1]  90  70  80  60 100  70  30 100  60  80  20  20  60  60  10  30  30  80  60
[20]  70  60  80  70  10  40
sample(c(10,20,30,40,50,60,70,80,90,100), 25, replace=FALSE)  # ERROR
Error in sample.int(length(x), size, replace, prob): cannot take a sample larger than the population when 'replace = FALSE'
sample(c(10,20,30,40,50,60,70,80,90,100), 25)  # ERROR
Error in sample.int(length(x), size, replace, prob): cannot take a sample larger than the population when 'replace = FALSE'
sample(1:10)               # sample all items without replacement
 [1]  8  9 10  1  6  4  3  7  5  2
sample(1:10, replace=TRUE) # sample 10 times with replacement
 [1] 6 1 5 6 1 9 7 7 3 6
# set probabilities on specific values
sample(c(1,2,3), 25, replace=TRUE, prob=c(.7,.2,.1)) # 70% prob 1, 20% prob 2, 10% prob 3
 [1] 1 1 2 1 1 1 3 1 1 1 2 1 1 1 1 1 1 1 1 1 3 1 1 1 3
sample(c(1,2,3), 25, replace=TRUE, prob=c(.7,.2,.1)) # 70% prob 1, 20% prob 2, 10% prob 3
 [1] 1 1 1 1 1 2 1 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 2 1 2
# set.seed works for sample too
set.seed(9876)
sample(c(1,2,3), 25, replace=TRUE, prob=c(.7,.2,.1)) # 70% prob 1, 20% prob 2, 10% prob 3
 [1] 2 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 1 1 1 3 2 1 1 1
sample(c(1,2,3), 25, replace=TRUE, prob=c(.7,.2,.1)) # 70% prob 1, 20% prob 2, 10% prob 3
 [1] 1 1 2 1 1 1 1 3 1 1 3 3 1 1 2 2 1 2 1 1 2 1 1 1 1
set.seed(9876)
sample(c(1,2,3), 25, replace=TRUE, prob=c(.7,.2,.1)) # 70% prob 1, 20% prob 2, 10% prob 3
 [1] 2 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 2 1 1 1 3 2 1 1 1
sample(c(1,2,3), 25, replace=TRUE, prob=c(.7,.2,.1)) # 70% prob 1, 20% prob 2, 10% prob 3
 [1] 1 1 2 1 1 1 1 3 1 1 3 3 1 1 2 2 1 2 1 1 2 1 1 1 1

35.16 Another exmaple - guessingGame()

#-------------------------------------------------------------------------
# Write a guessing game function
#-------------------------------------------------------------------------
# Function should
# 1. pick a random number between 1 and 100
# 2. allow the user to guess the number
# 3. keep looping until the user guesses correctly
# 4. return the number of times it took the user to guess correctly
#-------------------------------------------------------------------------
# NOTE: The following line of code that appears in the function is important
#       but easy to forget to include. This line of code converts the guess
#       from character to numeric. Without this line you would wind up with a
#       very hard to catch bug.
#
#                    guess <- as.numeric(guess) 
#
# Remember that readline always returns a character value.
# Without the code shown above, guess would be character and num would be numeric.
# This would have caused the following problem:
#
#    1. The code "if(guess < num)", which appears in the code below will
#       be comparing a character value with a numeric value.
#
#    2. Remember that character values sort and compare differently than
#       numeric values. For the purpose of this dicussions, remember
#       that "29" and "3" are both character values, while
#       29 and 3 (without the quotes) are numeric values.
#
#         29 < 3 is obviously FALSE, however ..
#
#         "29" < "3" is TRUE!!!
#
#       This is because character values have different rules for 
#       comparison than numeric values do. (Remember - because the first
#       character, in "29" i.e. the "2" is less than the first charcter
#       in "3", i.e. "3", "29" is less than "3".
#
#    3. Because the code "guess < num" compares a character value (i.e. guess)
#       and a numeric value (i.e. guess) the rules of "implicit conversions"
#       determines that both values will be implicitly converted
#       to character values. That means that if guess was "29" and num was 3
#       "29" < 3  would be implicitly converted to "29" < "3" which would
#       be TRUE! That would cause the block of code following
#       if(guess < num) be executed and the user would be told
#       "higher, guess again:" instead of the correct answer of
#       "lower, guess again".
#
#    4. By converting the guess to numeric, the code if(guess < num) will 
#       now correctly compare two numeric values and will correctly 
#       figure out that 29 < 3 is FALSE and will correctly tell the user
#       "lower, guess again".
#-------------------------------------------------------------------------

guessingGame <- function(low=1, high=100){
  
  if (!is.numeric(low) || length(low) != 1 || trunc(low) != low ||
      !is.numeric(high) || length(high) != 1 || trunc(high) != high ) {
    stop("min and max must each be single whole numbers")
  }
  
  if (low >= high){
    stop("low must be less than high")
  }
  
  num <- sample(low:high, 1)
  
  numGuesses <- 1
  guess <- readline("guess: ")
  guess <- as.numeric(guess) # IMPORTANT LINE - see the NOTE in comments above
  
  while(guess != num) {
    if (guess < num){
      guess <- readline("higher, guess again: ")
    } else if (guess > num) {
      guess <- readline("lower, guess again: ")
    }
    
    guess <- as.numeric(guess) # IMPORTANT LINE - see comment above for more info
    numGuesses <- numGuesses + 1
  } 

  return(numGuesses)  
}

#guessingGame()   
#guessingGame()
#guessingGame()

35.17 Another example - Fibonacci sequence

#-------------------------------------
# Another example - Fibonacci sequence
#-------------------------------------

# The numbers 0 1 1 2 3 5 8 13 21 34 55 89 144 ...
# are the first few number in the infinite sequence
# of "Fibonacci numbers". The first two numbers are 0 and 1
# Every other number in the sequence is the sum of the
# two numbers that precede it. 
#
# Write a function fib(n)  that returns the first
# n numbers from the fibonacci sequence. 
#
# n is expected to be a single non-negative whole number.
# The function should stop with an appropriate 
# error message if it is not.
#
# EXAMPLE:
#    > fib(1)
#    0
#
#    > fib(4)
#    0 1 1 2
#
#    > fib(8)
#    0 1 1 2 3 5 8 13

fib <- function(n){
  
  if (!is.numeric(n) || length(n) != 1 || n <= 0){
    stop("n must be a single whole non-negative number")
  }
  
  if (n == 1){
    return(0)
  } else if (n == 2) {
    return(c(0,1))
  }
  
  # set up the variables for the condition in the while
  # (n already has a value since it is an argument to the function)
  answer <- c(0,1)    
  
  while(length(answer) < n){   # a condition that will eventually become FALSE
    
    twoPrevious <- answer[length(answer)-1]
    onePrevious <- answer[length(answer)]
    
    # change a variable that's in the condition
    answer<-c(answer,onePrevious+twoPrevious) 
    
  }
  
  return(answer)
}

fib(0)
Error in fib(0): n must be a single whole non-negative number
fib(1)
[1] 0
fib(4)
[1] 0 1 1 2
fib(8)
[1]  0  1  1  2  3  5  8 13
fib(20)
 [1]    0    1    1    2    3    5    8   13   21   34   55   89  144  233  377
[16]  610  987 1597 2584 4181
lapply(1:10, fib)
[[1]]
[1] 0

[[2]]
[1] 0 1

[[3]]
[1] 0 1 1

[[4]]
[1] 0 1 1 2

[[5]]
[1] 0 1 1 2 3

[[6]]
[1] 0 1 1 2 3 5

[[7]]
[1] 0 1 1 2 3 5 8

[[8]]
[1]  0  1  1  2  3  5  8 13

[[9]]
[1]  0  1  1  2  3  5  8 13 21

[[10]]
 [1]  0  1  1  2  3  5  8 13 21 34

35.18 another example - primesUpTo(maxNum)

rm(list=ls())  # start over ...

# The following code was already created above. This is the exact same 
# code. It is copied here for reference, since the next function,
# primesUpTo, calls this code.

is.prime <- function( num ) {
  if (num < 2){
    return(FALSE)
  }
  divisor <- 2
  
  while ( divisor <= sqrt(num) ) {
    if (num %% divisor == 0){
      return(FALSE)   
    }
    divisor <- divisor + 1
  }
  return(TRUE)
}

#-----------------------------------------
# Get all primes up to a certain number
#-----------------------------------------

# Things to think about in the next function.
# 
# 1. What would happen if the line: numToCheck = numToCheck + 1
#    were placed inside of the block of code for the if?

# All primes up to n
primesUpTo = function( maxNum ){
  primes = numeric(0)
  
  # Set up the variables that are used in the condition 
  # maxNum already has a value since it is an argument to the function
  numToCheck = 2
  
  while (numToCheck <= maxNum){  # a condition that will eventually become FALSE
    
    if(is.prime(numToCheck)){
      primes = c(primes, numToCheck)
    }
    
    # change a variable that is in the condition in a way that will eventually
    # make the condition become FALSE
    numToCheck = numToCheck + 1
  }
  
  primes
}

primesUpTo(10)
[1] 2 3 5 7
primesUpTo(100)
 [1]  2  3  5  7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
primesUpTo(1000)
  [1]   2   3   5   7  11  13  17  19  23  29  31  37  41  43  47  53  59  61
 [19]  67  71  73  79  83  89  97 101 103 107 109 113 127 131 137 139 149 151
 [37] 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251
 [55] 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359
 [73] 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463
 [91] 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593
[109] 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701
[127] 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827
[145] 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953
[163] 967 971 977 983 991 997

35.19 another example - firstNPrimes ( N )

#---------------------------------
# Get first n primes
#---------------------------------
# Things to think about in the following function.
# 
# 1. What would happen if the line: numberToCheck = numberToCheck + 1
#    was not typed at all?

firstNPrimes = function( numPrimes ){
  
  # This is the variable that will be returned.
  # It is also a variable that is used in the condition.
  # We MUST give it a value for both of these reasons.
  primes = numeric(0)
  
  # Setup any other values that the while loop will need.
  numberToCheck = 2
  
  while(length(primes)<numPrimes){ # condition that will evenutually become FALSE
    
    if (is.prime(numberToCheck)){
      primes = c(primes, numberToCheck)
    }
    
    # change a variable that is used the the condition in a way that 
    # eventually the condition will become FALSE
    numberToCheck = numberToCheck + 1
  }

  primes
}

firstNPrimes(10)
 [1]  2  3  5  7 11 13 17 19 23 29
firstNPrimes(20)
 [1]  2  3  5  7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
firstNPrimes(100)
  [1]   2   3   5   7  11  13  17  19  23  29  31  37  41  43  47  53  59  61
 [19]  67  71  73  79  83  89  97 101 103 107 109 113 127 131 137 139 149 151
 [37] 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251
 [55] 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359
 [73] 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463
 [91] 467 479 487 491 499 503 509 521 523 541
primes3000 = firstNPrimes(3000)
length(primes3000)   # 3000
[1] 3000
tail(primes3000, 10)
 [1] 27337 27361 27367 27397 27407 27409 27427 27431 27437 27449

35.20 Another example - flightsBeforeReturning() , itineraray()

#############################################################.
# The following example is interesting but doesn't add any new 
# concepts.
#
# 2022 - We skipped going over this example in class for both
# Wilf and Beren classes but I told students to look at this example
# on their own.
#
# -Prof. Rosenthal
#############################################################.

#---------------------------------------------------------------------
# How many flights are needed before you get back to the city you 
# started?
#---------------------------------------------------------------------

# Given the following data:

# The vector cities has names and values that are the same set of cities
# just arranged in a different order. Interpret the names of the vector 
# positions as the cities where an airline has flights. The management of 
# the company schedules the flights based on the data in the vector.
# (see below for more info)

cities = c("new york", "london", "tokyo", "l.a.", "tel aviv", "brussels", "moscow")
names(cities) = sort(cities)
cities
  brussels       l.a.     london     moscow   new york   tel aviv      tokyo 
"new york"   "london"    "tokyo"     "l.a." "tel aviv" "brussels"   "moscow" 
# The airline has a complex scheduling system for each of their planes.
# Each plane flies from city to city to city based on the data shown above.
# Eventually a plane will return to its original city.
#
# For example, a plane that 
#    starts in Brussels will fly to New York
#    From New york, that same plane will fly to Tel Aviv.
#    From Tel Aviv, that same plane will fly back to Brussels
# for a total of 3 flights before it returns to where it started.
#
# Similarly, a plane that 
#    starts in L.A. office will fly to London.
#    From London, that same plane will fly to Tokyo.
#    From Tokyo, that same plane will fly to Moscow.
#    From Moscow that same plane will fly back to L.A.
# for a total of 4 flights before it returns to where it started.
#
# Write a function
#      flightsBeforeReturning = function(staringCity, schedulingVector)
#
# that figures out how many flights it will take for a plane that 
# starts in startingCity will have to fly before it returns to the same
# startingCity based on the data in the schedulingVector.

flightsBeforeReturning = function(startingCity, schedulingVector){
  
  currentCity = startingCity
  numberOfFlights = 0
  
  while( schedulingVector[ currentCity ] != startingCity ){
    currentCity = schedulingVector[ currentCity ]
    numberOfFlights = numberOfFlights + 1
  }
  
  if (schedulingVector[startingCity] != startingCity)
    numberOfFlights = numberOfFlights + 1
  
  numberOfFlights
}

cities
  brussels       l.a.     london     moscow   new york   tel aviv      tokyo 
"new york"   "london"    "tokyo"     "l.a." "tel aviv" "brussels"   "moscow" 
flightsBeforeReturning("brussels", cities)  # 3
[1] 3
flightsBeforeReturning("l.a.", cities)      # 4
[1] 4
flightsBeforeReturning("london", cities)    # 4
[1] 4
flightsBeforeReturning("moscow", cities)    # 4
[1] 4
flightsBeforeReturning("new york", cities)  # 3
[1] 3
flightsBeforeReturning("tel aviv", cities)  # 3
[1] 3
flightsBeforeReturning("tokyo", cities)     # 4
[1] 4
# Similar function to above, but this time return the actual sequence of
# cities that are visited
itinerary = function(startingCity, schedulingVector){
  
  currentCity = startingCity
  visitedCities = startingCity
  
  while( schedulingVector[ currentCity ] != startingCity ){
    
    visitedCities = c(visitedCities, schedulingVector[currentCity])

    currentCity = schedulingVector[ currentCity ]
  }

  # Add the last leg of the itinerary but only if we flew SOMEWHERE first
  if (schedulingVector[startingCity] != startingCity){
    visitedCities = c(visitedCities, startingCity)
  }
  
  names(visitedCities) = NULL   # remove the names
  
  visitedCities
}

cities
  brussels       l.a.     london     moscow   new york   tel aviv      tokyo 
"new york"   "london"    "tokyo"     "l.a." "tel aviv" "brussels"   "moscow" 
itinerary("brussels", cities)  # "brussels" "new york" "tel aviv" "brussels"
[1] "brussels" "new york" "tel aviv" "brussels"
itinerary("l.a.", cities)      # "l.a."   "london" "tokyo"  "moscow" "l.a."  
[1] "l.a."   "london" "tokyo"  "moscow" "l.a."  
itinerary("london", cities)    # "london" "tokyo"  "moscow" "l.a."   "london"
[1] "london" "tokyo"  "moscow" "l.a."   "london"
itinerary("moscow", cities)    # "moscow" "l.a."   "london" "tokyo"  "moscow"
[1] "moscow" "l.a."   "london" "tokyo"  "moscow"
itinerary("new york", cities)  # "new york" "tel aviv" "brussels" "new york"
[1] "new york" "tel aviv" "brussels" "new york"
itinerary("tel aviv", cities)  # "tel aviv" "brussels" "new york" "tel aviv"
[1] "tel aviv" "brussels" "new york" "tel aviv"
itinerary("tokyo", cities)     # "tokyo"  "moscow" "l.a."   "london" "tokyo" 
[1] "tokyo"  "moscow" "l.a."   "london" "tokyo" 

35.21 Using lapply and sapply to call a function multiple times

Suppose we wanted to get multiple factorials and put them in a vector. We could do so by putting the code for a while loop inside the body of another while loop (i.e. this is called a nested loop). We will explore how to do that in the next section. However, nested loops can be confusing, especially for new programmers.

For now, a simpler way to get the factorials of each value in a numeric vector is to use the lapply function. (For a review of lapply see this section.

#----------------------------------------------------------------
# The myFactorial function above only works with a single number.
# You can get the factorials of many numbers by using lapply
# to get a list of the answers for several numbers
#----------------------------------------------------------------
lapply(c(1,3,5,10), myFactorial)  # find the myFactorials of 1,2,3 and 4
Error: object 'myFactorial' not found

35.21.1 sapply is similar to lapply

#---------------------------------------------------------------------
# sapply
#---------------------------------------------------------------------
# The sapply function is similar to the lapply function.
#
# The "l" in lapply stands for "list" since the return value of 
# lapply is always a list.
#
# The "s" in sapply stands for "simplify". The idea of sapply is that 
# sapply can sometimes return the data in a "simpler" structure 
# than lapply does. In this regard, vectors and matrices are 
# considered "simpler" than lists.
# 
# sapply processes the data in a similar way to lapply. Each value 
# in the vector is passed to the specified function. The return values
# from the function calls are then gathered into a single object 
# (a list, a matrix or a vector) in the following way:
# 
# - If every "answer" (i.e. the return value from the function call) 
#is a single vector of length 1, then sapply will return 
#   all of the answers in a single vector instead of returning a list of answers.
#
# - If every "answer" is a vector that has more than one value but all answers
#   are the same length (e.g. all answers have 2 values or all answers have 3 values, etc)
#   then sapply returns a matrix. Each column in the matrix will contain one of the answers.
#
# - If different "answers" are of different lengths or different classes
#   of data, then sapply returns a list of answers. In this case, sapply
#   and lapply return the same value.
#
# The "s" in "sapply" stands for "simplify". In other words, sapply 
# might return a vector or a matrix, instead of a list. Vectors and matrices
# can be thought of as "simpler" data structures than lists, hence the name "sapply".
#
# The "l" in "lapply" stands for "list". This is because the result
# of calling lapply is ALWAY a list of answers.
#---------------------------------------------------------------------

# compare the following call to sapply with the next call to lapply

# sapply returns a vector in this case since myFactorial always returns a single number
sapply(c(1,3,5,10), myFactorial) 
Error: object 'myFactorial' not found
# lapply always returns a list of answers (remember "l" stands for "list")
lapply(c(1,3,5,10), myFactorial) 
Error: object 'myFactorial' not found

35.21.2 sapply - returns vector, matrix or list

As mentioned above, depending on the return values from the function calls, sapply might return a vector, a matrix or a list.

  • As shown above with the myFactorial function, when all function calls return a single value, sapply returns a vector.

  • The examples below show that when all function calls return vectors of more than one value, but all of the same length, then sapply returns a matrix.

  • The examples below also show that when the function calls return vectors of different lengths, or different classes of data (e.g. dataframes, lists, etc), then sapply returns a list.

#..................................................................
# These values and functions will be used below to demonstrate the 
# differences between the lapply and sapply functions.
#..................................................................

# the following function always returns a vector of 3 numbers
# regardless of the value of num. See examples below.
getThreeNumbers = function(num){
  if(length(num) > 1 || !is.numeric(num)){
    stop("num is expected to be a single number")
  }
  c(num, num+10, num+100)
}
getThreeNumbers(2)
[1]   2  12 102
getThreeNumbers(3)
[1]   3  13 103
getThreeNumbers(5)
[1]   5  15 105
# the following function returns different length vectors
# for different values of num. See examples below.
repNumTimes  = function(num){
  if(length(num) > 1 || !is.numeric(num)){
    stop("num is expected to be a single number")
  }
  rep(num, num)  
}
repNumTimes(2)
[1] 2 2
repNumTimes(3)
[1] 3 3 3
repNumTimes(5)
[1] 5 5 5 5 5
# These are some numbers we will use with the following examples
nums = c(1,3,5,10)

# Function f always returns 3 numbers so sapply returns a matrix of 3 rows.
# There will be as many columns in the matrix as there are numbers in nums.
lapply(nums, getThreeNumbers)   # a list
[[1]]
[1]   1  11 101

[[2]]
[1]   3  13 103

[[3]]
[1]   5  15 105

[[4]]
[1]  10  20 110
sapply(nums, getThreeNumbers)   # a matrix
     [,1] [,2] [,3] [,4]
[1,]    1    3    5   10
[2,]   11   13   15   20
[3,]  101  103  105  110
# Function g returns different length vectors for different numbers
# so sapply returns a list, just as lapply does.
lapply(nums, repNumTimes)   # a list
[[1]]
[1] 1

[[2]]
[1] 3 3 3

[[3]]
[1] 5 5 5 5 5

[[4]]
 [1] 10 10 10 10 10 10 10 10 10 10
sapply(nums, repNumTimes)   # also a list
[[1]]
[1] 1

[[2]]
[1] 3 3 3

[[3]]
[1] 5 5 5 5 5

[[4]]
 [1] 10 10 10 10 10 10 10 10 10 10

35.22 Example: Combining techniques - loops, lapply/sapply, named lists

The following examples show how to use lapply and sapply with the is.prime function.

The following gets the first 20 numbers and checks if they are prime. It’s relatively easy to see which number is prime and which is not as the results are in order - 1st answer is TRUE or FALSE for 1, 2nd answer is TRUE or FALSE for 2, etc.

lapply(1:20, is.prime) 
[[1]]
[1] FALSE

[[2]]
[1] TRUE

[[3]]
[1] TRUE

[[4]]
[1] FALSE

[[5]]
[1] TRUE

[[6]]
[1] FALSE

[[7]]
[1] TRUE

[[8]]
[1] FALSE

[[9]]
[1] FALSE

[[10]]
[1] FALSE

[[11]]
[1] TRUE

[[12]]
[1] FALSE

[[13]]
[1] TRUE

[[14]]
[1] FALSE

[[15]]
[1] FALSE

[[16]]
[1] FALSE

[[17]]
[1] TRUE

[[18]]
[1] FALSE

[[19]]
[1] TRUE

[[20]]
[1] FALSE

The following gets the prime status of the first few odd numbers. It’s harder to see which number is prime and which is not as the first TRUE/FALSE is for 1, the second TRUE/FALSE is for 3, the third TRUE/FALSE is for 5, etc.

lapply(seq(1,19,by=2), is.prime)  # harder to read ... 2nd answer is for 3 not 2
[[1]]
[1] FALSE

[[2]]
[1] TRUE

[[3]]
[1] TRUE

[[4]]
[1] TRUE

[[5]]
[1] FALSE

[[6]]
[1] TRUE

[[7]]
[1] TRUE

[[8]]
[1] FALSE

[[9]]
[1] TRUE

[[10]]
[1] TRUE

We can make it easier to see which number is prime and which is not by creating a named vector where the name of each element in the vector is the number that was checked.

# add names
x = lapply(seq(1,19,by=2), is.prime)
names(x) = seq(1,19,by=2)
x      # names must start with a letter. If they don't you can include the name in `backticks`
$`1`
[1] FALSE

$`3`
[1] TRUE

$`5`
[1] TRUE

$`7`
[1] TRUE

$`9`
[1] FALSE

$`11`
[1] TRUE

$`13`
[1] TRUE

$`15`
[1] FALSE

$`17`
[1] TRUE

$`19`
[1] TRUE
x$`9`  # FALSE
[1] FALSE
x$`17` # TRUE
[1] TRUE
#------------------------------------------.
# Use sapply to get multiple results
#------------------------------------------.

sapply(1:20, is.prime)     # result is below
 [1] FALSE  TRUE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE
[13]  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE
# FALSE  TRUE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE

sapply(seq(1,19,by=2), is.prime)  # # check just the odd numbers
 [1] FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE
#  [1] FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE


# add names
x = sapply(seq(1,19,by=2), is.prime)
names(x) = seq(1,19,by=2)

x      # result is below
    1     3     5     7     9    11    13    15    17    19 
FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE 
#     1     3     5     7     9    11    13    15    17    19 
# FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE

x[9]   # result is below - we only checked odd numbers so the 9th number checked is 17
  17 
TRUE 
#   17 
# TRUE 


x["9"] # result is below - the value whose "name" is "9"
    9 
FALSE 
#     9 
# FALSE 

35.23 NESTED LOOPS

#####################################################################
#####################################################################
##
## NESTED LOOPS 
##
## A "nested loop" is a loop inside of another loop (similar
## to "nested ifs")
##
## We often refer to the "outer loop" and the "inner loop".
##
#####################################################################
#####################################################################

rm(list=ls())   # start over

example = function( maxOuter, maxInner){
  outer = 1
  while(outer <= maxOuter){
    cat("OUTER LOOP (before inner loop): outer=", outer, "\n\n")
    
    inner = 1
    while(inner <= maxInner){
      cat("   INNER LOOP: outer=",outer,"inner=",inner,"\n")
      inner = inner + 1
    }
    
    outer = outer + 1
    
  }
}

example(maxOuter = 2, maxInner = 3)
OUTER LOOP (before inner loop): outer= 1 

   INNER LOOP: outer= 1 inner= 1 
   INNER LOOP: outer= 1 inner= 2 
   INNER LOOP: outer= 1 inner= 3 
OUTER LOOP (before inner loop): outer= 2 

   INNER LOOP: outer= 2 inner= 1 
   INNER LOOP: outer= 2 inner= 2 
   INNER LOOP: outer= 2 inner= 3 
example(maxOuter = 3, maxInner = 5)
OUTER LOOP (before inner loop): outer= 1 

   INNER LOOP: outer= 1 inner= 1 
   INNER LOOP: outer= 1 inner= 2 
   INNER LOOP: outer= 1 inner= 3 
   INNER LOOP: outer= 1 inner= 4 
   INNER LOOP: outer= 1 inner= 5 
OUTER LOOP (before inner loop): outer= 2 

   INNER LOOP: outer= 2 inner= 1 
   INNER LOOP: outer= 2 inner= 2 
   INNER LOOP: outer= 2 inner= 3 
   INNER LOOP: outer= 2 inner= 4 
   INNER LOOP: outer= 2 inner= 5 
OUTER LOOP (before inner loop): outer= 3 

   INNER LOOP: outer= 3 inner= 1 
   INNER LOOP: outer= 3 inner= 2 
   INNER LOOP: outer= 3 inner= 3 
   INNER LOOP: outer= 3 inner= 4 
   INNER LOOP: outer= 3 inner= 5 

35.24 example - primesUpTo() with nested loops

###############################################################################
# 
# Examples of nested loops 
#
###############################################################################

rm(list=ls())  # start over ...

#-----------------------------------------------------------------------------
# Above we defined a
#
#     primesUpTo = function( n )
#
# That returns a vector of all the primes up to n. For example:
#
#     > primesUpTo(15)
#     [1] 2 3 5 7 11 13
#
# In that version of the function, we used a single loop. We also
# called the function is.prime that we had defined earlier inside of the loop.
# Both the funciton is.prime and the function primesUpTo, used a single 
# loop for each function.
#
#
#   ***********************************************************************
#   *** THE FOLLOWING IS ANOTHER WAY OF WRITING THE SAME FUNCTION.      ***
#   *** THIS VERSION DOES NOT CALL is.prime AT ALL. RATHER THIS SINGLE  ***
#   *** FUNCTION DOES ALL OF THE WORK USING TWO DIFFERENT LOOPS -       ***
#   *** ONE INSIDE THE OTHER (i.e. a "nested loop")                     ***
#   ***********************************************************************
#
# The following function, primesUpTo_nestedLoops, returns the exact same values 
# as the primesUpTo function above. However, this version of the function
# does NOT call is.prime. Rather, this version calculates whether a number
# is prime directly in the same function by using a nested loop (i.e. 
# one loop inside of another loop)
#-----------------------------------------------------------------------------

rm(list=ls())

primesUpTo_nestedLoops = function( maxNum ){
 primes = numeric(0)
 
 # Set up the variables that are used in the condition 
 # maxNum already has a value since it is an argument to the function
 numToCheck = 2
 
 while (numToCheck <= maxNum){  # a condition that will eventually become FALSE
  
  isPrime = TRUE
  
  # Check if numToCheck is prime. If it isn't prime set the variable
  # isPrime to FALSE.
  
  divisor = 2
  while(divisor < numToCheck){
   if ( numToCheck %% divisor == 0){
    isPrime = FALSE
   }
   
   divisor = divisor + 1
  }
  
  
  if(isPrime == TRUE){
   primes = c(primes, numToCheck)
  }
  
  # change a variable that is in the condition in a way that will eventually
  # make the condition become FALSE
  numToCheck = numToCheck + 1
 }
 
 primes
}

primesUpTo_nestedLoops(10)
[1] 2 3 5 7
primesUpTo_nestedLoops(100)
 [1]  2  3  5  7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
# VERSION WITH "nested loops"
primesUpTo_nestedLoops = function( maxNum ){
 primes = numeric(0)
 numToCheck = 2
 
 while (numToCheck <= maxNum){
  
  # Use an inner loop to figure out if numToCheck is in fact prime
  # and if it is add numToCheck to the vector primes
  isPrime = TRUE
  divisor = 2
  while(divisor < numToCheck){
   if( numToCheck %% divisor == 0){
    isPrime = FALSE
   }
   
   divisor = divisor+1
  }
  
  # Add the numToCheck to the primes if it in fact is prime
  if(isPrime) {
   primes = c(primes, numToCheck)
  }    
  
  numToCheck = numToCheck + 1
 }
 
 primes
}

primesUpTo_nestedLoops(10)
[1] 2 3 5 7
primesUpTo_nestedLoops(100)
 [1]  2  3  5  7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
primesUpTo_nestedLoops(1000)
  [1]   2   3   5   7  11  13  17  19  23  29  31  37  41  43  47  53  59  61
 [19]  67  71  73  79  83  89  97 101 103 107 109 113 127 131 137 139 149 151
 [37] 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251
 [55] 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359
 [73] 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463
 [91] 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593
[109] 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701
[127] 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827
[145] 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953
[163] 967 971 977 983 991 997

35.25 example - firstNPrimes() with nested loops

QUESTION: Rewrite the function firstNPrimes to use nested loops.
#-----------------------------------------------------------------------
# QUESTION:
# Rewrite the function firstNPrimes that we wrote above. The new version
# should use nested loops instead of calling the is.prime function.
#-----------------------------------------------------------------------

#~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
# For your reference, below are the original versions of the is.prime function
# and the firstNPimes function that calls the is.prime function and does NOT
# use nested loops.
#~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

rm(list=ls())    # start over

is.prime <- function( num ) {
 if (num < 2){
  return(FALSE)
 }
 divisor <- 2
 while ( divisor <= sqrt(num) ) {
  if (num %% divisor == 0){
   return(FALSE)   
  }
  divisor <- divisor + 1
 }
 return(TRUE)
}

firstNPrimes = function( numPrimes ){
 primes = numeric(0)
 numberToCheck = 2
 while ( length(primes) < numPrimes  ){
  if (is.prime(numberToCheck)){
   primes = c(primes, numberToCheck)
  }
  numberToCheck = numberToCheck + 1
 }
 primes
}

firstNPrimes(3)
[1] 2 3 5
firstNPrimes(100)
  [1]   2   3   5   7  11  13  17  19  23  29  31  37  41  43  47  53  59  61
 [19]  67  71  73  79  83  89  97 101 103 107 109 113 127 131 137 139 149 151
 [37] 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251
 [55] 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359
 [73] 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463
 [91] 467 479 487 491 499 503 509 521 523 541
firstNPrimes(1000)
   [1]    2    3    5    7   11   13   17   19   23   29   31   37   41   43
  [15]   47   53   59   61   67   71   73   79   83   89   97  101  103  107
  [29]  109  113  127  131  137  139  149  151  157  163  167  173  179  181
  [43]  191  193  197  199  211  223  227  229  233  239  241  251  257  263
  [57]  269  271  277  281  283  293  307  311  313  317  331  337  347  349
  [71]  353  359  367  373  379  383  389  397  401  409  419  421  431  433
  [85]  439  443  449  457  461  463  467  479  487  491  499  503  509  521
  [99]  523  541  547  557  563  569  571  577  587  593  599  601  607  613
 [113]  617  619  631  641  643  647  653  659  661  673  677  683  691  701
 [127]  709  719  727  733  739  743  751  757  761  769  773  787  797  809
 [141]  811  821  823  827  829  839  853  857  859  863  877  881  883  887
 [155]  907  911  919  929  937  941  947  953  967  971  977  983  991  997
 [169] 1009 1013 1019 1021 1031 1033 1039 1049 1051 1061 1063 1069 1087 1091
 [183] 1093 1097 1103 1109 1117 1123 1129 1151 1153 1163 1171 1181 1187 1193
 [197] 1201 1213 1217 1223 1229 1231 1237 1249 1259 1277 1279 1283 1289 1291
 [211] 1297 1301 1303 1307 1319 1321 1327 1361 1367 1373 1381 1399 1409 1423
 [225] 1427 1429 1433 1439 1447 1451 1453 1459 1471 1481 1483 1487 1489 1493
 [239] 1499 1511 1523 1531 1543 1549 1553 1559 1567 1571 1579 1583 1597 1601
 [253] 1607 1609 1613 1619 1621 1627 1637 1657 1663 1667 1669 1693 1697 1699
 [267] 1709 1721 1723 1733 1741 1747 1753 1759 1777 1783 1787 1789 1801 1811
 [281] 1823 1831 1847 1861 1867 1871 1873 1877 1879 1889 1901 1907 1913 1931
 [295] 1933 1949 1951 1973 1979 1987 1993 1997 1999 2003 2011 2017 2027 2029
 [309] 2039 2053 2063 2069 2081 2083 2087 2089 2099 2111 2113 2129 2131 2137
 [323] 2141 2143 2153 2161 2179 2203 2207 2213 2221 2237 2239 2243 2251 2267
 [337] 2269 2273 2281 2287 2293 2297 2309 2311 2333 2339 2341 2347 2351 2357
 [351] 2371 2377 2381 2383 2389 2393 2399 2411 2417 2423 2437 2441 2447 2459
 [365] 2467 2473 2477 2503 2521 2531 2539 2543 2549 2551 2557 2579 2591 2593
 [379] 2609 2617 2621 2633 2647 2657 2659 2663 2671 2677 2683 2687 2689 2693
 [393] 2699 2707 2711 2713 2719 2729 2731 2741 2749 2753 2767 2777 2789 2791
 [407] 2797 2801 2803 2819 2833 2837 2843 2851 2857 2861 2879 2887 2897 2903
 [421] 2909 2917 2927 2939 2953 2957 2963 2969 2971 2999 3001 3011 3019 3023
 [435] 3037 3041 3049 3061 3067 3079 3083 3089 3109 3119 3121 3137 3163 3167
 [449] 3169 3181 3187 3191 3203 3209 3217 3221 3229 3251 3253 3257 3259 3271
 [463] 3299 3301 3307 3313 3319 3323 3329 3331 3343 3347 3359 3361 3371 3373
 [477] 3389 3391 3407 3413 3433 3449 3457 3461 3463 3467 3469 3491 3499 3511
 [491] 3517 3527 3529 3533 3539 3541 3547 3557 3559 3571 3581 3583 3593 3607
 [505] 3613 3617 3623 3631 3637 3643 3659 3671 3673 3677 3691 3697 3701 3709
 [519] 3719 3727 3733 3739 3761 3767 3769 3779 3793 3797 3803 3821 3823 3833
 [533] 3847 3851 3853 3863 3877 3881 3889 3907 3911 3917 3919 3923 3929 3931
 [547] 3943 3947 3967 3989 4001 4003 4007 4013 4019 4021 4027 4049 4051 4057
 [561] 4073 4079 4091 4093 4099 4111 4127 4129 4133 4139 4153 4157 4159 4177
 [575] 4201 4211 4217 4219 4229 4231 4241 4243 4253 4259 4261 4271 4273 4283
 [589] 4289 4297 4327 4337 4339 4349 4357 4363 4373 4391 4397 4409 4421 4423
 [603] 4441 4447 4451 4457 4463 4481 4483 4493 4507 4513 4517 4519 4523 4547
 [617] 4549 4561 4567 4583 4591 4597 4603 4621 4637 4639 4643 4649 4651 4657
 [631] 4663 4673 4679 4691 4703 4721 4723 4729 4733 4751 4759 4783 4787 4789
 [645] 4793 4799 4801 4813 4817 4831 4861 4871 4877 4889 4903 4909 4919 4931
 [659] 4933 4937 4943 4951 4957 4967 4969 4973 4987 4993 4999 5003 5009 5011
 [673] 5021 5023 5039 5051 5059 5077 5081 5087 5099 5101 5107 5113 5119 5147
 [687] 5153 5167 5171 5179 5189 5197 5209 5227 5231 5233 5237 5261 5273 5279
 [701] 5281 5297 5303 5309 5323 5333 5347 5351 5381 5387 5393 5399 5407 5413
 [715] 5417 5419 5431 5437 5441 5443 5449 5471 5477 5479 5483 5501 5503 5507
 [729] 5519 5521 5527 5531 5557 5563 5569 5573 5581 5591 5623 5639 5641 5647
 [743] 5651 5653 5657 5659 5669 5683 5689 5693 5701 5711 5717 5737 5741 5743
 [757] 5749 5779 5783 5791 5801 5807 5813 5821 5827 5839 5843 5849 5851 5857
 [771] 5861 5867 5869 5879 5881 5897 5903 5923 5927 5939 5953 5981 5987 6007
 [785] 6011 6029 6037 6043 6047 6053 6067 6073 6079 6089 6091 6101 6113 6121
 [799] 6131 6133 6143 6151 6163 6173 6197 6199 6203 6211 6217 6221 6229 6247
 [813] 6257 6263 6269 6271 6277 6287 6299 6301 6311 6317 6323 6329 6337 6343
 [827] 6353 6359 6361 6367 6373 6379 6389 6397 6421 6427 6449 6451 6469 6473
 [841] 6481 6491 6521 6529 6547 6551 6553 6563 6569 6571 6577 6581 6599 6607
 [855] 6619 6637 6653 6659 6661 6673 6679 6689 6691 6701 6703 6709 6719 6733
 [869] 6737 6761 6763 6779 6781 6791 6793 6803 6823 6827 6829 6833 6841 6857
 [883] 6863 6869 6871 6883 6899 6907 6911 6917 6947 6949 6959 6961 6967 6971
 [897] 6977 6983 6991 6997 7001 7013 7019 7027 7039 7043 7057 7069 7079 7103
 [911] 7109 7121 7127 7129 7151 7159 7177 7187 7193 7207 7211 7213 7219 7229
 [925] 7237 7243 7247 7253 7283 7297 7307 7309 7321 7331 7333 7349 7351 7369
 [939] 7393 7411 7417 7433 7451 7457 7459 7477 7481 7487 7489 7499 7507 7517
 [953] 7523 7529 7537 7541 7547 7549 7559 7561 7573 7577 7583 7589 7591 7603
 [967] 7607 7621 7639 7643 7649 7669 7673 7681 7687 7691 7699 7703 7717 7723
 [981] 7727 7741 7753 7757 7759 7789 7793 7817 7823 7829 7841 7853 7867 7873
 [995] 7877 7879 7883 7901 7907 7919
firstNPrimes(2000)
   [1]     2     3     5     7    11    13    17    19    23    29    31    37
  [13]    41    43    47    53    59    61    67    71    73    79    83    89
  [25]    97   101   103   107   109   113   127   131   137   139   149   151
  [37]   157   163   167   173   179   181   191   193   197   199   211   223
  [49]   227   229   233   239   241   251   257   263   269   271   277   281
  [61]   283   293   307   311   313   317   331   337   347   349   353   359
  [73]   367   373   379   383   389   397   401   409   419   421   431   433
  [85]   439   443   449   457   461   463   467   479   487   491   499   503
  [97]   509   521   523   541   547   557   563   569   571   577   587   593
 [109]   599   601   607   613   617   619   631   641   643   647   653   659
 [121]   661   673   677   683   691   701   709   719   727   733   739   743
 [133]   751   757   761   769   773   787   797   809   811   821   823   827
 [145]   829   839   853   857   859   863   877   881   883   887   907   911
 [157]   919   929   937   941   947   953   967   971   977   983   991   997
 [169]  1009  1013  1019  1021  1031  1033  1039  1049  1051  1061  1063  1069
 [181]  1087  1091  1093  1097  1103  1109  1117  1123  1129  1151  1153  1163
 [193]  1171  1181  1187  1193  1201  1213  1217  1223  1229  1231  1237  1249
 [205]  1259  1277  1279  1283  1289  1291  1297  1301  1303  1307  1319  1321
 [217]  1327  1361  1367  1373  1381  1399  1409  1423  1427  1429  1433  1439
 [229]  1447  1451  1453  1459  1471  1481  1483  1487  1489  1493  1499  1511
 [241]  1523  1531  1543  1549  1553  1559  1567  1571  1579  1583  1597  1601
 [253]  1607  1609  1613  1619  1621  1627  1637  1657  1663  1667  1669  1693
 [265]  1697  1699  1709  1721  1723  1733  1741  1747  1753  1759  1777  1783
 [277]  1787  1789  1801  1811  1823  1831  1847  1861  1867  1871  1873  1877
 [289]  1879  1889  1901  1907  1913  1931  1933  1949  1951  1973  1979  1987
 [301]  1993  1997  1999  2003  2011  2017  2027  2029  2039  2053  2063  2069
 [313]  2081  2083  2087  2089  2099  2111  2113  2129  2131  2137  2141  2143
 [325]  2153  2161  2179  2203  2207  2213  2221  2237  2239  2243  2251  2267
 [337]  2269  2273  2281  2287  2293  2297  2309  2311  2333  2339  2341  2347
 [349]  2351  2357  2371  2377  2381  2383  2389  2393  2399  2411  2417  2423
 [361]  2437  2441  2447  2459  2467  2473  2477  2503  2521  2531  2539  2543
 [373]  2549  2551  2557  2579  2591  2593  2609  2617  2621  2633  2647  2657
 [385]  2659  2663  2671  2677  2683  2687  2689  2693  2699  2707  2711  2713
 [397]  2719  2729  2731  2741  2749  2753  2767  2777  2789  2791  2797  2801
 [409]  2803  2819  2833  2837  2843  2851  2857  2861  2879  2887  2897  2903
 [421]  2909  2917  2927  2939  2953  2957  2963  2969  2971  2999  3001  3011
 [433]  3019  3023  3037  3041  3049  3061  3067  3079  3083  3089  3109  3119
 [445]  3121  3137  3163  3167  3169  3181  3187  3191  3203  3209  3217  3221
 [457]  3229  3251  3253  3257  3259  3271  3299  3301  3307  3313  3319  3323
 [469]  3329  3331  3343  3347  3359  3361  3371  3373  3389  3391  3407  3413
 [481]  3433  3449  3457  3461  3463  3467  3469  3491  3499  3511  3517  3527
 [493]  3529  3533  3539  3541  3547  3557  3559  3571  3581  3583  3593  3607
 [505]  3613  3617  3623  3631  3637  3643  3659  3671  3673  3677  3691  3697
 [517]  3701  3709  3719  3727  3733  3739  3761  3767  3769  3779  3793  3797
 [529]  3803  3821  3823  3833  3847  3851  3853  3863  3877  3881  3889  3907
 [541]  3911  3917  3919  3923  3929  3931  3943  3947  3967  3989  4001  4003
 [553]  4007  4013  4019  4021  4027  4049  4051  4057  4073  4079  4091  4093
 [565]  4099  4111  4127  4129  4133  4139  4153  4157  4159  4177  4201  4211
 [577]  4217  4219  4229  4231  4241  4243  4253  4259  4261  4271  4273  4283
 [589]  4289  4297  4327  4337  4339  4349  4357  4363  4373  4391  4397  4409
 [601]  4421  4423  4441  4447  4451  4457  4463  4481  4483  4493  4507  4513
 [613]  4517  4519  4523  4547  4549  4561  4567  4583  4591  4597  4603  4621
 [625]  4637  4639  4643  4649  4651  4657  4663  4673  4679  4691  4703  4721
 [637]  4723  4729  4733  4751  4759  4783  4787  4789  4793  4799  4801  4813
 [649]  4817  4831  4861  4871  4877  4889  4903  4909  4919  4931  4933  4937
 [661]  4943  4951  4957  4967  4969  4973  4987  4993  4999  5003  5009  5011
 [673]  5021  5023  5039  5051  5059  5077  5081  5087  5099  5101  5107  5113
 [685]  5119  5147  5153  5167  5171  5179  5189  5197  5209  5227  5231  5233
 [697]  5237  5261  5273  5279  5281  5297  5303  5309  5323  5333  5347  5351
 [709]  5381  5387  5393  5399  5407  5413  5417  5419  5431  5437  5441  5443
 [721]  5449  5471  5477  5479  5483  5501  5503  5507  5519  5521  5527  5531
 [733]  5557  5563  5569  5573  5581  5591  5623  5639  5641  5647  5651  5653
 [745]  5657  5659  5669  5683  5689  5693  5701  5711  5717  5737  5741  5743
 [757]  5749  5779  5783  5791  5801  5807  5813  5821  5827  5839  5843  5849
 [769]  5851  5857  5861  5867  5869  5879  5881  5897  5903  5923  5927  5939
 [781]  5953  5981  5987  6007  6011  6029  6037  6043  6047  6053  6067  6073
 [793]  6079  6089  6091  6101  6113  6121  6131  6133  6143  6151  6163  6173
 [805]  6197  6199  6203  6211  6217  6221  6229  6247  6257  6263  6269  6271
 [817]  6277  6287  6299  6301  6311  6317  6323  6329  6337  6343  6353  6359
 [829]  6361  6367  6373  6379  6389  6397  6421  6427  6449  6451  6469  6473
 [841]  6481  6491  6521  6529  6547  6551  6553  6563  6569  6571  6577  6581
 [853]  6599  6607  6619  6637  6653  6659  6661  6673  6679  6689  6691  6701
 [865]  6703  6709  6719  6733  6737  6761  6763  6779  6781  6791  6793  6803
 [877]  6823  6827  6829  6833  6841  6857  6863  6869  6871  6883  6899  6907
 [889]  6911  6917  6947  6949  6959  6961  6967  6971  6977  6983  6991  6997
 [901]  7001  7013  7019  7027  7039  7043  7057  7069  7079  7103  7109  7121
 [913]  7127  7129  7151  7159  7177  7187  7193  7207  7211  7213  7219  7229
 [925]  7237  7243  7247  7253  7283  7297  7307  7309  7321  7331  7333  7349
 [937]  7351  7369  7393  7411  7417  7433  7451  7457  7459  7477  7481  7487
 [949]  7489  7499  7507  7517  7523  7529  7537  7541  7547  7549  7559  7561
 [961]  7573  7577  7583  7589  7591  7603  7607  7621  7639  7643  7649  7669
 [973]  7673  7681  7687  7691  7699  7703  7717  7723  7727  7741  7753  7757
 [985]  7759  7789  7793  7817  7823  7829  7841  7853  7867  7873  7877  7879
 [997]  7883  7901  7907  7919  7927  7933  7937  7949  7951  7963  7993  8009
[1009]  8011  8017  8039  8053  8059  8069  8081  8087  8089  8093  8101  8111
[1021]  8117  8123  8147  8161  8167  8171  8179  8191  8209  8219  8221  8231
[1033]  8233  8237  8243  8263  8269  8273  8287  8291  8293  8297  8311  8317
[1045]  8329  8353  8363  8369  8377  8387  8389  8419  8423  8429  8431  8443
[1057]  8447  8461  8467  8501  8513  8521  8527  8537  8539  8543  8563  8573
[1069]  8581  8597  8599  8609  8623  8627  8629  8641  8647  8663  8669  8677
[1081]  8681  8689  8693  8699  8707  8713  8719  8731  8737  8741  8747  8753
[1093]  8761  8779  8783  8803  8807  8819  8821  8831  8837  8839  8849  8861
[1105]  8863  8867  8887  8893  8923  8929  8933  8941  8951  8963  8969  8971
[1117]  8999  9001  9007  9011  9013  9029  9041  9043  9049  9059  9067  9091
[1129]  9103  9109  9127  9133  9137  9151  9157  9161  9173  9181  9187  9199
[1141]  9203  9209  9221  9227  9239  9241  9257  9277  9281  9283  9293  9311
[1153]  9319  9323  9337  9341  9343  9349  9371  9377  9391  9397  9403  9413
[1165]  9419  9421  9431  9433  9437  9439  9461  9463  9467  9473  9479  9491
[1177]  9497  9511  9521  9533  9539  9547  9551  9587  9601  9613  9619  9623
[1189]  9629  9631  9643  9649  9661  9677  9679  9689  9697  9719  9721  9733
[1201]  9739  9743  9749  9767  9769  9781  9787  9791  9803  9811  9817  9829
[1213]  9833  9839  9851  9857  9859  9871  9883  9887  9901  9907  9923  9929
[1225]  9931  9941  9949  9967  9973 10007 10009 10037 10039 10061 10067 10069
[1237] 10079 10091 10093 10099 10103 10111 10133 10139 10141 10151 10159 10163
[1249] 10169 10177 10181 10193 10211 10223 10243 10247 10253 10259 10267 10271
[1261] 10273 10289 10301 10303 10313 10321 10331 10333 10337 10343 10357 10369
[1273] 10391 10399 10427 10429 10433 10453 10457 10459 10463 10477 10487 10499
[1285] 10501 10513 10529 10531 10559 10567 10589 10597 10601 10607 10613 10627
[1297] 10631 10639 10651 10657 10663 10667 10687 10691 10709 10711 10723 10729
[1309] 10733 10739 10753 10771 10781 10789 10799 10831 10837 10847 10853 10859
[1321] 10861 10867 10883 10889 10891 10903 10909 10937 10939 10949 10957 10973
[1333] 10979 10987 10993 11003 11027 11047 11057 11059 11069 11071 11083 11087
[1345] 11093 11113 11117 11119 11131 11149 11159 11161 11171 11173 11177 11197
[1357] 11213 11239 11243 11251 11257 11261 11273 11279 11287 11299 11311 11317
[1369] 11321 11329 11351 11353 11369 11383 11393 11399 11411 11423 11437 11443
[1381] 11447 11467 11471 11483 11489 11491 11497 11503 11519 11527 11549 11551
[1393] 11579 11587 11593 11597 11617 11621 11633 11657 11677 11681 11689 11699
[1405] 11701 11717 11719 11731 11743 11777 11779 11783 11789 11801 11807 11813
[1417] 11821 11827 11831 11833 11839 11863 11867 11887 11897 11903 11909 11923
[1429] 11927 11933 11939 11941 11953 11959 11969 11971 11981 11987 12007 12011
[1441] 12037 12041 12043 12049 12071 12073 12097 12101 12107 12109 12113 12119
[1453] 12143 12149 12157 12161 12163 12197 12203 12211 12227 12239 12241 12251
[1465] 12253 12263 12269 12277 12281 12289 12301 12323 12329 12343 12347 12373
[1477] 12377 12379 12391 12401 12409 12413 12421 12433 12437 12451 12457 12473
[1489] 12479 12487 12491 12497 12503 12511 12517 12527 12539 12541 12547 12553
[1501] 12569 12577 12583 12589 12601 12611 12613 12619 12637 12641 12647 12653
[1513] 12659 12671 12689 12697 12703 12713 12721 12739 12743 12757 12763 12781
[1525] 12791 12799 12809 12821 12823 12829 12841 12853 12889 12893 12899 12907
[1537] 12911 12917 12919 12923 12941 12953 12959 12967 12973 12979 12983 13001
[1549] 13003 13007 13009 13033 13037 13043 13049 13063 13093 13099 13103 13109
[1561] 13121 13127 13147 13151 13159 13163 13171 13177 13183 13187 13217 13219
[1573] 13229 13241 13249 13259 13267 13291 13297 13309 13313 13327 13331 13337
[1585] 13339 13367 13381 13397 13399 13411 13417 13421 13441 13451 13457 13463
[1597] 13469 13477 13487 13499 13513 13523 13537 13553 13567 13577 13591 13597
[1609] 13613 13619 13627 13633 13649 13669 13679 13681 13687 13691 13693 13697
[1621] 13709 13711 13721 13723 13729 13751 13757 13759 13763 13781 13789 13799
[1633] 13807 13829 13831 13841 13859 13873 13877 13879 13883 13901 13903 13907
[1645] 13913 13921 13931 13933 13963 13967 13997 13999 14009 14011 14029 14033
[1657] 14051 14057 14071 14081 14083 14087 14107 14143 14149 14153 14159 14173
[1669] 14177 14197 14207 14221 14243 14249 14251 14281 14293 14303 14321 14323
[1681] 14327 14341 14347 14369 14387 14389 14401 14407 14411 14419 14423 14431
[1693] 14437 14447 14449 14461 14479 14489 14503 14519 14533 14537 14543 14549
[1705] 14551 14557 14561 14563 14591 14593 14621 14627 14629 14633 14639 14653
[1717] 14657 14669 14683 14699 14713 14717 14723 14731 14737 14741 14747 14753
[1729] 14759 14767 14771 14779 14783 14797 14813 14821 14827 14831 14843 14851
[1741] 14867 14869 14879 14887 14891 14897 14923 14929 14939 14947 14951 14957
[1753] 14969 14983 15013 15017 15031 15053 15061 15073 15077 15083 15091 15101
[1765] 15107 15121 15131 15137 15139 15149 15161 15173 15187 15193 15199 15217
[1777] 15227 15233 15241 15259 15263 15269 15271 15277 15287 15289 15299 15307
[1789] 15313 15319 15329 15331 15349 15359 15361 15373 15377 15383 15391 15401
[1801] 15413 15427 15439 15443 15451 15461 15467 15473 15493 15497 15511 15527
[1813] 15541 15551 15559 15569 15581 15583 15601 15607 15619 15629 15641 15643
[1825] 15647 15649 15661 15667 15671 15679 15683 15727 15731 15733 15737 15739
[1837] 15749 15761 15767 15773 15787 15791 15797 15803 15809 15817 15823 15859
[1849] 15877 15881 15887 15889 15901 15907 15913 15919 15923 15937 15959 15971
[1861] 15973 15991 16001 16007 16033 16057 16061 16063 16067 16069 16073 16087
[1873] 16091 16097 16103 16111 16127 16139 16141 16183 16187 16189 16193 16217
[1885] 16223 16229 16231 16249 16253 16267 16273 16301 16319 16333 16339 16349
[1897] 16361 16363 16369 16381 16411 16417 16421 16427 16433 16447 16451 16453
[1909] 16477 16481 16487 16493 16519 16529 16547 16553 16561 16567 16573 16603
[1921] 16607 16619 16631 16633 16649 16651 16657 16661 16673 16691 16693 16699
[1933] 16703 16729 16741 16747 16759 16763 16787 16811 16823 16829 16831 16843
[1945] 16871 16879 16883 16889 16901 16903 16921 16927 16931 16937 16943 16963
[1957] 16979 16981 16987 16993 17011 17021 17027 17029 17033 17041 17047 17053
[1969] 17077 17093 17099 17107 17117 17123 17137 17159 17167 17183 17189 17191
[1981] 17203 17207 17209 17231 17239 17257 17291 17293 17299 17317 17321 17327
[1993] 17333 17341 17351 17359 17377 17383 17387 17389
rm(list=ls())
#############.
# ANSWER
#############.

firstNPrimes = function( numPrimes ){
 primes = numeric(0)
 numberToCheck = 2
 while ( length(primes) < numPrimes  ){
  
  isPrime = TRUE
  
  # Check if numberToCheck is prime. If it isn't prime set the variable
  # isPrime to FALSE.
  
  divisor = 2
  while(divisor < numberToCheck){
   if ( numberToCheck %% divisor == 0){
    isPrime = FALSE
   }
   
   divisor = divisor + 1
  }
  
  
  
  
  if (isPrime == TRUE){
   primes = c(primes, numberToCheck)
  }
  numberToCheck = numberToCheck + 1
 }
 primes
}

firstNPrimes(100)
  [1]   2   3   5   7  11  13  17  19  23  29  31  37  41  43  47  53  59  61
 [19]  67  71  73  79  83  89  97 101 103 107 109 113 127 131 137 139 149 151
 [37] 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251
 [55] 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359
 [73] 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463
 [91] 467 479 487 491 499 503 509 521 523 541
firstNPrimes(1000)
   [1]    2    3    5    7   11   13   17   19   23   29   31   37   41   43
  [15]   47   53   59   61   67   71   73   79   83   89   97  101  103  107
  [29]  109  113  127  131  137  139  149  151  157  163  167  173  179  181
  [43]  191  193  197  199  211  223  227  229  233  239  241  251  257  263
  [57]  269  271  277  281  283  293  307  311  313  317  331  337  347  349
  [71]  353  359  367  373  379  383  389  397  401  409  419  421  431  433
  [85]  439  443  449  457  461  463  467  479  487  491  499  503  509  521
  [99]  523  541  547  557  563  569  571  577  587  593  599  601  607  613
 [113]  617  619  631  641  643  647  653  659  661  673  677  683  691  701
 [127]  709  719  727  733  739  743  751  757  761  769  773  787  797  809
 [141]  811  821  823  827  829  839  853  857  859  863  877  881  883  887
 [155]  907  911  919  929  937  941  947  953  967  971  977  983  991  997
 [169] 1009 1013 1019 1021 1031 1033 1039 1049 1051 1061 1063 1069 1087 1091
 [183] 1093 1097 1103 1109 1117 1123 1129 1151 1153 1163 1171 1181 1187 1193
 [197] 1201 1213 1217 1223 1229 1231 1237 1249 1259 1277 1279 1283 1289 1291
 [211] 1297 1301 1303 1307 1319 1321 1327 1361 1367 1373 1381 1399 1409 1423
 [225] 1427 1429 1433 1439 1447 1451 1453 1459 1471 1481 1483 1487 1489 1493
 [239] 1499 1511 1523 1531 1543 1549 1553 1559 1567 1571 1579 1583 1597 1601
 [253] 1607 1609 1613 1619 1621 1627 1637 1657 1663 1667 1669 1693 1697 1699
 [267] 1709 1721 1723 1733 1741 1747 1753 1759 1777 1783 1787 1789 1801 1811
 [281] 1823 1831 1847 1861 1867 1871 1873 1877 1879 1889 1901 1907 1913 1931
 [295] 1933 1949 1951 1973 1979 1987 1993 1997 1999 2003 2011 2017 2027 2029
 [309] 2039 2053 2063 2069 2081 2083 2087 2089 2099 2111 2113 2129 2131 2137
 [323] 2141 2143 2153 2161 2179 2203 2207 2213 2221 2237 2239 2243 2251 2267
 [337] 2269 2273 2281 2287 2293 2297 2309 2311 2333 2339 2341 2347 2351 2357
 [351] 2371 2377 2381 2383 2389 2393 2399 2411 2417 2423 2437 2441 2447 2459
 [365] 2467 2473 2477 2503 2521 2531 2539 2543 2549 2551 2557 2579 2591 2593
 [379] 2609 2617 2621 2633 2647 2657 2659 2663 2671 2677 2683 2687 2689 2693
 [393] 2699 2707 2711 2713 2719 2729 2731 2741 2749 2753 2767 2777 2789 2791
 [407] 2797 2801 2803 2819 2833 2837 2843 2851 2857 2861 2879 2887 2897 2903
 [421] 2909 2917 2927 2939 2953 2957 2963 2969 2971 2999 3001 3011 3019 3023
 [435] 3037 3041 3049 3061 3067 3079 3083 3089 3109 3119 3121 3137 3163 3167
 [449] 3169 3181 3187 3191 3203 3209 3217 3221 3229 3251 3253 3257 3259 3271
 [463] 3299 3301 3307 3313 3319 3323 3329 3331 3343 3347 3359 3361 3371 3373
 [477] 3389 3391 3407 3413 3433 3449 3457 3461 3463 3467 3469 3491 3499 3511
 [491] 3517 3527 3529 3533 3539 3541 3547 3557 3559 3571 3581 3583 3593 3607
 [505] 3613 3617 3623 3631 3637 3643 3659 3671 3673 3677 3691 3697 3701 3709
 [519] 3719 3727 3733 3739 3761 3767 3769 3779 3793 3797 3803 3821 3823 3833
 [533] 3847 3851 3853 3863 3877 3881 3889 3907 3911 3917 3919 3923 3929 3931
 [547] 3943 3947 3967 3989 4001 4003 4007 4013 4019 4021 4027 4049 4051 4057
 [561] 4073 4079 4091 4093 4099 4111 4127 4129 4133 4139 4153 4157 4159 4177
 [575] 4201 4211 4217 4219 4229 4231 4241 4243 4253 4259 4261 4271 4273 4283
 [589] 4289 4297 4327 4337 4339 4349 4357 4363 4373 4391 4397 4409 4421 4423
 [603] 4441 4447 4451 4457 4463 4481 4483 4493 4507 4513 4517 4519 4523 4547
 [617] 4549 4561 4567 4583 4591 4597 4603 4621 4637 4639 4643 4649 4651 4657
 [631] 4663 4673 4679 4691 4703 4721 4723 4729 4733 4751 4759 4783 4787 4789
 [645] 4793 4799 4801 4813 4817 4831 4861 4871 4877 4889 4903 4909 4919 4931
 [659] 4933 4937 4943 4951 4957 4967 4969 4973 4987 4993 4999 5003 5009 5011
 [673] 5021 5023 5039 5051 5059 5077 5081 5087 5099 5101 5107 5113 5119 5147
 [687] 5153 5167 5171 5179 5189 5197 5209 5227 5231 5233 5237 5261 5273 5279
 [701] 5281 5297 5303 5309 5323 5333 5347 5351 5381 5387 5393 5399 5407 5413
 [715] 5417 5419 5431 5437 5441 5443 5449 5471 5477 5479 5483 5501 5503 5507
 [729] 5519 5521 5527 5531 5557 5563 5569 5573 5581 5591 5623 5639 5641 5647
 [743] 5651 5653 5657 5659 5669 5683 5689 5693 5701 5711 5717 5737 5741 5743
 [757] 5749 5779 5783 5791 5801 5807 5813 5821 5827 5839 5843 5849 5851 5857
 [771] 5861 5867 5869 5879 5881 5897 5903 5923 5927 5939 5953 5981 5987 6007
 [785] 6011 6029 6037 6043 6047 6053 6067 6073 6079 6089 6091 6101 6113 6121
 [799] 6131 6133 6143 6151 6163 6173 6197 6199 6203 6211 6217 6221 6229 6247
 [813] 6257 6263 6269 6271 6277 6287 6299 6301 6311 6317 6323 6329 6337 6343
 [827] 6353 6359 6361 6367 6373 6379 6389 6397 6421 6427 6449 6451 6469 6473
 [841] 6481 6491 6521 6529 6547 6551 6553 6563 6569 6571 6577 6581 6599 6607
 [855] 6619 6637 6653 6659 6661 6673 6679 6689 6691 6701 6703 6709 6719 6733
 [869] 6737 6761 6763 6779 6781 6791 6793 6803 6823 6827 6829 6833 6841 6857
 [883] 6863 6869 6871 6883 6899 6907 6911 6917 6947 6949 6959 6961 6967 6971
 [897] 6977 6983 6991 6997 7001 7013 7019 7027 7039 7043 7057 7069 7079 7103
 [911] 7109 7121 7127 7129 7151 7159 7177 7187 7193 7207 7211 7213 7219 7229
 [925] 7237 7243 7247 7253 7283 7297 7307 7309 7321 7331 7333 7349 7351 7369
 [939] 7393 7411 7417 7433 7451 7457 7459 7477 7481 7487 7489 7499 7507 7517
 [953] 7523 7529 7537 7541 7547 7549 7559 7561 7573 7577 7583 7589 7591 7603
 [967] 7607 7621 7639 7643 7649 7669 7673 7681 7687 7691 7699 7703 7717 7723
 [981] 7727 7741 7753 7757 7759 7789 7793 7817 7823 7829 7841 7853 7867 7873
 [995] 7877 7879 7883 7901 7907 7919
firstNPrimes(2000)
   [1]     2     3     5     7    11    13    17    19    23    29    31    37
  [13]    41    43    47    53    59    61    67    71    73    79    83    89
  [25]    97   101   103   107   109   113   127   131   137   139   149   151
  [37]   157   163   167   173   179   181   191   193   197   199   211   223
  [49]   227   229   233   239   241   251   257   263   269   271   277   281
  [61]   283   293   307   311   313   317   331   337   347   349   353   359
  [73]   367   373   379   383   389   397   401   409   419   421   431   433
  [85]   439   443   449   457   461   463   467   479   487   491   499   503
  [97]   509   521   523   541   547   557   563   569   571   577   587   593
 [109]   599   601   607   613   617   619   631   641   643   647   653   659
 [121]   661   673   677   683   691   701   709   719   727   733   739   743
 [133]   751   757   761   769   773   787   797   809   811   821   823   827
 [145]   829   839   853   857   859   863   877   881   883   887   907   911
 [157]   919   929   937   941   947   953   967   971   977   983   991   997
 [169]  1009  1013  1019  1021  1031  1033  1039  1049  1051  1061  1063  1069
 [181]  1087  1091  1093  1097  1103  1109  1117  1123  1129  1151  1153  1163
 [193]  1171  1181  1187  1193  1201  1213  1217  1223  1229  1231  1237  1249
 [205]  1259  1277  1279  1283  1289  1291  1297  1301  1303  1307  1319  1321
 [217]  1327  1361  1367  1373  1381  1399  1409  1423  1427  1429  1433  1439
 [229]  1447  1451  1453  1459  1471  1481  1483  1487  1489  1493  1499  1511
 [241]  1523  1531  1543  1549  1553  1559  1567  1571  1579  1583  1597  1601
 [253]  1607  1609  1613  1619  1621  1627  1637  1657  1663  1667  1669  1693
 [265]  1697  1699  1709  1721  1723  1733  1741  1747  1753  1759  1777  1783
 [277]  1787  1789  1801  1811  1823  1831  1847  1861  1867  1871  1873  1877
 [289]  1879  1889  1901  1907  1913  1931  1933  1949  1951  1973  1979  1987
 [301]  1993  1997  1999  2003  2011  2017  2027  2029  2039  2053  2063  2069
 [313]  2081  2083  2087  2089  2099  2111  2113  2129  2131  2137  2141  2143
 [325]  2153  2161  2179  2203  2207  2213  2221  2237  2239  2243  2251  2267
 [337]  2269  2273  2281  2287  2293  2297  2309  2311  2333  2339  2341  2347
 [349]  2351  2357  2371  2377  2381  2383  2389  2393  2399  2411  2417  2423
 [361]  2437  2441  2447  2459  2467  2473  2477  2503  2521  2531  2539  2543
 [373]  2549  2551  2557  2579  2591  2593  2609  2617  2621  2633  2647  2657
 [385]  2659  2663  2671  2677  2683  2687  2689  2693  2699  2707  2711  2713
 [397]  2719  2729  2731  2741  2749  2753  2767  2777  2789  2791  2797  2801
 [409]  2803  2819  2833  2837  2843  2851  2857  2861  2879  2887  2897  2903
 [421]  2909  2917  2927  2939  2953  2957  2963  2969  2971  2999  3001  3011
 [433]  3019  3023  3037  3041  3049  3061  3067  3079  3083  3089  3109  3119
 [445]  3121  3137  3163  3167  3169  3181  3187  3191  3203  3209  3217  3221
 [457]  3229  3251  3253  3257  3259  3271  3299  3301  3307  3313  3319  3323
 [469]  3329  3331  3343  3347  3359  3361  3371  3373  3389  3391  3407  3413
 [481]  3433  3449  3457  3461  3463  3467  3469  3491  3499  3511  3517  3527
 [493]  3529  3533  3539  3541  3547  3557  3559  3571  3581  3583  3593  3607
 [505]  3613  3617  3623  3631  3637  3643  3659  3671  3673  3677  3691  3697
 [517]  3701  3709  3719  3727  3733  3739  3761  3767  3769  3779  3793  3797
 [529]  3803  3821  3823  3833  3847  3851  3853  3863  3877  3881  3889  3907
 [541]  3911  3917  3919  3923  3929  3931  3943  3947  3967  3989  4001  4003
 [553]  4007  4013  4019  4021  4027  4049  4051  4057  4073  4079  4091  4093
 [565]  4099  4111  4127  4129  4133  4139  4153  4157  4159  4177  4201  4211
 [577]  4217  4219  4229  4231  4241  4243  4253  4259  4261  4271  4273  4283
 [589]  4289  4297  4327  4337  4339  4349  4357  4363  4373  4391  4397  4409
 [601]  4421  4423  4441  4447  4451  4457  4463  4481  4483  4493  4507  4513
 [613]  4517  4519  4523  4547  4549  4561  4567  4583  4591  4597  4603  4621
 [625]  4637  4639  4643  4649  4651  4657  4663  4673  4679  4691  4703  4721
 [637]  4723  4729  4733  4751  4759  4783  4787  4789  4793  4799  4801  4813
 [649]  4817  4831  4861  4871  4877  4889  4903  4909  4919  4931  4933  4937
 [661]  4943  4951  4957  4967  4969  4973  4987  4993  4999  5003  5009  5011
 [673]  5021  5023  5039  5051  5059  5077  5081  5087  5099  5101  5107  5113
 [685]  5119  5147  5153  5167  5171  5179  5189  5197  5209  5227  5231  5233
 [697]  5237  5261  5273  5279  5281  5297  5303  5309  5323  5333  5347  5351
 [709]  5381  5387  5393  5399  5407  5413  5417  5419  5431  5437  5441  5443
 [721]  5449  5471  5477  5479  5483  5501  5503  5507  5519  5521  5527  5531
 [733]  5557  5563  5569  5573  5581  5591  5623  5639  5641  5647  5651  5653
 [745]  5657  5659  5669  5683  5689  5693  5701  5711  5717  5737  5741  5743
 [757]  5749  5779  5783  5791  5801  5807  5813  5821  5827  5839  5843  5849
 [769]  5851  5857  5861  5867  5869  5879  5881  5897  5903  5923  5927  5939
 [781]  5953  5981  5987  6007  6011  6029  6037  6043  6047  6053  6067  6073
 [793]  6079  6089  6091  6101  6113  6121  6131  6133  6143  6151  6163  6173
 [805]  6197  6199  6203  6211  6217  6221  6229  6247  6257  6263  6269  6271
 [817]  6277  6287  6299  6301  6311  6317  6323  6329  6337  6343  6353  6359
 [829]  6361  6367  6373  6379  6389  6397  6421  6427  6449  6451  6469  6473
 [841]  6481  6491  6521  6529  6547  6551  6553  6563  6569  6571  6577  6581
 [853]  6599  6607  6619  6637  6653  6659  6661  6673  6679  6689  6691  6701
 [865]  6703  6709  6719  6733  6737  6761  6763  6779  6781  6791  6793  6803
 [877]  6823  6827  6829  6833  6841  6857  6863  6869  6871  6883  6899  6907
 [889]  6911  6917  6947  6949  6959  6961  6967  6971  6977  6983  6991  6997
 [901]  7001  7013  7019  7027  7039  7043  7057  7069  7079  7103  7109  7121
 [913]  7127  7129  7151  7159  7177  7187  7193  7207  7211  7213  7219  7229
 [925]  7237  7243  7247  7253  7283  7297  7307  7309  7321  7331  7333  7349
 [937]  7351  7369  7393  7411  7417  7433  7451  7457  7459  7477  7481  7487
 [949]  7489  7499  7507  7517  7523  7529  7537  7541  7547  7549  7559  7561
 [961]  7573  7577  7583  7589  7591  7603  7607  7621  7639  7643  7649  7669
 [973]  7673  7681  7687  7691  7699  7703  7717  7723  7727  7741  7753  7757
 [985]  7759  7789  7793  7817  7823  7829  7841  7853  7867  7873  7877  7879
 [997]  7883  7901  7907  7919  7927  7933  7937  7949  7951  7963  7993  8009
[1009]  8011  8017  8039  8053  8059  8069  8081  8087  8089  8093  8101  8111
[1021]  8117  8123  8147  8161  8167  8171  8179  8191  8209  8219  8221  8231
[1033]  8233  8237  8243  8263  8269  8273  8287  8291  8293  8297  8311  8317
[1045]  8329  8353  8363  8369  8377  8387  8389  8419  8423  8429  8431  8443
[1057]  8447  8461  8467  8501  8513  8521  8527  8537  8539  8543  8563  8573
[1069]  8581  8597  8599  8609  8623  8627  8629  8641  8647  8663  8669  8677
[1081]  8681  8689  8693  8699  8707  8713  8719  8731  8737  8741  8747  8753
[1093]  8761  8779  8783  8803  8807  8819  8821  8831  8837  8839  8849  8861
[1105]  8863  8867  8887  8893  8923  8929  8933  8941  8951  8963  8969  8971
[1117]  8999  9001  9007  9011  9013  9029  9041  9043  9049  9059  9067  9091
[1129]  9103  9109  9127  9133  9137  9151  9157  9161  9173  9181  9187  9199
[1141]  9203  9209  9221  9227  9239  9241  9257  9277  9281  9283  9293  9311
[1153]  9319  9323  9337  9341  9343  9349  9371  9377  9391  9397  9403  9413
[1165]  9419  9421  9431  9433  9437  9439  9461  9463  9467  9473  9479  9491
[1177]  9497  9511  9521  9533  9539  9547  9551  9587  9601  9613  9619  9623
[1189]  9629  9631  9643  9649  9661  9677  9679  9689  9697  9719  9721  9733
[1201]  9739  9743  9749  9767  9769  9781  9787  9791  9803  9811  9817  9829
[1213]  9833  9839  9851  9857  9859  9871  9883  9887  9901  9907  9923  9929
[1225]  9931  9941  9949  9967  9973 10007 10009 10037 10039 10061 10067 10069
[1237] 10079 10091 10093 10099 10103 10111 10133 10139 10141 10151 10159 10163
[1249] 10169 10177 10181 10193 10211 10223 10243 10247 10253 10259 10267 10271
[1261] 10273 10289 10301 10303 10313 10321 10331 10333 10337 10343 10357 10369
[1273] 10391 10399 10427 10429 10433 10453 10457 10459 10463 10477 10487 10499
[1285] 10501 10513 10529 10531 10559 10567 10589 10597 10601 10607 10613 10627
[1297] 10631 10639 10651 10657 10663 10667 10687 10691 10709 10711 10723 10729
[1309] 10733 10739 10753 10771 10781 10789 10799 10831 10837 10847 10853 10859
[1321] 10861 10867 10883 10889 10891 10903 10909 10937 10939 10949 10957 10973
[1333] 10979 10987 10993 11003 11027 11047 11057 11059 11069 11071 11083 11087
[1345] 11093 11113 11117 11119 11131 11149 11159 11161 11171 11173 11177 11197
[1357] 11213 11239 11243 11251 11257 11261 11273 11279 11287 11299 11311 11317
[1369] 11321 11329 11351 11353 11369 11383 11393 11399 11411 11423 11437 11443
[1381] 11447 11467 11471 11483 11489 11491 11497 11503 11519 11527 11549 11551
[1393] 11579 11587 11593 11597 11617 11621 11633 11657 11677 11681 11689 11699
[1405] 11701 11717 11719 11731 11743 11777 11779 11783 11789 11801 11807 11813
[1417] 11821 11827 11831 11833 11839 11863 11867 11887 11897 11903 11909 11923
[1429] 11927 11933 11939 11941 11953 11959 11969 11971 11981 11987 12007 12011
[1441] 12037 12041 12043 12049 12071 12073 12097 12101 12107 12109 12113 12119
[1453] 12143 12149 12157 12161 12163 12197 12203 12211 12227 12239 12241 12251
[1465] 12253 12263 12269 12277 12281 12289 12301 12323 12329 12343 12347 12373
[1477] 12377 12379 12391 12401 12409 12413 12421 12433 12437 12451 12457 12473
[1489] 12479 12487 12491 12497 12503 12511 12517 12527 12539 12541 12547 12553
[1501] 12569 12577 12583 12589 12601 12611 12613 12619 12637 12641 12647 12653
[1513] 12659 12671 12689 12697 12703 12713 12721 12739 12743 12757 12763 12781
[1525] 12791 12799 12809 12821 12823 12829 12841 12853 12889 12893 12899 12907
[1537] 12911 12917 12919 12923 12941 12953 12959 12967 12973 12979 12983 13001
[1549] 13003 13007 13009 13033 13037 13043 13049 13063 13093 13099 13103 13109
[1561] 13121 13127 13147 13151 13159 13163 13171 13177 13183 13187 13217 13219
[1573] 13229 13241 13249 13259 13267 13291 13297 13309 13313 13327 13331 13337
[1585] 13339 13367 13381 13397 13399 13411 13417 13421 13441 13451 13457 13463
[1597] 13469 13477 13487 13499 13513 13523 13537 13553 13567 13577 13591 13597
[1609] 13613 13619 13627 13633 13649 13669 13679 13681 13687 13691 13693 13697
[1621] 13709 13711 13721 13723 13729 13751 13757 13759 13763 13781 13789 13799
[1633] 13807 13829 13831 13841 13859 13873 13877 13879 13883 13901 13903 13907
[1645] 13913 13921 13931 13933 13963 13967 13997 13999 14009 14011 14029 14033
[1657] 14051 14057 14071 14081 14083 14087 14107 14143 14149 14153 14159 14173
[1669] 14177 14197 14207 14221 14243 14249 14251 14281 14293 14303 14321 14323
[1681] 14327 14341 14347 14369 14387 14389 14401 14407 14411 14419 14423 14431
[1693] 14437 14447 14449 14461 14479 14489 14503 14519 14533 14537 14543 14549
[1705] 14551 14557 14561 14563 14591 14593 14621 14627 14629 14633 14639 14653
[1717] 14657 14669 14683 14699 14713 14717 14723 14731 14737 14741 14747 14753
[1729] 14759 14767 14771 14779 14783 14797 14813 14821 14827 14831 14843 14851
[1741] 14867 14869 14879 14887 14891 14897 14923 14929 14939 14947 14951 14957
[1753] 14969 14983 15013 15017 15031 15053 15061 15073 15077 15083 15091 15101
[1765] 15107 15121 15131 15137 15139 15149 15161 15173 15187 15193 15199 15217
[1777] 15227 15233 15241 15259 15263 15269 15271 15277 15287 15289 15299 15307
[1789] 15313 15319 15329 15331 15349 15359 15361 15373 15377 15383 15391 15401
[1801] 15413 15427 15439 15443 15451 15461 15467 15473 15493 15497 15511 15527
[1813] 15541 15551 15559 15569 15581 15583 15601 15607 15619 15629 15641 15643
[1825] 15647 15649 15661 15667 15671 15679 15683 15727 15731 15733 15737 15739
[1837] 15749 15761 15767 15773 15787 15791 15797 15803 15809 15817 15823 15859
[1849] 15877 15881 15887 15889 15901 15907 15913 15919 15923 15937 15959 15971
[1861] 15973 15991 16001 16007 16033 16057 16061 16063 16067 16069 16073 16087
[1873] 16091 16097 16103 16111 16127 16139 16141 16183 16187 16189 16193 16217
[1885] 16223 16229 16231 16249 16253 16267 16273 16301 16319 16333 16339 16349
[1897] 16361 16363 16369 16381 16411 16417 16421 16427 16433 16447 16451 16453
[1909] 16477 16481 16487 16493 16519 16529 16547 16553 16561 16567 16573 16603
[1921] 16607 16619 16631 16633 16649 16651 16657 16661 16673 16691 16693 16699
[1933] 16703 16729 16741 16747 16759 16763 16787 16811 16823 16829 16831 16843
[1945] 16871 16879 16883 16889 16901 16903 16921 16927 16931 16937 16943 16963
[1957] 16979 16981 16987 16993 17011 17021 17027 17029 17033 17041 17047 17053
[1969] 17077 17093 17099 17107 17117 17123 17137 17159 17167 17183 17189 17191
[1981] 17203 17207 17209 17231 17239 17257 17291 17293 17299 17317 17321 17327
[1993] 17333 17341 17351 17359 17377 17383 17387 17389
QUESTION: Rewrite your own version of the t function
#---------------------------------------------------------------------------
# The t function takes a matrix and returns a copy of the matrix with the
# rows and columns swapped, i.e. mat[i,j] becomes returnValue[j,i].
# See the example below.
#---------------------------------------------------------------------------
mat = matrix(seq(10,180,10), nrow=3, ncol=6)
mat     # 3 rows, 4 columns
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   10   40   70  100  130  160
[2,]   20   50   80  110  140  170
[3,]   30   60   90  120  150  180
t(mat)  # 4 rows, 3 columns (the rows became cols and the cols became rows)
     [,1] [,2] [,3]
[1,]   10   20   30
[2,]   40   50   60
[3,]   70   80   90
[4,]  100  110  120
[5,]  130  140  150
[6,]  160  170  180
#---------------------------------------------------------------------------
# QUESTION
#
# Write the function myt that does the same thing as the t function.
# Do NOT call the t function in your code.
# HINT - use a nested loop
#---------------------------------------------------------------------------
#############.
# ANSWER
#############.
myt = function( m ){
 
 # make the answer the right number of rows and columns
 answer = matrix( 0 ,  nrow=ncol(m) , ncol=nrow(m) )
 
 row = 1
 while(row <= nrow(m)) {
  
  col = 1
  while(col <= ncol(m)) {
   
   # assign the value at row,col in m to the correct place in the answer
   answer[col,row] = m[row,col]
   col = col + 1
  }
  
  row = row + 1
 }
 
 answer
}

mat
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   10   40   70  100  130  160
[2,]   20   50   80  110  140  170
[3,]   30   60   90  120  150  180
#debugonce(myt)
myt(mat)
     [,1] [,2] [,3]
[1,]   10   20   30
[2,]   40   50   60
[3,]   70   80   90
[4,]  100  110  120
[5,]  130  140  150
[6,]  160  170  180
#############.
# ANSWER
#############.

myt=function( m ){
 returnValue = matrix(1 ,nrow=ncol(m) ,ncol=nrow(m))
 
 row = 1
 while(row <= nrow(m)) {
  
  col = 1
  while(col <= ncol(m)) {
   
   returnValue[ col , row ]   =   m[ row ,  col ]     
   col = col + 1
  }
  
  row = row + 1
 }
 returnValue
}

mat = matrix(seq(10,120,10), nrow=3, ncol=4)
mat
     [,1] [,2] [,3] [,4]
[1,]   10   40   70  100
[2,]   20   50   80  110
[3,]   30   60   90  120
myt(mat)
     [,1] [,2] [,3]
[1,]   10   20   30
[2,]   40   50   60
[3,]   70   80   90
[4,]  100  110  120
#---------------------------------------------------------------------------
# QUESTION
#
# Rewrite the function myt to use a single loop (not a nested loop).
#
# HINTS
#
# - Use a single loop. 
#
#   The loop should keep updating a variable, eg. inRow, that contains
#   the number of a row from the input matrix. For example 
#
#     If the input matrix has 3 rows then the loop should go around 3 times. 
#     The 1st time through the loop, the variable inRowNumber, should contain 1,
#     The 2nd time through the loop, the variable inRowNumber, should contain 2,
#     The 3rd time through the loop, the variable inRowNumber, should contain 3
#
# - Inside the loop use matrix notation to assign the values from
#   a row in the input matrix to the corresponding column
#   in the output matrix
#
#---------------------------------------------------------------------------

#############.
# ANSWER
#############.

myt=function( m ){
 returnValue = matrix(1 ,nrow=ncol(m) ,ncol=nrow(m))
 
 inRow = 1
 while(inRow <= nrow(m)) {
  
  returnValue[ , inRow] = m[inRow , ]
  inRow = inRow + 1
  
 }
 returnValue
}

mat = matrix(seq(10,180,10), nrow=3, ncol=6)
mat
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   10   40   70  100  130  160
[2,]   20   50   80  110  140  170
[3,]   30   60   90  120  150  180
myt(mat)
     [,1] [,2] [,3]
[1,]   10   20   30
[2,]   40   50   60
[3,]   70   80   90
[4,]  100  110  120
[5,]  130  140  150
[6,]  160  170  180

35.26 More practice - drawing shapes with numbers

#####################################################################.
# SOME "TOY" FUNCTIONS
#
# Below are a few "toy" examples of using nested loops. Exercises
# like these help you to become more familiar with the concepts 
# of nested loops. This is similar to playing "scales" when learning 
# to play the piano - no one will play scales in real life - but
# it is important to get the hang of things when you're first
# starting out.
#####################################################################.


#---------------------------------------------------------------------
# The following are some simple functions that do NOT use nested loops.
# These are provided for comparison with the equivalent versions that use
# nested loops which we will show you below.
#---------------------------------------------------------------------

rm(list=ls())   # start over

# draw a line of x's of the specified width
# Do not use the rep function. Use the cat function and a loop.
drawLine_WithXs = function( width ) {
  
  while(width > 0){
    cat("x")
    width = width - 1
  }
}

drawLine_WithXs(4)  # xxxx
xxxx
drawLine_WithXs(5)  # xxxxx
xxxxx
# draw a box of x's
drawBox_WithXs = function(h, w){
  while(h > 0){
    drawLine_WithXs(w)
    cat("\n")
    h = h - 1
  }
}

drawBox_WithXs(3,4)  # box of 3 rows and 4 columns of x's
xxxx
xxxx
xxxx
# Draw a horizontal line with calls to cat that displays the numbers as shown below
drawLine_WithNums = function(width){
  num1 = 1
  while(num1 <= width){
    cat(num1)
    num1 = num1 + 1
  }  
}

drawLine_WithNums(4)  # 1234
1234
drawLine_WithNums(5)  # 12345
12345
#-----------------------------------------------------------------------
# drawBox using nested loops
#-----------------------------------------------------------------------

# QUESTION:
# Write a function 
#   drawBox1 = function(height, width)
#
# height and width are expected to be whole numbers between 1 and 9.
# The function should draw a box that has dimensions height rows and width columns.
# The box should be drawn with numbers such that each number represent the 
# number of the column it is in. For example:
#
#       > drawBox1(3, 5)
#       12345
#       12345
#       12345

drawBox1 = function(height, width){

  rowNumber = 1
  while(rowNumber <= height){
    
      colNumber = 1
      while(colNumber <= width){
        cat(colNumber)
        colNumber = colNumber + 1
      }  
      
      cat("\n")

      rowNumber = rowNumber + 1      
  }
  
}

#debugonce(drawBox1)
drawBox1(3, 4)
1234
1234
1234
# 1234
# 1234
# 1234

drawBox1(4,9)
123456789
123456789
123456789
123456789
#-----------------------------------------------------------------------------


# QUESTION:
# Write a function 
#   drawBox2 = function(height, width)
#
# height and width are expected to be whole numbers between 1 and 9.
# The function should draw a box that has dimensions height rows and width columns.
# The box should be drawn with numbers such that each number represent the 
# number of the row it is in. For example:
#
#       > drawBox1(3, 5)
#       11111
#       22222
#       33333

drawBox2 = function(height, width){
  
  rowNumber = 1
  while(rowNumber <= height){
    
    colNumber = 1
    while(colNumber <= width){
      cat(rowNumber)
      colNumber = colNumber + 1
    }  
    
    cat("\n")
    
    rowNumber = rowNumber + 1      
  }
  
}

drawBox2(3,4)
1111
2222
3333
# 1111
# 2222
# 3333

#-----------------------------------------------------------------------------
# Write the function drawBox3 to produce the results according to the pattern
# demonstrated in the following example:
#
# EXAMPLE: 
#   > drawBox3(3,4)
#   3333
#   2222
#   1111
#-----------------------------------------------------------------------------


drawBox3 = function(height, width){
  
  rowNumber = height
  while(rowNumber > 0){
    
    colNumber = 1
    while(colNumber <= width){
      cat(rowNumber)
      colNumber = colNumber + 1
    }  
    
    cat("\n")
    
    rowNumber = rowNumber - 1      
  }
  
}

drawBox3(3,4)
3333
2222
1111
# 3333
# 2222
# 1111



#-----------------------------------------------------------------------------
# Write the function drawBox4 to produce the results according to the pattern
# demonstrated in the following example:
#
# EXAMPLE: 
#   > drawBox3(3,4)
#   1234
#   1234
#   1234
#-----------------------------------------------------------------------------

drawBox4 = function(height, width){
  rowNumber = 1
  while (rowNumber <= height){
    
    colNumber = 1
    while(colNumber <= width) {
      cat( colNumber )
      colNumber = colNumber + 1
    }

    cat("\n")    
    rowNumber = rowNumber+1

  }
}

drawBox4(3,4)
1234
1234
1234
# 1234
# 1234
# 1234





#-----------------------------------------------------------------------------
# Write the function drawBox4 to produce the results according to the pattern
# demonstrated in the following example:
#
# EXAMPLE: 
#   > drawBox5(3,4)
#   4321
#   4321
#   4321
#-----------------------------------------------------------------------------

#############.
# ANSWER
#############.
drawBox5 = function(height, width){
 
  row = 1
  while(row <= height){
    
    col = width
    while( col >= 1){
      cat(col)
      
      col = col - 1      
    }
    
    cat("\n")
    row = row + 1 
  }
}


drawBox5(3,4)
4321
4321
4321
# 4321
# 4321
# 4321


#-----------------------------------------------------------------------------
# Write the function drawTriangle1 to produce the results according to the pattern
# demonstrated in the following example:
#
# EXAMPLE: 
#    > drawTriangle1(3)
#    1
#    12
#    123
#
#    > drawTriangle(5)
#    1
#    12
#    123
#    1234
#    12345
#-----------------------------------------------------------------------------

#############.
# ANSWER
#############.
drawTriangle1 = function(size){

  row = 1
  while(row <= size){
    
    col = 1
    while(col <= row){
      cat(col)
      col = col + 1      
    }
    cat("\n")
    row = row + 1    
  }
  
}

drawTriangle1(3)
1
12
123
drawTriangle1(9)
1
12
123
1234
12345
123456
1234567
12345678
123456789
# 1
# 12
# 123

#-----------------------------------------------------------------------------
# Write the function drawTriangle1 to produce the results according to the pattern
# demonstrated in the following example:
#
# EXAMPLE: 
#    > drawTriangle2(3)
#    111
#    22
#    3
#-----------------------------------------------------------------------------

#############.
# ANSWER
#############.
drawTriangle2 = function(size){

  outer = 1
  while( outer <= size ){
    
    inner = 1
    while( inner <= size - outer + 1){
      
      cat ( outer )
      
      inner = inner + 1
    }
    
    cat("\n")
    outer = outer + 1
  }
  
  
}

drawTriangle2(3)
111
22
3
# 111
# 22
# 3

drawTriangle2(5)
11111
2222
333
44
5

35.27 Other ways to do something over and over …

In R there are a few ways to do something over and over again … Often it is possible to recreate the same effect as a while loop by using one of these other approaches.

  1. Vector arithmetic automaticlly performs the same operation over and over to each item in the vector. For example:
# the folloiwng adds 1 to each number
nums = c(10,20,30)
nums + 1
[1] 11 21 31
  1. R has many “vectorized functions” that do something over and over. For exmaple, the prod function takes the product of all the values in a vector. This can be used to very quickly calculate the factorial of a number without actually using the factorial (or myFactorial) function.
prod(1:5)   # product of the values in the vector, i.e. 120 - same as myFactorial(5)
[1] 120
  1. The apply family of R functions, e.g. lapply and sapply (we’ll cover this later) perform a function for each value in a vector (or a list). See example below.

  2. R has other types of loops - e.g. for loop (covered in another chapter) and repeat loop (not covered in this book)

© 2025 Y. Rosenthal. All rights reserved.