Review from last time

Let’s review variables and types

# Create a variable that holds the number 53
var_1 <- 53
# Create a variable that holds two times the value of the first variable
var_2 <- var_1 * 2
# Create a variable that holds the word "science"
sci_var <- 'science'
# Get R to tell you the "type" of the last variable you created
is(sci_var)
[1] "character"           "vector"              "data.frameRowLabels" "SuperClassMethod"   
# What happens if you try to add two of the "science" variables together? Why?
  # error, since characters can't be added together

Introduction to vectors

So far, we’ve been using R to do things we can easily do on our own, or with a simple calculator. We don’t need R to add two numbers. But where programming languages start to get really powerful is when you have to do the same thing over and over. Today, we’re going to learn how R deals with lists of multiple numbers or strings. These lists are called vectors. (Actually, a ‘list’ is also a thing in R, but it means something slightly different… very confusing. So let’s stick with calling these things vectors.)

We can create a vector by using c(), with the things we want to put inside the vector going in parentheses. (c stands for concatenate/combine.) For example:

# Create a vector
vector_1 <- c(1, 4, 3, 18)
print(vector_1)
[1]  1  4  3 18

You can use variables to define vectors too! Try it below:

# Create 3 variables, named variable_1, variable_2, and bob, and have each of
# them hold a single number
variable_1 <- 1
variable_2 <- 2
bob <- 9
# Combine these variables in any order you want into a vector named bob_the_vector
bob_the_vector <- c(variable_1, variable_2, bob)
# print out bob_the_vector
print(bob_the_vector)
[1] 1 2 9

Vectors can also hold character types!

# Create a vector, char_vector_1 containing multiple strings, and print it out
char_vector_1 = c('stuff', 'things')
char_vector_1
[1] "stuff"  "things"

Let’s check the types that these vectors belong to

# check the type of bob_the_vector
is(bob_the_vector)
[1] "numeric" "vector" 
# check the type of char_vector_1
is(char_vector_1)
[1] "character"           "vector"              "data.frameRowLabels" "SuperClassMethod"   
# by the way... what is the type of c, as in, the thing you put before your vector?

The type of c (which we can get by running is(c)) is a function

What if we wanted to store the number 3 and the character “3” together in a vector?

# Create a vector, mix_vector, with 3 and "3"
mix_vector <- c(3, '3')
# check the type of mix_vector
is(mix_vector)
[1] "character"           "vector"              "data.frameRowLabels" "SuperClassMethod"   
# why is this happening (check the documentation of c)

The description says that “All arguments are coerced to a common type”. Programming languages usually have a formal ‘hierarchy’ for types, but the easiest way to think about which type is the ‘common type’ in this case is to think about whether it makes more sense to convert a number to a character, or a character to a number.

Either way, you want to watch out for automatic type conversion like this. R has many defaults like this one that can easily trip up your future programs.

Converting between numeric and character types

Finally, it’s sometimes really helpful to be able to switch something between a numeric and a character type. Let’s say you import some data and your computer insists on thinking it’s letters, when it is clearly numbers (this happens a lot!) We can use the as.numeric() function to set things right.

bad_numeric_vector <- c('1','3','4','7','11')

# check the type of bad_numeric_vector
is(bad_numeric_vector)
[1] "character"           "vector"              "data.frameRowLabels" "SuperClassMethod"   
# why is it not numeric?
  # we put quotes around each number
# use as.numeric() to create a new vector, good_numeric_vector, which has all
# the values from bad_numeric_vector but as numbers instead of characters
good_numeric_vector <- as.numeric(bad_numeric_vector)
# check the type of good_numeric_vector
is(good_numeric_vector)
[1] "numeric" "vector" 

We can also do this change backwards. Based on what you saw right above, what do you think the function is called that converts numeric values to character type?

num_vector <- c(81, 243, 729)

# convert num_vector to a character vector
as.character(num_vector)
[1] "81"  "243" "729"

Making consecutive sequences

One really useful thing we can do in R is make vectors of evenly spaced numbers. To do this, we can use the seq() function. Let’s try to use the built-in R documentation of seq() to figure out how to use it.

# On your own:
# Based on the documentation from of seq, make the sequence: 1, 2, 3, 4
seq(1, 4)
[1] 1 2 3 4
# In pairs:
# Now make the sequence: 2, 2.5, 3, 3.5
seq(2, 3.5, by = 0.5)
[1] 2.0 2.5 3.0 3.5
# Identify what values are corresponding to what arguments

Here, the first value corresponds to the ‘from’ argument, the second to the ‘to’ argument, and in the second example we add a ‘by’ argument to tell seq() what the number to skip is.

Seq can work in both directions (i.e., the numbers don’t have to be going up)

# Use seq to make the following sequence: 5, 3, 1, -1
seq(5, -1, by = -2)
[1]  5  3  1 -1

There are three things that make seq really powerful compared to just typing out vectors of numbers by hand:

  1. It can generate reaaaaaally long sequences of numbers

  2. Like all functions, it can use variables as inputs, which means you don’t have to change your whole code every time you change your mind about what numbers you’re interested in working with

  3. When you want to make a vector of a certain length, it will do the math for you of what the spacing between your numbers needs to look like

Let’s try using some of this!

# Make a variable number_elements, which will tell you how many numbers you want
# in your final vector
number_elements <- 8
# Make a variable first_number, containing any number you want your vector to
# start with
first_number <- 6
# Make a variable last_number, containing any number you want your vector to
# end with
last_number <- 7
# Use first_number, last_number, and number_elements as arguments to seq to
# create your vector, final_vector
final_vector <- seq(first_number, last_number, length.out = number_elements)
print(final_vector)
[1] 6.000000 6.142857 6.285714 6.428571 6.571429 6.714286 6.857143 7.000000

Relatedly, a really useful function in R is length(). It can tell you how long your vector is (how many elements are in your vector)

# Use length() to find out how long number_elements is
length(number_elements)
[1] 1
# Use length() to find out how long final_vector is
length(final_vector)
[1] 8
# Does this make sense?

Operations on vectors of numbers

One of the best things about vectors that will come up again and again soon is that you can do operations on them, just like with numbers. Here’s one example:

# Create a variable holding a vector that contains an evenly spaced sequence of
# five numbers, from 2 to 4
vector_2 <- seq(2, 4, length.out = 5)
# Add 3 to the vector. What happens?
3 + vector_2
[1] 5.0 5.5 6.0 6.5 7.0

You can also add vectors together!

vector_a <- c(1,2,3)
vector_b <- c(4,5,6)

# Add vector_a and vector_b
vector_a + vector_b
[1] 5 7 9

And finally… many math-related functions can work on vectors! sum() is a great example of this.

# Create a vector of consecutive numbers between 1 and 100
hundred_vec <- seq(1, 100)
# Use sum() to add up those numbers
sum(hundred_vec)
[1] 5050

Getting specific elements from vectors

Often, it’s really useful to find out what the value of a specific position (or index) in a vector is. R makes this easy.

Let’s create a really long vector and ask R to tell us about specific points along that vector.

# Create three variables, first_num, last_num, and num_of_elements
# The first two can be whatever numbers you want, num_of_elements should be 100
# DON'T use 1 for first_num, and don't use 100 for last_num. Be creative.
first_num <- 34
last_num <- 43
num_of_elements <- 100
# Use the function we learned during the last class to make a sequence of length
# num_of_elements starting at first_num and going to last_num, and put that in a
# vector called new_vector
new_vector <- seq(first_num, last_num, length.out = num_of_elements)
# Check the length of the vector you just created
length(new_vector)
[1] 100

To access the number at a specific position, we can use square brackets!

# Make a vector called long_vector that goes from -1 to 50 and has 100 numbers inside
long_vector <- seq(-1, 50, length.out = 100)
# Let's check what the first number in long_vector is
print(long_vector[1])
[1] -1
# Now check what the 32nd number in long_vector is
print(long_vector[32])
[1] 14.9697
# Now check what the last number in long_vector is
# (bonus: do this using a variable you've already created, rather than just
# typing out 100)
long_vector[length(long_vector)]
[1] 50

You don’t have to just provide a single number as in index (the thing inside the square brackets); vectors work too!

# Print out the 4th, 5th, 6th, 7th, and 8th number in long_vector
print(long_vector[c(4,5,6,7,8)])
[1] 0.5454545 1.0606061 1.5757576 2.0909091 2.6060606
# Now do the same thing as above, but using a function we have learned today to
# specificy the indices (4, 5, 6, 7, 8)
print(long_vector[seq(4,8)])
[1] 0.5454545 1.0606061 1.5757576 2.0909091 2.6060606

Actually, we can get even more creative here. Let’s say you wanted to create a vector that had inside it every other number from a vector (i.e. the 1st, 3rd, 5th, etc numbers that are in that vector). Let’s try this. Hint: you can use seq() to create a vector of positions (indices) that you then use to get the positions you want from that vector

long_vector_2_start <- -1
long_vector_2_end <- 50
long_vector_2_length <- 20
long_vector_2 <-
  seq(long_vector_2_start, long_vector_2_end, length.out = long_vector_2_length)
# Create position_vector, which will hold the positions you want to get out of
# long_vector_2 (i.e. c(1,3,5,....))
position_vector <- seq(1, long_vector_2_length, by = 2)
# Use long_vector together with position_vector to create shorter_vector, which
# will hold every othern number from long_vector
shorter_vector <- long_vector_2[position_vector]
# print out long_vector_2, then shorter_vector
print(long_vector_2)
 [1] -1.000000  1.684211  4.368421  7.052632  9.736842 12.421053 15.105263 17.789474 20.473684 23.157895
[11] 25.842105 28.526316 31.210526 33.894737 36.578947 39.263158 41.947368 44.631579 47.315789 50.000000
print(shorter_vector)
 [1] -1.000000  4.368421  9.736842 15.105263 20.473684 25.842105 31.210526 36.578947 41.947368 47.315789

Things we hope you’ve learned today (and will hopefully remember next time)

LS0tCnRpdGxlOiAiSW50cm8gUiBDb3Vyc2UsIFNvbHV0aW9ucyB0byBXb3Jrc2hvcCAzOiBWZWN0b3JzIgpzdWJ0aXRsZTogfAogICAgfCAgIC0gY3JlYXRpbmcgdmVjdG9ycyAobGlzdHMgb2YgdGhpbmdzKQogICAgfCAgIC0gY29uc2VjdXRpdmUgc2VxdWVuY2VzIG9mIG51bWJlcnMKICAgIHwgICAtIG1hdGggd2l0aCB2ZWN0b3JzCiAgICB8ICAgLSBwdWxsaW5nIHNwZWNpZmljIGVsZW1lbnRzIG91dCBvZiB2ZWN0b3JzCiAgICB8ICAgLSB2ZWN0b3IgdHlwZXMKYXV0aG9yOgotIEV1Z2VuZSBQbGF2c2tpbgotIEdyYWNlIEF2ZWNpbGxhCi0gVG9iaSBTY2hyYWluawpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZGVwdGg6IDMKICAgIHRpZHk6IHllcwogICAgdG9jOiB5ZXMKLS0tCgojIFJldmlldyBmcm9tIGxhc3QgdGltZQoKTGV0J3MgcmV2aWV3IHZhcmlhYmxlcyBhbmQgdHlwZXMKCmBgYHtyfQojIENyZWF0ZSBhIHZhcmlhYmxlIHRoYXQgaG9sZHMgdGhlIG51bWJlciA1Mwp2YXJfMSA8LSA1MwojIENyZWF0ZSBhIHZhcmlhYmxlIHRoYXQgaG9sZHMgdHdvIHRpbWVzIHRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgdmFyaWFibGUKdmFyXzIgPC0gdmFyXzEgKiAyCiMgQ3JlYXRlIGEgdmFyaWFibGUgdGhhdCBob2xkcyB0aGUgd29yZCAic2NpZW5jZSIKc2NpX3ZhciA8LSAnc2NpZW5jZScKIyBHZXQgUiB0byB0ZWxsIHlvdSB0aGUgInR5cGUiIG9mIHRoZSBsYXN0IHZhcmlhYmxlIHlvdSBjcmVhdGVkCmlzKHNjaV92YXIpCiMgV2hhdCBoYXBwZW5zIGlmIHlvdSB0cnkgdG8gYWRkIHR3byBvZiB0aGUgInNjaWVuY2UiIHZhcmlhYmxlcyB0b2dldGhlcj8gV2h5PwogICMgZXJyb3IsIHNpbmNlIGNoYXJhY3RlcnMgY2FuJ3QgYmUgYWRkZWQgdG9nZXRoZXIKYGBgCgojIEludHJvZHVjdGlvbiB0byB2ZWN0b3JzCgpTbyBmYXIsIHdlJ3ZlIGJlZW4gdXNpbmcgUiB0byBkbyB0aGluZ3Mgd2UgY2FuIGVhc2lseSBkbyBvbiBvdXIgb3duLCBvciB3aXRoIGEgc2ltcGxlIGNhbGN1bGF0b3IuIFdlIGRvbid0IG5lZWQgUiB0byBhZGQgdHdvIG51bWJlcnMuIEJ1dCB3aGVyZSBwcm9ncmFtbWluZyBsYW5ndWFnZXMgc3RhcnQgdG8gZ2V0IHJlYWxseSBwb3dlcmZ1bCBpcyB3aGVuIHlvdSBoYXZlIHRvIGRvIHRoZSBzYW1lIHRoaW5nIG92ZXIgYW5kIG92ZXIuIFRvZGF5LCB3ZSdyZSBnb2luZyB0byBsZWFybiBob3cgUiBkZWFscyB3aXRoIGxpc3RzIG9mIG11bHRpcGxlIG51bWJlcnMgb3Igc3RyaW5ncy4gVGhlc2UgbGlzdHMgYXJlIGNhbGxlZCAqdmVjdG9ycyouIChBY3R1YWxseSwgYSAnbGlzdCcgaXMgYWxzbyBhIHRoaW5nIGluIFIsIGJ1dCBpdCBtZWFucyBzb21ldGhpbmcgc2xpZ2h0bHkgZGlmZmVyZW50Li4uIHZlcnkgY29uZnVzaW5nLiBTbyBsZXQncyBzdGljayB3aXRoIGNhbGxpbmcgdGhlc2UgdGhpbmdzIHZlY3RvcnMuKQoKV2UgY2FuIGNyZWF0ZSBhIHZlY3RvciBieSB1c2luZyBgYygpYCwgd2l0aCB0aGUgdGhpbmdzIHdlIHdhbnQgdG8gcHV0IGluc2lkZSB0aGUgdmVjdG9yIGdvaW5nIGluIHBhcmVudGhlc2VzLiAoYyBzdGFuZHMgZm9yIGNvbmNhdGVuYXRlL2NvbWJpbmUuKSBGb3IgZXhhbXBsZToKYGBge3J9CiMgQ3JlYXRlIGEgdmVjdG9yCnZlY3Rvcl8xIDwtIGMoMSwgNCwgMywgMTgpCnByaW50KHZlY3Rvcl8xKQpgYGAKCllvdSBjYW4gdXNlIHZhcmlhYmxlcyB0byBkZWZpbmUgdmVjdG9ycyB0b28hIFRyeSBpdCBiZWxvdzoKYGBge3J9CiMgQ3JlYXRlIDMgdmFyaWFibGVzLCBuYW1lZCB2YXJpYWJsZV8xLCB2YXJpYWJsZV8yLCBhbmQgYm9iLCBhbmQgaGF2ZSBlYWNoIG9mCiMgdGhlbSBob2xkIGEgc2luZ2xlIG51bWJlcgp2YXJpYWJsZV8xIDwtIDEKdmFyaWFibGVfMiA8LSAyCmJvYiA8LSA5CiMgQ29tYmluZSB0aGVzZSB2YXJpYWJsZXMgaW4gYW55IG9yZGVyIHlvdSB3YW50IGludG8gYSB2ZWN0b3IgbmFtZWQgYm9iX3RoZV92ZWN0b3IKYm9iX3RoZV92ZWN0b3IgPC0gYyh2YXJpYWJsZV8xLCB2YXJpYWJsZV8yLCBib2IpCiMgcHJpbnQgb3V0IGJvYl90aGVfdmVjdG9yCnByaW50KGJvYl90aGVfdmVjdG9yKQpgYGAKClZlY3RvcnMgY2FuIGFsc28gaG9sZCBjaGFyYWN0ZXIgdHlwZXMhCmBgYHtyfQojIENyZWF0ZSBhIHZlY3RvciwgY2hhcl92ZWN0b3JfMSBjb250YWluaW5nIG11bHRpcGxlIHN0cmluZ3MsIGFuZCBwcmludCBpdCBvdXQKY2hhcl92ZWN0b3JfMSA9IGMoJ3N0dWZmJywgJ3RoaW5ncycpCmNoYXJfdmVjdG9yXzEKYGBgCgpMZXQncyBjaGVjayB0aGUgKnR5cGVzKiB0aGF0IHRoZXNlIHZlY3RvcnMgYmVsb25nIHRvCmBgYHtyfQojIGNoZWNrIHRoZSB0eXBlIG9mIGJvYl90aGVfdmVjdG9yCmlzKGJvYl90aGVfdmVjdG9yKQojIGNoZWNrIHRoZSB0eXBlIG9mIGNoYXJfdmVjdG9yXzEKaXMoY2hhcl92ZWN0b3JfMSkKIyBieSB0aGUgd2F5Li4uIHdoYXQgaXMgdGhlIHR5cGUgb2YgYywgYXMgaW4sIHRoZSB0aGluZyB5b3UgcHV0IGJlZm9yZSB5b3VyIHZlY3Rvcj8KYGBgClRoZSB0eXBlIG9mIGBjYCAod2hpY2ggd2UgY2FuIGdldCBieSBydW5uaW5nIGBpcyhjKWApIGlzIGEgZnVuY3Rpb24KCldoYXQgaWYgd2Ugd2FudGVkIHRvIHN0b3JlIHRoZSBudW1iZXIgMyBhbmQgdGhlIGNoYXJhY3RlciAiMyIgdG9nZXRoZXIgaW4gYSB2ZWN0b3I/CmBgYHtyfQojIENyZWF0ZSBhIHZlY3RvciwgbWl4X3ZlY3Rvciwgd2l0aCAzIGFuZCAiMyIKbWl4X3ZlY3RvciA8LSBjKDMsICczJykKIyBjaGVjayB0aGUgdHlwZSBvZiBtaXhfdmVjdG9yCmlzKG1peF92ZWN0b3IpCiMgd2h5IGlzIHRoaXMgaGFwcGVuaW5nIChjaGVjayB0aGUgIkRlc2NyaXB0aW9uIiBzZWN0aW9uIGluIGRvY3VtZW50YXRpb24gZm9yIGMpCmBgYApUaGUgZGVzY3JpcHRpb24gc2F5cyB0aGF0ICJBbGwgYXJndW1lbnRzIGFyZSBjb2VyY2VkIHRvIGEgY29tbW9uIHR5cGUiLiBQcm9ncmFtbWluZyBsYW5ndWFnZXMgdXN1YWxseSBoYXZlIGEgZm9ybWFsICdoaWVyYXJjaHknIGZvciB0eXBlcywgYnV0IHRoZSBlYXNpZXN0IHdheSB0byB0aGluayBhYm91dCB3aGljaCB0eXBlIGlzIHRoZSAnY29tbW9uIHR5cGUnIGluIHRoaXMgY2FzZSBpcyB0byB0aGluayBhYm91dCB3aGV0aGVyIGl0IG1ha2VzIG1vcmUgc2Vuc2UgdG8gY29udmVydCBhIG51bWJlciB0byBhIGNoYXJhY3Rlciwgb3IgYSBjaGFyYWN0ZXIgdG8gYSBudW1iZXIuCgpFaXRoZXIgd2F5LCB5b3Ugd2FudCB0byB3YXRjaCBvdXQgZm9yIGF1dG9tYXRpYyB0eXBlIGNvbnZlcnNpb24gbGlrZSB0aGlzLiBSIGhhcyBtYW55IGRlZmF1bHRzIGxpa2UgdGhpcyBvbmUgdGhhdCBjYW4gZWFzaWx5IHRyaXAgdXAgeW91ciBmdXR1cmUgcHJvZ3JhbXMuCgojIENvbnZlcnRpbmcgYmV0d2VlbiBudW1lcmljIGFuZCBjaGFyYWN0ZXIgdHlwZXMKRmluYWxseSwgaXQncyBzb21ldGltZXMgcmVhbGx5IGhlbHBmdWwgdG8gYmUgYWJsZSB0byBzd2l0Y2ggc29tZXRoaW5nIGJldHdlZW4gYSBudW1lcmljIGFuZCBhIGNoYXJhY3RlciB0eXBlLiBMZXQncyBzYXkgeW91IGltcG9ydCBzb21lIGRhdGEgYW5kIHlvdXIgY29tcHV0ZXIgaW5zaXN0cyBvbiB0aGlua2luZyBpdCdzIGxldHRlcnMsIHdoZW4gaXQgaXMgY2xlYXJseSBudW1iZXJzICh0aGlzIGhhcHBlbnMgYSBsb3QhKSBXZSBjYW4gdXNlIHRoZSBgYXMubnVtZXJpYygpYCBmdW5jdGlvbiB0byBzZXQgdGhpbmdzIHJpZ2h0LgpgYGB7cn0KYmFkX251bWVyaWNfdmVjdG9yIDwtIGMoJzEnLCczJywnNCcsJzcnLCcxMScpCgojIGNoZWNrIHRoZSB0eXBlIG9mIGJhZF9udW1lcmljX3ZlY3RvcgppcyhiYWRfbnVtZXJpY192ZWN0b3IpCiMgd2h5IGlzIGl0IG5vdCBudW1lcmljPwogICMgd2UgcHV0IHF1b3RlcyBhcm91bmQgZWFjaCBudW1iZXIKIyB1c2UgYXMubnVtZXJpYygpIHRvIGNyZWF0ZSBhIG5ldyB2ZWN0b3IsIGdvb2RfbnVtZXJpY192ZWN0b3IsIHdoaWNoIGhhcyBhbGwKIyB0aGUgdmFsdWVzIGZyb20gYmFkX251bWVyaWNfdmVjdG9yIGJ1dCBhcyBudW1iZXJzIGluc3RlYWQgb2YgY2hhcmFjdGVycwpnb29kX251bWVyaWNfdmVjdG9yIDwtIGFzLm51bWVyaWMoYmFkX251bWVyaWNfdmVjdG9yKQojIGNoZWNrIHRoZSB0eXBlIG9mIGdvb2RfbnVtZXJpY192ZWN0b3IKaXMoZ29vZF9udW1lcmljX3ZlY3RvcikKYGBgCgpXZSBjYW4gYWxzbyBkbyB0aGlzIGNoYW5nZSBiYWNrd2FyZHMuIEJhc2VkIG9uIHdoYXQgeW91IHNhdyByaWdodCBhYm92ZSwgd2hhdCBkbyB5b3UgdGhpbmsgdGhlIGZ1bmN0aW9uIGlzIGNhbGxlZCB0aGF0IGNvbnZlcnRzIG51bWVyaWMgdmFsdWVzIHRvIGNoYXJhY3RlciB0eXBlPwpgYGB7cn0KbnVtX3ZlY3RvciA8LSBjKDgxLCAyNDMsIDcyOSkKCiMgY29udmVydCBudW1fdmVjdG9yIHRvIGEgY2hhcmFjdGVyIHZlY3Rvcgphcy5jaGFyYWN0ZXIobnVtX3ZlY3RvcikKYGBgCgojIE1ha2luZyBjb25zZWN1dGl2ZSBzZXF1ZW5jZXMKCk9uZSByZWFsbHkgdXNlZnVsIHRoaW5nIHdlIGNhbiBkbyBpbiBSIGlzIG1ha2UgdmVjdG9ycyBvZiBldmVubHkgc3BhY2VkIG51bWJlcnMuIFRvIGRvIHRoaXMsIHdlIGNhbiB1c2UgdGhlIGBzZXEoKWAgZnVuY3Rpb24uIExldCdzIHRyeSB0byB1c2UgdGhlIGJ1aWx0LWluIFIgZG9jdW1lbnRhdGlvbiBvZiBgc2VxKClgIHRvIGZpZ3VyZSBvdXQgaG93IHRvIHVzZSBpdC4KYGBge3J9CiMgT24geW91ciBvd246CiMgQmFzZWQgb24gdGhlIGRvY3VtZW50YXRpb24gZnJvbSBvZiBzZXEsIG1ha2UgdGhlIHNlcXVlbmNlOiAxLCAyLCAzLCA0CnNlcSgxLCA0KQojIEluIHBhaXJzOgojIE5vdyBtYWtlIHRoZSBzZXF1ZW5jZTogMiwgMi41LCAzLCAzLjUKc2VxKDIsIDMuNSwgYnkgPSAwLjUpCiMgSWRlbnRpZnkgd2hhdCB2YWx1ZXMgYXJlIGNvcnJlc3BvbmRpbmcgdG8gd2hhdCBhcmd1bWVudHMKYGBgCkhlcmUsIHRoZSBmaXJzdCB2YWx1ZSBjb3JyZXNwb25kcyB0byB0aGUgJ2Zyb20nIGFyZ3VtZW50LCB0aGUgc2Vjb25kIHRvIHRoZSAndG8nIGFyZ3VtZW50LCBhbmQgaW4gdGhlIHNlY29uZCBleGFtcGxlIHdlIGFkZCBhICdieScgYXJndW1lbnQgdG8gdGVsbCBgc2VxKClgIHdoYXQgdGhlIG51bWJlciB0byBza2lwIGlzLgoKU2VxIGNhbiB3b3JrIGluIGJvdGggZGlyZWN0aW9ucyAoaS5lLiwgdGhlIG51bWJlcnMgZG9uJ3QgaGF2ZSB0byBiZSBnb2luZyB1cCkKYGBge3J9CiMgVXNlIHNlcSB0byBtYWtlIHRoZSBmb2xsb3dpbmcgc2VxdWVuY2U6IDUsIDMsIDEsIC0xCnNlcSg1LCAtMSwgYnkgPSAtMikKYGBgCgpUaGVyZSBhcmUgdGhyZWUgdGhpbmdzIHRoYXQgbWFrZSBzZXEgcmVhbGx5IHBvd2VyZnVsIGNvbXBhcmVkIHRvIGp1c3QgdHlwaW5nIG91dCB2ZWN0b3JzIG9mIG51bWJlcnMgYnkgaGFuZDoKCjEuIEl0IGNhbiBnZW5lcmF0ZSByZWFhYWFhYWxseSBsb25nIHNlcXVlbmNlcyBvZiBudW1iZXJzCgoyLiBMaWtlIGFsbCBmdW5jdGlvbnMsIGl0IGNhbiB1c2UgdmFyaWFibGVzIGFzIGlucHV0cywgd2hpY2ggbWVhbnMgeW91IGRvbid0IGhhdmUgdG8gY2hhbmdlIHlvdXIgd2hvbGUgY29kZSBldmVyeSB0aW1lIHlvdSBjaGFuZ2UgeW91ciBtaW5kIGFib3V0IHdoYXQgbnVtYmVycyB5b3UncmUgaW50ZXJlc3RlZCBpbiB3b3JraW5nIHdpdGgKCjMuIFdoZW4geW91IHdhbnQgdG8gbWFrZSBhIHZlY3RvciBvZiBhIGNlcnRhaW4gbGVuZ3RoLCBpdCB3aWxsIGRvIHRoZSBtYXRoIGZvciB5b3Ugb2Ygd2hhdCB0aGUgc3BhY2luZyBiZXR3ZWVuIHlvdXIgbnVtYmVycyBuZWVkcyB0byBsb29rIGxpa2UKCkxldCdzIHRyeSB1c2luZyBzb21lIG9mIHRoaXMhCmBgYHtyfQojIE1ha2UgYSB2YXJpYWJsZSBudW1iZXJfZWxlbWVudHMsIHdoaWNoIHdpbGwgdGVsbCB5b3UgaG93IG1hbnkgbnVtYmVycyB5b3Ugd2FudAojIGluIHlvdXIgZmluYWwgdmVjdG9yCm51bWJlcl9lbGVtZW50cyA8LSA4CiMgTWFrZSBhIHZhcmlhYmxlIGZpcnN0X251bWJlciwgY29udGFpbmluZyBhbnkgbnVtYmVyIHlvdSB3YW50IHlvdXIgdmVjdG9yIHRvCiMgc3RhcnQgd2l0aApmaXJzdF9udW1iZXIgPC0gNgojIE1ha2UgYSB2YXJpYWJsZSBsYXN0X251bWJlciwgY29udGFpbmluZyBhbnkgbnVtYmVyIHlvdSB3YW50IHlvdXIgdmVjdG9yIHRvCiMgZW5kIHdpdGgKbGFzdF9udW1iZXIgPC0gNwojIFVzZSBmaXJzdF9udW1iZXIsIGxhc3RfbnVtYmVyLCBhbmQgbnVtYmVyX2VsZW1lbnRzIGFzIGFyZ3VtZW50cyB0byBzZXEgdG8KIyBjcmVhdGUgeW91ciB2ZWN0b3IsIGZpbmFsX3ZlY3RvcgpmaW5hbF92ZWN0b3IgPC0gc2VxKGZpcnN0X251bWJlciwgbGFzdF9udW1iZXIsIGxlbmd0aC5vdXQgPSBudW1iZXJfZWxlbWVudHMpCnByaW50KGZpbmFsX3ZlY3RvcikKYGBgCgpSZWxhdGVkbHksIGEgcmVhbGx5IHVzZWZ1bCBmdW5jdGlvbiBpbiBSIGlzIGBsZW5ndGgoKWAuIEl0IGNhbiB0ZWxsIHlvdSBob3cgbG9uZyB5b3VyIHZlY3RvciBpcyAoaG93IG1hbnkgZWxlbWVudHMgYXJlIGluIHlvdXIgdmVjdG9yKQpgYGB7cn0KIyBVc2UgbGVuZ3RoKCkgdG8gZmluZCBvdXQgaG93IGxvbmcgbnVtYmVyX2VsZW1lbnRzIGlzCmxlbmd0aChudW1iZXJfZWxlbWVudHMpCiMgVXNlIGxlbmd0aCgpIHRvIGZpbmQgb3V0IGhvdyBsb25nIGZpbmFsX3ZlY3RvciBpcwpsZW5ndGgoZmluYWxfdmVjdG9yKQojIERvZXMgdGhpcyBtYWtlIHNlbnNlPwoKYGBgCgojIE9wZXJhdGlvbnMgb24gdmVjdG9ycyBvZiBudW1iZXJzCgpPbmUgb2YgdGhlIGJlc3QgdGhpbmdzIGFib3V0IHZlY3RvcnMgdGhhdCB3aWxsIGNvbWUgdXAgYWdhaW4gYW5kIGFnYWluIHNvb24gaXMgdGhhdCB5b3UgY2FuIGRvIG9wZXJhdGlvbnMgb24gdGhlbSwganVzdCBsaWtlIHdpdGggbnVtYmVycy4gSGVyZSdzIG9uZSBleGFtcGxlOgpgYGB7cn0KIyBDcmVhdGUgYSB2YXJpYWJsZSBob2xkaW5nIGEgdmVjdG9yIHRoYXQgY29udGFpbnMgYW4gZXZlbmx5IHNwYWNlZCBzZXF1ZW5jZSBvZgojIGZpdmUgbnVtYmVycywgZnJvbSAyIHRvIDQKdmVjdG9yXzIgPC0gc2VxKDIsIDQsIGxlbmd0aC5vdXQgPSA1KQojIEFkZCAzIHRvIHRoZSB2ZWN0b3IuIFdoYXQgaGFwcGVucz8KMyArIHZlY3Rvcl8yCmBgYAoKWW91IGNhbiBhbHNvIGFkZCB2ZWN0b3JzIHRvZ2V0aGVyIQpgYGB7cn0KdmVjdG9yX2EgPC0gYygxLDIsMykKdmVjdG9yX2IgPC0gYyg0LDUsNikKCiMgQWRkIHZlY3Rvcl9hIGFuZCB2ZWN0b3JfYgp2ZWN0b3JfYSArIHZlY3Rvcl9iCmBgYAoKQW5kIGZpbmFsbHkuLi4gbWFueSBtYXRoLXJlbGF0ZWQgZnVuY3Rpb25zIGNhbiB3b3JrIG9uIHZlY3RvcnMhIGBzdW0oKWAgaXMgYSBncmVhdCBleGFtcGxlIG9mIHRoaXMuCmBgYHtyfQojIENyZWF0ZSBhIHZlY3RvciBvZiBjb25zZWN1dGl2ZSBudW1iZXJzIGJldHdlZW4gMSBhbmQgMTAwCmh1bmRyZWRfdmVjIDwtIHNlcSgxLCAxMDApCiMgVXNlIHN1bSgpIHRvIGFkZCB1cCB0aG9zZSBudW1iZXJzCnN1bShodW5kcmVkX3ZlYykKYGBgCgojIEdldHRpbmcgc3BlY2lmaWMgZWxlbWVudHMgZnJvbSB2ZWN0b3JzCgpPZnRlbiwgaXQncyByZWFsbHkgdXNlZnVsIHRvIGZpbmQgb3V0IHdoYXQgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWMgcG9zaXRpb24gKG9yICppbmRleCopIGluIGEgdmVjdG9yIGlzLiBSIG1ha2VzIHRoaXMgZWFzeS4KYGBge3IgZWNobz1GQUxTRX0KIyBUaGlzIGp1c3QgbWFrZXMgc3VyZSB0aGUgZ3JhcGhpYyBpcyBpbmNsdWRlZAppZiAoZGlyLmV4aXN0cygnY2xhc3NfZmlndXJlcycpKXsKICBsaWJyYXJ5KGtuaXRyKQogIGluY2x1ZGVfZ3JhcGhpY3MoJ2NsYXNzX2ZpZ3VyZXMvdmVjdG9yX2lsbHVzdHJhdGlvbjEucG5nJykKfQpgYGAKCkxldCdzIGNyZWF0ZSBhIHJlYWxseSBsb25nIHZlY3RvciBhbmQgYXNrIFIgdG8gdGVsbCB1cyBhYm91dCBzcGVjaWZpYyBwb2ludHMgYWxvbmcgdGhhdCB2ZWN0b3IuCmBgYHtyfQojIENyZWF0ZSB0aHJlZSB2YXJpYWJsZXMsIGZpcnN0X251bSwgbGFzdF9udW0sIGFuZCBudW1fb2ZfZWxlbWVudHMKIyBUaGUgZmlyc3QgdHdvIGNhbiBiZSB3aGF0ZXZlciBudW1iZXJzIHlvdSB3YW50LCBudW1fb2ZfZWxlbWVudHMgc2hvdWxkIGJlIDEwMAojIERPTidUIHVzZSAxIGZvciBmaXJzdF9udW0sIGFuZCBkb24ndCB1c2UgMTAwIGZvciBsYXN0X251bS4gQmUgY3JlYXRpdmUuCmZpcnN0X251bSA8LSAzNApsYXN0X251bSA8LSA0MwpudW1fb2ZfZWxlbWVudHMgPC0gMTAwCiMgVXNlIHRoZSBmdW5jdGlvbiB3ZSBsZWFybmVkIGR1cmluZyB0aGUgbGFzdCBjbGFzcyB0byBtYWtlIGEgc2VxdWVuY2Ugb2YgbGVuZ3RoCiMgbnVtX29mX2VsZW1lbnRzIHN0YXJ0aW5nIGF0IGZpcnN0X251bSBhbmQgZ29pbmcgdG8gbGFzdF9udW0sIGFuZCBwdXQgdGhhdCBpbiBhCiMgdmVjdG9yIGNhbGxlZCBuZXdfdmVjdG9yCm5ld192ZWN0b3IgPC0gc2VxKGZpcnN0X251bSwgbGFzdF9udW0sIGxlbmd0aC5vdXQgPSBudW1fb2ZfZWxlbWVudHMpCiMgQ2hlY2sgdGhlIGxlbmd0aCBvZiB0aGUgdmVjdG9yIHlvdSBqdXN0IGNyZWF0ZWQKbGVuZ3RoKG5ld192ZWN0b3IpCmBgYAoKVG8gYWNjZXNzIHRoZSBudW1iZXIgYXQgYSBzcGVjaWZpYyBwb3NpdGlvbiwgd2UgY2FuIHVzZSBzcXVhcmUgYnJhY2tldHMhCmBgYHtyfQojIE1ha2UgYSB2ZWN0b3IgY2FsbGVkIGxvbmdfdmVjdG9yIHRoYXQgZ29lcyBmcm9tIC0xIHRvIDUwIGFuZCBoYXMgMTAwIG51bWJlcnMgaW5zaWRlCmxvbmdfdmVjdG9yIDwtIHNlcSgtMSwgNTAsIGxlbmd0aC5vdXQgPSAxMDApCiMgTGV0J3MgY2hlY2sgd2hhdCB0aGUgZmlyc3QgbnVtYmVyIGluIGxvbmdfdmVjdG9yIGlzCnByaW50KGxvbmdfdmVjdG9yWzFdKQoKIyBOb3cgY2hlY2sgd2hhdCB0aGUgMzJuZCBudW1iZXIgaW4gbG9uZ192ZWN0b3IgaXMKcHJpbnQobG9uZ192ZWN0b3JbMzJdKQpgYGAKCgpgYGB7cn0KIyBOb3cgY2hlY2sgd2hhdCB0aGUgbGFzdCBudW1iZXIgaW4gbG9uZ192ZWN0b3IgaXMKIyAoYm9udXM6IGRvIHRoaXMgdXNpbmcgYSB2YXJpYWJsZSB5b3UndmUgYWxyZWFkeSBjcmVhdGVkLCByYXRoZXIgdGhhbiBqdXN0CiMgdHlwaW5nIG91dCAxMDApCmxvbmdfdmVjdG9yW2xlbmd0aChsb25nX3ZlY3RvcildCgpgYGAKCllvdSBkb24ndCBoYXZlIHRvIGp1c3QgcHJvdmlkZSBhIHNpbmdsZSBudW1iZXIgYXMgaW4gaW5kZXggKHRoZSB0aGluZyBpbnNpZGUgdGhlIHNxdWFyZSBicmFja2V0cyk7IHZlY3RvcnMgd29yayB0b28hCmBgYHtyfQojIFByaW50IG91dCB0aGUgNHRoLCA1dGgsIDZ0aCwgN3RoLCBhbmQgOHRoIG51bWJlciBpbiBsb25nX3ZlY3RvcgpwcmludChsb25nX3ZlY3RvcltjKDQsNSw2LDcsOCldKQojIE5vdyBkbyB0aGUgc2FtZSB0aGluZyBhcyBhYm92ZSwgYnV0IHVzaW5nIGEgZnVuY3Rpb24gd2UgaGF2ZSBsZWFybmVkIHRvZGF5IHRvCiMgc3BlY2lmaWN5IHRoZSBpbmRpY2VzICg0LCA1LCA2LCA3LCA4KQpwcmludChsb25nX3ZlY3RvcltzZXEoNCw4KV0pCmBgYAoKQWN0dWFsbHksIHdlIGNhbiBnZXQgZXZlbiBtb3JlIGNyZWF0aXZlIGhlcmUuIExldCdzIHNheSB5b3Ugd2FudGVkIHRvIGNyZWF0ZSBhIHZlY3RvciB0aGF0IGhhZCBpbnNpZGUgaXQgKmV2ZXJ5IG90aGVyIG51bWJlciogZnJvbSBhIHZlY3RvciAoKmkuZS4qIHRoZSAxc3QsIDNyZCwgNXRoLCBldGMgbnVtYmVycyB0aGF0IGFyZSBpbiB0aGF0IHZlY3RvcikuIExldCdzIHRyeSB0aGlzLgpIaW50OiB5b3UgY2FuIHVzZSBgc2VxKClgIHRvIGNyZWF0ZSBhIHZlY3RvciBvZiBwb3NpdGlvbnMgKCppbmRpY2VzKikgdGhhdCB5b3UgdGhlbiB1c2UgdG8gZ2V0IHRoZSBwb3NpdGlvbnMgeW91IHdhbnQgZnJvbSB0aGF0IHZlY3RvcgpgYGB7cn0KbG9uZ192ZWN0b3JfMl9zdGFydCA8LSAtMQpsb25nX3ZlY3Rvcl8yX2VuZCA8LSA1MApsb25nX3ZlY3Rvcl8yX2xlbmd0aCA8LSAyMApsb25nX3ZlY3Rvcl8yIDwtCiAgc2VxKGxvbmdfdmVjdG9yXzJfc3RhcnQsIGxvbmdfdmVjdG9yXzJfZW5kLCBsZW5ndGgub3V0ID0gbG9uZ192ZWN0b3JfMl9sZW5ndGgpCiMgQ3JlYXRlIHBvc2l0aW9uX3ZlY3Rvciwgd2hpY2ggd2lsbCBob2xkIHRoZSBwb3NpdGlvbnMgeW91IHdhbnQgdG8gZ2V0IG91dCBvZgojIGxvbmdfdmVjdG9yXzIgKGkuZS4gYygxLDMsNSwuLi4uKSkKcG9zaXRpb25fdmVjdG9yIDwtIHNlcSgxLCBsb25nX3ZlY3Rvcl8yX2xlbmd0aCwgYnkgPSAyKQojIFVzZSBsb25nX3ZlY3RvciB0b2dldGhlciB3aXRoIHBvc2l0aW9uX3ZlY3RvciB0byBjcmVhdGUgc2hvcnRlcl92ZWN0b3IsIHdoaWNoCiMgd2lsbCBob2xkIGV2ZXJ5IG90aGVybiBudW1iZXIgZnJvbSBsb25nX3ZlY3RvcgpzaG9ydGVyX3ZlY3RvciA8LSBsb25nX3ZlY3Rvcl8yW3Bvc2l0aW9uX3ZlY3Rvcl0KIyBwcmludCBvdXQgbG9uZ192ZWN0b3JfMiwgdGhlbiBzaG9ydGVyX3ZlY3RvcgpwcmludChsb25nX3ZlY3Rvcl8yKQpwcmludChzaG9ydGVyX3ZlY3RvcikKYGBgCgojIFRoaW5ncyB3ZSBob3BlIHlvdSd2ZSBsZWFybmVkIHRvZGF5IChhbmQgd2lsbCBob3BlZnVsbHkgcmVtZW1iZXIgbmV4dCB0aW1lKQoKKiBWZWN0b3JzIGFyZSBsaXN0cyBvZiBlaXRoZXIgbnVtZXJpYyBvciBjaGFyYWN0ZXIgdHlwZQoqIFlvdSBjYW4gZG8gbWF0aCBvbiBudW1lcmljIHZlY3RvcnMKKiBZb3UgY2FuIGNvbnZlcnQgYmV0d2VlbiBudW1lcmljIGFuZCBjaGFyYWN0ZXIgdHlwZSB2ZWN0b3JzIHVzaW5nIGBhcy5udW1lcmljKClgIGFuZCBgYXMuY2hhcmFjdGVyKClgCiogWW91IGNhbiB1c2UgdGhlIGBzZXEoKWAgZnVuY3Rpb24gdG8gZ2VuZXJhdGUgdmVjdG9ycyBvZiBldmVubHkgc3BhY2VkIG51bWJlcnMKKiBJbmRleGluZyEhIQoKCgo=