function() {
  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  #                   Intro to the Tidyverse by Colleen O'Briant
  #                               Koan #19: reduce()
  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # In order to progress:
  # 1. Read all instructions carefully.
  # 2. When you come to an exercise, fill in the blank, un-comment the line
  #    (Ctrl/Cmd Shift C), and execute the code in the console (Ctrl/Cmd Return).
  #    If the piece of code spans multiple lines, highlight the whole chunk or
  #    simply put your cursor at the end of the last line.
  # 3. Save (Ctrl/Cmd S).
  # 4. Test that your answers are correct (Ctrl/Cmd Shift T).

  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # We've already learned the first function from the purrr family: map(). Now
  # we'll learn the next two: in this koan, we'll focus on reduce(), and in koan
  # 20, we'll learn accumulate().

  # map(.x, .f) applies a function `.f` to every element of `.x` and creates a
  # list of outputs the same length as `.x`.

  # Similarly, reduce(.x, .f) applies a 2-argument function `.f` to every
  # element of `.x` *sequentially* to get you *one* final output. That is, it
  # uses `.f` to reduce `.x`.

  # In this koan, we'll see how max() reduces a vector down to a single output,
  # and also that min() and sum() do the same thing.

  library(tidyverse)

  # The first example of how reduce() can be used is the function max(). max()
  # takes a vector of numbers and returns the number which is the largest.

  # 1. Fill in the blank below so that the statement returns TRUE: -------------

  #1@

  # max(c(5, 3, __, 2)) == 9

  #@1

  # What if you had to write the function `max` from scratch? You would probably
  # need to use `>`, keeping track of the maximum you've seen so far. So an
  # algorithm to sequentially apply `>` to find the maximum of c(4, 2, 6, 8)
  # would be this:

  # Compare the first two numbers in `.x`:
  4 > 2
  # Since this returns TRUE, save 4 as the largest number seen thus far.

  # Compare 4 with the next number in `.x`:
  4 > 6
  # Since this returns FALSE, save 6 as the largest number seen thus far.

  # Compare 6 with the next number in `.x`:
  6 > 8
  # Since this returns FALSE, save 8 as the largest number seen thus far.
  # Return 8 since we've made it through `.x`.

  # I'll write a 2-argument function that takes two numbers, compares them, and
  # returns the larger one. I'll call this function "larger", and I'll use
  # if_else() to do it:

  ?qelp::if_else

  larger <- function(x, y) {
    if_else(x > y, x, y)
  }

  # 2. Test that the function works by filling in the blank below with any -----
  # number to make the statement return TRUE:

  #2@

  # larger(5, __) == 5

  #@2

  # `larger` is a good start, but I want `max` to work on a vector of any size,
  # not just 2. Something I could do is to apply `larger` until `.x` is through,
  # sequentially:

  larger(4, 2) %>%
    larger(6) %>%
    larger(8)

  # Using `reduce()` does the same thing as what I've written above to
  # sequentially apply `.f` until `.x` is through:

  reduce(c(4, 2, 6, 8), larger)

  # So I can write a function my_max() that takes any vector of any length and
  # finds what the maximum is by sequentially applying `larger`:

  my_max <- function(x) {
    reduce(x, larger)
  }

  # Check that the function works:

  my_max(c(4, 2, 6, 8))

  # Instead of creating the functions `larger` and `my_max`, if you just wanted
  # to find the maximum of a vector using reduce(), you can use the formula
  # syntax just like with map(). Since .f is a 2-argument function for reduce(),
  # you'll refer to `.x` AND `.y`. .x is the value passed from previous
  # evaluations of .f, and .y refers to the new element of the vector.

  reduce(c(4, 2, 6, 8), ~ if_else(.x > .y, .x, .y))

  # This is a great visualization of what `reduce()` does from Hadley Wickham's
  # book *Advanced R*:
  #' https://d33wubrfki0l68.cloudfront.net/9c239e1227c69b7a2c9c2df234c21f3e1c74dd57/eec0e/diagrams/functionals/reduce.png

  # Also read the qelp docs for reduce:
  ?qelp::reduce

  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # 3. Your turn: create a function my_min() that finds the minimum of a -------
  # vector of numbers, using `<`, if_else(), and reduce().

  #3@

  # my_min <- function(x) {
  #   __
  # }

  #@3

  # Check that my_min works:

  # my_min(c(4, 2, 6, 8))

  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # So we've learned that you can think of max() as a reduced `>` and min() as a
  # reduced `<`. You can also think of sum() as a reduced `+`.

  # sum() takes a vector and sequentially applies `+` until .x is through:
  sum(1:10)

  # a + b is actually just syntactic sugar for this: `+`(a, b): you're applying
  # the 2-argument function `+` to a and b. So sum(1:10) does this:

  `+`(1, 2) %>%
    `+`(3) %>%
    `+`(4) %>%
    `+`(5) %>%
    `+`(6) %>%
    `+`(7) %>%
    `+`(8) %>%
    `+`(9) %>%
    `+`(10)

  # 4. Use `+` and `reduce` to write a function that finds the sum of any ------
  # vector.

  #4@

  # my_sum <- function(x) {
  #   __
  # }

  #@4

  # my_sum(1:1000) == sum(1:1000)

  #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # Great work! You're one step closer to tidyverse enlightenment. Make sure to
  # return to this topic to meditate on it later.
}
## function() {
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
##   #                   Intro to the Tidyverse by Colleen O'Briant
##   #                               Koan #19: reduce()
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # In order to progress:
##   # 1. Read all instructions carefully.
##   # 2. When you come to an exercise, fill in the blank, un-comment the line
##   #    (Ctrl/Cmd Shift C), and execute the code in the console (Ctrl/Cmd Return).
##   #    If the piece of code spans multiple lines, highlight the whole chunk or
##   #    simply put your cursor at the end of the last line.
##   # 3. Save (Ctrl/Cmd S).
##   # 4. Test that your answers are correct (Ctrl/Cmd Shift T).
## 
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # We've already learned the first function from the purrr family: map(). Now
##   # we'll learn the next two: in this koan, we'll focus on reduce(), and in koan
##   # 20, we'll learn accumulate().
## 
##   # map(.x, .f) applies a function `.f` to every element of `.x` and creates a
##   # list of outputs the same length as `.x`.
## 
##   # Similarly, reduce(.x, .f) applies a 2-argument function `.f` to every
##   # element of `.x` *sequentially* to get you *one* final output. That is, it
##   # uses `.f` to reduce `.x`.
## 
##   # In this koan, we'll see how max() reduces a vector down to a single output,
##   # and also that min() and sum() do the same thing.
## 
##   library(tidyverse)
## 
##   # The first example of how reduce() can be used is the function max(). max()
##   # takes a vector of numbers and returns the number which is the largest.
## 
##   # 1. Fill in the blank below so that the statement returns TRUE: -------------
## 
##   #1@
## 
##   # max(c(5, 3, __, 2)) == 9
## 
##   #@1
## 
##   # What if you had to write the function `max` from scratch? You would probably
##   # need to use `>`, keeping track of the maximum you've seen so far. So an
##   # algorithm to sequentially apply `>` to find the maximum of c(4, 2, 6, 8)
##   # would be this:
## 
##   # Compare the first two numbers in `.x`:
##   4 > 2
##   # Since this returns TRUE, save 4 as the largest number seen thus far.
## 
##   # Compare 4 with the next number in `.x`:
##   4 > 6
##   # Since this returns FALSE, save 6 as the largest number seen thus far.
## 
##   # Compare 6 with the next number in `.x`:
##   6 > 8
##   # Since this returns FALSE, save 8 as the largest number seen thus far.
##   # Return 8 since we've made it through `.x`.
## 
##   # I'll write a 2-argument function that takes two numbers, compares them, and
##   # returns the larger one. I'll call this function "larger", and I'll use
##   # if_else() to do it:
## 
##   ?qelp::if_else
## 
##   larger <- function(x, y) {
##     if_else(x > y, x, y)
##   }
## 
##   # 2. Test that the function works by filling in the blank below with any -----
##   # number to make the statement return TRUE:
## 
##   #2@
## 
##   # larger(5, __) == 5
## 
##   #@2
## 
##   # `larger` is a good start, but I want `max` to work on a vector of any size,
##   # not just 2. Something I could do is to apply `larger` until `.x` is through,
##   # sequentially:
## 
##   larger(4, 2) %>%
##     larger(6) %>%
##     larger(8)
## 
##   # Using `reduce()` does the same thing as what I've written above to
##   # sequentially apply `.f` until `.x` is through:
## 
##   reduce(c(4, 2, 6, 8), larger)
## 
##   # So I can write a function my_max() that takes any vector of any length and
##   # finds what the maximum is by sequentially applying `larger`:
## 
##   my_max <- function(x) {
##     reduce(x, larger)
##   }
## 
##   # Check that the function works:
## 
##   my_max(c(4, 2, 6, 8))
## 
##   # Instead of creating the functions `larger` and `my_max`, if you just wanted
##   # to find the maximum of a vector using reduce(), you can use the formula
##   # syntax just like with map(). Since .f is a 2-argument function for reduce(),
##   # you'll refer to `.x` AND `.y`. .x is the value passed from previous
##   # evaluations of .f, and .y refers to the new element of the vector.
## 
##   reduce(c(4, 2, 6, 8), ~ if_else(.x > .y, .x, .y))
## 
##   # This is a great visualization of what `reduce()` does from Hadley Wickham's
##   # book *Advanced R*:
##   #' https://d33wubrfki0l68.cloudfront.net/9c239e1227c69b7a2c9c2df234c21f3e1c74dd57/eec0e/diagrams/functionals/reduce.png
## 
##   # Also read the qelp docs for reduce:
##   ?qelp::reduce
## 
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # 3. Your turn: create a function my_min() that finds the minimum of a -------
##   # vector of numbers, using `<`, if_else(), and reduce().
## 
##   #3@
## 
##   # my_min <- function(x) {
##   #   __
##   # }
## 
##   #@3
## 
##   # Check that my_min works:
## 
##   # my_min(c(4, 2, 6, 8))
## 
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # So we've learned that you can think of max() as a reduced `>` and min() as a
##   # reduced `<`. You can also think of sum() as a reduced `+`.
## 
##   # sum() takes a vector and sequentially applies `+` until .x is through:
##   sum(1:10)
## 
##   # a + b is actually just syntactic sugar for this: `+`(a, b): you're applying
##   # the 2-argument function `+` to a and b. So sum(1:10) does this:
## 
##   `+`(1, 2) %>%
##     `+`(3) %>%
##     `+`(4) %>%
##     `+`(5) %>%
##     `+`(6) %>%
##     `+`(7) %>%
##     `+`(8) %>%
##     `+`(9) %>%
##     `+`(10)
## 
##   # 4. Use `+` and `reduce` to write a function that finds the sum of any ------
##   # vector.
## 
##   #4@
## 
##   # my_sum <- function(x) {
##   #   __
##   # }
## 
##   #@4
## 
##   # my_sum(1:1000) == sum(1:1000)
## 
##   #:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
## 
##   # Great work! You're one step closer to tidyverse enlightenment. Make sure to
##   # return to this topic to meditate on it later.
## }