Solutions to this workshop can be found here

Review from last time

Let’s review variables and types

# Create a variable that holds the number 53

# Create a variable that holds two times the value of the first variable

# Create a variable that holds the word "science"

# Get R to tell you the "type" of the last variable you created

# What happens if you try to add two of the "science" variables together? Why?

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)

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)

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

Let’s check the types that these vectors belong to

# check the type of bob_the_vector
is(bob_the_vector)
# check the type of char_vector_1
is(char_vector_1)
# by the way... what is the type of c, as in, the thing you put before your vector?

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"

# check the type of mix_vector

# why is this happening (check the documentation of c)

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

# why is it not numeric?

# 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

# check the type of good_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

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

# In pairs:
# Now make the sequence: 2, 2.5, 3, 3.5

# Identify what values are corresponding to what arguments

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

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

# Make a variable first_number, containing any number you want your vector to
# start with

# Make a variable last_number, containing any number you want your vector to
# end with

# Use first_number, last_number, and number_elements as arguments to seq to
# create your vector, final_vector

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

# Use length() to find out how long final_vector is

# 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

# Add 3 to the vector. What happens?

You can also add vectors together!

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

# Add vector_a and vector_b

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

# Use sum() to add up those numbers

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.

# 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

# Check the length of the vector you just created

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

# Let's check what the first number in long_vector is
print(long_vector[1])

# Now check what the 32nd number in long_vector is
# 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)

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)])
# Now do the same thing as above, but using a function we have learned today to
# specificy the indices (4, 5, 6, 7, 8)

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,....))

# Use long_vector together with position_vector to create shorter_vector, which
# will hold every othern number from long_vector

# print out long_vector_2, then shorter_vector

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

LS0tCnRpdGxlOiAiSW50cm8gUiBDb3Vyc2UsIFdvcmtzaG9wIDM6IFZlY3RvcnMiCnN1YnRpdGxlOiB8CiAgICB8ICAgLSBjcmVhdGluZyB2ZWN0b3JzIChsaXN0cyBvZiB0aGluZ3MpCiAgICB8ICAgLSBjb25zZWN1dGl2ZSBzZXF1ZW5jZXMgb2YgbnVtYmVycwogICAgfCAgIC0gbWF0aCB3aXRoIHZlY3RvcnMKICAgIHwgICAtIHB1bGxpbmcgc3BlY2lmaWMgZWxlbWVudHMgb3V0IG9mIHZlY3RvcnMKICAgIHwgICAtIHZlY3RvciB0eXBlcwphdXRob3I6Ci0gRXVnZW5lIFBsYXZza2luCi0gR3JhY2UgQXZlY2lsbGEKLSBUb2JpIFNjaHJhaW5rCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBkZXB0aDogMwogICAgdGlkeTogeWVzCiAgICB0b2M6IHllcwotLS0KKipTb2x1dGlvbnMgdG8gdGhpcyB3b3Jrc2hvcCBjYW4gYmUgZm91bmQgW2hlcmVdKFNvbHV0aW9uc19Xb3Jrc2hvcF8zLm5iLmh0bWwpKioKCiMgUmV2aWV3IGZyb20gbGFzdCB0aW1lCgpMZXQncyByZXZpZXcgdmFyaWFibGVzIGFuZCB0eXBlcwpgYGB7cn0KIyBDcmVhdGUgYSB2YXJpYWJsZSB0aGF0IGhvbGRzIHRoZSBudW1iZXIgNTMKCiMgQ3JlYXRlIGEgdmFyaWFibGUgdGhhdCBob2xkcyB0d28gdGltZXMgdGhlIHZhbHVlIG9mIHRoZSBmaXJzdCB2YXJpYWJsZQoKIyBDcmVhdGUgYSB2YXJpYWJsZSB0aGF0IGhvbGRzIHRoZSB3b3JkICJzY2llbmNlIgoKIyBHZXQgUiB0byB0ZWxsIHlvdSB0aGUgInR5cGUiIG9mIHRoZSBsYXN0IHZhcmlhYmxlIHlvdSBjcmVhdGVkCgojIFdoYXQgaGFwcGVucyBpZiB5b3UgdHJ5IHRvIGFkZCB0d28gb2YgdGhlICJzY2llbmNlIiB2YXJpYWJsZXMgdG9nZXRoZXI/IFdoeT8KCmBgYAoKIyBJbnRyb2R1Y3Rpb24gdG8gdmVjdG9ycwpTbyBmYXIsIHdlJ3ZlIGJlZW4gdXNpbmcgUiB0byBkbyB0aGluZ3Mgd2UgY2FuIGVhc2lseSBkbyBvbiBvdXIgb3duLCBvciB3aXRoIGEgc2ltcGxlIGNhbGN1bGF0b3IuIFdlIGRvbid0IG5lZWQgUiB0byBhZGQgdHdvIG51bWJlcnMuIEJ1dCB3aGVyZSBwcm9ncmFtbWluZyBsYW5ndWFnZXMgc3RhcnQgdG8gZ2V0IHJlYWxseSBwb3dlcmZ1bCBpcyB3aGVuIHlvdSBoYXZlIHRvIGRvIHRoZSBzYW1lIHRoaW5nIG92ZXIgYW5kIG92ZXIuIFRvZGF5LCB3ZSdyZSBnb2luZyB0byBsZWFybiBob3cgUiBkZWFscyB3aXRoIGxpc3RzIG9mIG11bHRpcGxlIG51bWJlcnMgb3Igc3RyaW5ncy4gVGhlc2UgbGlzdHMgYXJlIGNhbGxlZCAqdmVjdG9ycyouIChBY3R1YWxseSwgYSAnbGlzdCcgaXMgYWxzbyBhIHRoaW5nIGluIFIsIGJ1dCBpdCBtZWFucyBzb21ldGhpbmcgc2xpZ2h0bHkgZGlmZmVyZW50Li4uIHZlcnkgY29uZnVzaW5nLiBTbyBsZXQncyBzdGljayB3aXRoIGNhbGxpbmcgdGhlc2UgdGhpbmdzIHZlY3RvcnMuKQoKV2UgY2FuIGNyZWF0ZSBhIHZlY3RvciBieSB1c2luZyBgYygpYCwgd2l0aCB0aGUgdGhpbmdzIHdlIHdhbnQgdG8gcHV0IGluc2lkZSB0aGUgdmVjdG9yIGdvaW5nIGluIHBhcmVudGhlc2VzLiAoYyBzdGFuZHMgZm9yIGNvbmNhdGVuYXRlL2NvbWJpbmUuKSBGb3IgZXhhbXBsZToKYGBge3J9CiMgQ3JlYXRlIGEgdmVjdG9yCnZlY3Rvcl8xIDwtIGMoMSwgNCwgMywgMTgpCnByaW50KHZlY3Rvcl8xKQpgYGAKCllvdSBjYW4gdXNlIHZhcmlhYmxlcyB0byBkZWZpbmUgdmVjdG9ycyB0b28hIFRyeSBpdCBiZWxvdzoKYGBge3J9CiMgQ3JlYXRlIDMgdmFyaWFibGVzLCBuYW1lZCB2YXJpYWJsZV8xLCB2YXJpYWJsZV8yLCBhbmQgYm9iLCBhbmQgaGF2ZSBlYWNoIG9mCiMgdGhlbSBob2xkIGEgc2luZ2xlIG51bWJlcgp2YXJpYWJsZV8xIDwtIDEKdmFyaWFibGVfMiA8LSAyCmJvYiA8LSA5CiMgQ29tYmluZSB0aGVzZSB2YXJpYWJsZXMgaW4gYW55IG9yZGVyIHlvdSB3YW50IGludG8gYSB2ZWN0b3IgbmFtZWQgYm9iX3RoZV92ZWN0b3IKYm9iX3RoZV92ZWN0b3IgPC0gYyh2YXJpYWJsZV8xLCB2YXJpYWJsZV8yLCBib2IpCiMgcHJpbnQgb3V0IGJvYl90aGVfdmVjdG9yCnByaW50KGJvYl90aGVfdmVjdG9yKQpgYGAKClZlY3RvcnMgY2FuIGFsc28gaG9sZCBjaGFyYWN0ZXIgdHlwZXMhCmBgYHtyfQojIENyZWF0ZSBhIHZlY3RvciwgY2hhcl92ZWN0b3JfMSBjb250YWluaW5nIG11bHRpcGxlIHN0cmluZ3MsIGFuZCBwcmludCBpdCBvdXQKY2hhcl92ZWN0b3JfMSA9IGMoJ3N0dWZmJywgJ3RoaW5ncycpCmNoYXJfdmVjdG9yXzEKYGBgCgpMZXQncyBjaGVjayB0aGUgKnR5cGVzKiB0aGF0IHRoZXNlIHZlY3RvcnMgYmVsb25nIHRvCmBgYHtyfQojIGNoZWNrIHRoZSB0eXBlIG9mIGJvYl90aGVfdmVjdG9yCmlzKGJvYl90aGVfdmVjdG9yKQojIGNoZWNrIHRoZSB0eXBlIG9mIGNoYXJfdmVjdG9yXzEKaXMoY2hhcl92ZWN0b3JfMSkKIyBieSB0aGUgd2F5Li4uIHdoYXQgaXMgdGhlIHR5cGUgb2YgYywgYXMgaW4sIHRoZSB0aGluZyB5b3UgcHV0IGJlZm9yZSB5b3VyIHZlY3Rvcj8KYGBgCgpXaGF0IGlmIHdlIHdhbnRlZCB0byBzdG9yZSB0aGUgbnVtYmVyIDMgYW5kIHRoZSBjaGFyYWN0ZXIgIjMiIHRvZ2V0aGVyIGluIGEgdmVjdG9yPwpgYGB7cn0KIyBDcmVhdGUgYSB2ZWN0b3IsIG1peF92ZWN0b3IsIHdpdGggMyBhbmQgIjMiCgojIGNoZWNrIHRoZSB0eXBlIG9mIG1peF92ZWN0b3IKCiMgd2h5IGlzIHRoaXMgaGFwcGVuaW5nIChjaGVjayB0aGUgZG9jdW1lbnRhdGlvbiBvZiBjKQpgYGAKCiMgQ29udmVydGluZyBiZXR3ZWVuIG51bWVyaWMgYW5kIGNoYXJhY3RlciB0eXBlcwpGaW5hbGx5LCBpdCdzIHNvbWV0aW1lcyByZWFsbHkgaGVscGZ1bCB0byBiZSBhYmxlIHRvIHN3aXRjaCBzb21ldGhpbmcgYmV0d2VlbiBhIG51bWVyaWMgYW5kIGEgY2hhcmFjdGVyIHR5cGUuIExldCdzIHNheSB5b3UgaW1wb3J0IHNvbWUgZGF0YSBhbmQgeW91ciBjb21wdXRlciBpbnNpc3RzIG9uIHRoaW5raW5nIGl0J3MgbGV0dGVycywgd2hlbiBpdCBpcyBjbGVhcmx5IG51bWJlcnMgKHRoaXMgaGFwcGVucyBhIGxvdCEpIFdlIGNhbiB1c2UgdGhlIGBhcy5udW1lcmljKClgIGZ1bmN0aW9uIHRvIHNldCB0aGluZ3MgcmlnaHQuCmBgYHtyfQpiYWRfbnVtZXJpY192ZWN0b3IgPC0gYygnMScsJzMnLCc0JywnNycsJzExJykKCiMgY2hlY2sgdGhlIHR5cGUgb2YgYmFkX251bWVyaWNfdmVjdG9yCgojIHdoeSBpcyBpdCBub3QgbnVtZXJpYz8KCiMgdXNlIGFzLm51bWVyaWMoKSB0byBjcmVhdGUgYSBuZXcgdmVjdG9yLCBnb29kX251bWVyaWNfdmVjdG9yLCB3aGljaCBoYXMgYWxsCiMgdGhlIHZhbHVlcyBmcm9tIGJhZF9udW1lcmljX3ZlY3RvciBidXQgYXMgbnVtYmVycyBpbnN0ZWFkIG9mIGNoYXJhY3RlcnMKCiMgY2hlY2sgdGhlIHR5cGUgb2YgZ29vZF9udW1lcmljX3ZlY3RvcgoKYGBgCgpXZSBjYW4gYWxzbyBkbyB0aGlzIGNoYW5nZSBiYWNrd2FyZHMuIEJhc2VkIG9uIHdoYXQgeW91IHNhdyByaWdodCBhYm92ZSwgd2hhdCBkbyB5b3UgdGhpbmsgdGhlIGZ1bmN0aW9uIGlzIGNhbGxlZCB0aGF0IGNvbnZlcnRzIG51bWVyaWMgdmFsdWVzIHRvIGNoYXJhY3RlciB0eXBlPwpgYGB7cn0KbnVtX3ZlY3RvciA8LSBjKDgxLCAyNDMsIDcyOSkKCiMgY29udmVydCBudW1fdmVjdG9yIHRvIGEgY2hhcmFjdGVyIHZlY3RvcgoKYGBgCgojIE1ha2luZyBjb25zZWN1dGl2ZSBzZXF1ZW5jZXMKCk9uZSByZWFsbHkgdXNlZnVsIHRoaW5nIHdlIGNhbiBkbyBpbiBSIGlzIG1ha2UgdmVjdG9ycyBvZiBldmVubHkgc3BhY2VkIG51bWJlcnMuIFRvIGRvIHRoaXMsIHdlIGNhbiB1c2UgdGhlIGBzZXEoKWAgZnVuY3Rpb24uIExldCdzIHRyeSB0byB1c2UgdGhlIGJ1aWx0LWluIFIgZG9jdW1lbnRhdGlvbiBvZiBgc2VxKClgIHRvIGZpZ3VyZSBvdXQgaG93IHRvIHVzZSBpdC4KYGBge3J9CiMgT24geW91ciBvd246CiMgQmFzZWQgb24gdGhlIGRvY3VtZW50YXRpb24gZnJvbSBvZiBzZXEsIG1ha2UgdGhlIHNlcXVlbmNlOiAxLCAyLCAzLCA0CgojIEluIHBhaXJzOgojIE5vdyBtYWtlIHRoZSBzZXF1ZW5jZTogMiwgMi41LCAzLCAzLjUKCiMgSWRlbnRpZnkgd2hhdCB2YWx1ZXMgYXJlIGNvcnJlc3BvbmRpbmcgdG8gd2hhdCBhcmd1bWVudHMKCmBgYAoKU2VxIGNhbiB3b3JrIGluIGJvdGggZGlyZWN0aW9ucyAoaS5lLiwgdGhlIG51bWJlcnMgZG9uJ3QgaGF2ZSB0byBiZSBnb2luZyB1cCkKYGBge3J9CiMgVXNlIHNlcSB0byBtYWtlIHRoZSBmb2xsb3dpbmcgc2VxdWVuY2U6IDUsIDMsIDEsIC0xCgpgYGAKClRoZXJlIGFyZSB0aHJlZSB0aGluZ3MgdGhhdCBtYWtlIHNlcSByZWFsbHkgcG93ZXJmdWwgY29tcGFyZWQgdG8ganVzdCB0eXBpbmcgb3V0IHZlY3RvcnMgb2YgbnVtYmVycyBieSBoYW5kOgoKMS4gSXQgY2FuIGdlbmVyYXRlIHJlYWFhYWFhbGx5IGxvbmcgc2VxdWVuY2VzIG9mIG51bWJlcnMKCjIuIExpa2UgYWxsIGZ1bmN0aW9ucywgaXQgY2FuIHVzZSB2YXJpYWJsZXMgYXMgaW5wdXRzLCB3aGljaCBtZWFucyB5b3UgZG9uJ3QgaGF2ZSB0byBjaGFuZ2UgeW91ciB3aG9sZSBjb2RlIGV2ZXJ5IHRpbWUgeW91IGNoYW5nZSB5b3VyIG1pbmQgYWJvdXQgd2hhdCBudW1iZXJzIHlvdSdyZSBpbnRlcmVzdGVkIGluIHdvcmtpbmcgd2l0aAoKMy4gV2hlbiB5b3Ugd2FudCB0byBtYWtlIGEgdmVjdG9yIG9mIGEgY2VydGFpbiBsZW5ndGgsIGl0IHdpbGwgZG8gdGhlIG1hdGggZm9yIHlvdSBvZiB3aGF0IHRoZSBzcGFjaW5nIGJldHdlZW4geW91ciBudW1iZXJzIG5lZWRzIHRvIGxvb2sgbGlrZQoKTGV0J3MgdHJ5IHVzaW5nIHNvbWUgb2YgdGhpcyEKYGBge3J9CiMgTWFrZSBhIHZhcmlhYmxlIG51bWJlcl9lbGVtZW50cywgd2hpY2ggd2lsbCB0ZWxsIHlvdSBob3cgbWFueSBudW1iZXJzIHlvdSB3YW50CiMgaW4geW91ciBmaW5hbCB2ZWN0b3IKCiMgTWFrZSBhIHZhcmlhYmxlIGZpcnN0X251bWJlciwgY29udGFpbmluZyBhbnkgbnVtYmVyIHlvdSB3YW50IHlvdXIgdmVjdG9yIHRvCiMgc3RhcnQgd2l0aAoKIyBNYWtlIGEgdmFyaWFibGUgbGFzdF9udW1iZXIsIGNvbnRhaW5pbmcgYW55IG51bWJlciB5b3Ugd2FudCB5b3VyIHZlY3RvciB0bwojIGVuZCB3aXRoCgojIFVzZSBmaXJzdF9udW1iZXIsIGxhc3RfbnVtYmVyLCBhbmQgbnVtYmVyX2VsZW1lbnRzIGFzIGFyZ3VtZW50cyB0byBzZXEgdG8KIyBjcmVhdGUgeW91ciB2ZWN0b3IsIGZpbmFsX3ZlY3RvcgoKYGBgCgpSZWxhdGVkbHksIGEgcmVhbGx5IHVzZWZ1bCBmdW5jdGlvbiBpbiBSIGlzIGBsZW5ndGgoKWAuIEl0IGNhbiB0ZWxsIHlvdSBob3cgbG9uZyB5b3VyIHZlY3RvciBpcyAoaG93IG1hbnkgZWxlbWVudHMgYXJlIGluIHlvdXIgdmVjdG9yKQpgYGB7cn0KIyBVc2UgbGVuZ3RoKCkgdG8gZmluZCBvdXQgaG93IGxvbmcgbnVtYmVyX2VsZW1lbnRzIGlzCgojIFVzZSBsZW5ndGgoKSB0byBmaW5kIG91dCBob3cgbG9uZyBmaW5hbF92ZWN0b3IgaXMKCiMgRG9lcyB0aGlzIG1ha2Ugc2Vuc2U/CgpgYGAKCiMgT3BlcmF0aW9ucyBvbiB2ZWN0b3JzIG9mIG51bWJlcnMKCk9uZSBvZiB0aGUgYmVzdCB0aGluZ3MgYWJvdXQgdmVjdG9ycyB0aGF0IHdpbGwgY29tZSB1cCBhZ2FpbiBhbmQgYWdhaW4gc29vbiBpcyB0aGF0IHlvdSBjYW4gZG8gb3BlcmF0aW9ucyBvbiB0aGVtLCBqdXN0IGxpa2Ugd2l0aCBudW1iZXJzLiBIZXJlJ3Mgb25lIGV4YW1wbGU6CmBgYHtyfQojIENyZWF0ZSBhIHZhcmlhYmxlIGhvbGRpbmcgYSB2ZWN0b3IgdGhhdCBjb250YWlucyBhbiBldmVubHkgc3BhY2VkIHNlcXVlbmNlIG9mCiMgZml2ZSBudW1iZXJzLCBmcm9tIDIgdG8gNAoKIyBBZGQgMyB0byB0aGUgdmVjdG9yLiBXaGF0IGhhcHBlbnM/CgpgYGAKCllvdSBjYW4gYWxzbyBhZGQgdmVjdG9ycyB0b2dldGhlciEKYGBge3J9CnZlY3Rvcl9hIDwtIGMoMSwyLDMpCnZlY3Rvcl9iIDwtIGMoNCw1LDYpCgojIEFkZCB2ZWN0b3JfYSBhbmQgdmVjdG9yX2IKCmBgYAoKQW5kIGZpbmFsbHkuLi4gbWFueSBtYXRoLXJlbGF0ZWQgZnVuY3Rpb25zIGNhbiB3b3JrIG9uIHZlY3RvcnMhIGBzdW0oKWAgaXMgYSBncmVhdCBleGFtcGxlIG9mIHRoaXMuCmBgYHtyfQojIENyZWF0ZSBhIHZlY3RvciBvZiBjb25zZWN1dGl2ZSBudW1iZXJzIGJldHdlZW4gMSBhbmQgMTAwCgojIFVzZSBzdW0oKSB0byBhZGQgdXAgdGhvc2UgbnVtYmVycwoKYGBgCgojIEdldHRpbmcgc3BlY2lmaWMgZWxlbWVudHMgZnJvbSB2ZWN0b3JzCgpPZnRlbiwgaXQncyByZWFsbHkgdXNlZnVsIHRvIGZpbmQgb3V0IHdoYXQgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWMgcG9zaXRpb24gKG9yICppbmRleCopIGluIGEgdmVjdG9yIGlzLiBSIG1ha2VzIHRoaXMgZWFzeS4KYGBge3IgZWNobz1GQUxTRX0KIyBUaGlzIGp1c3QgbWFrZXMgc3VyZSB0aGUgZ3JhcGhpYyBpcyBpbmNsdWRlZAppZiAoZGlyLmV4aXN0cygnY2xhc3NfZmlndXJlcycpKXsKICBsaWJyYXJ5KGtuaXRyKQogIGluY2x1ZGVfZ3JhcGhpY3MoJ2NsYXNzX2ZpZ3VyZXMvdmVjdG9yX2lsbHVzdHJhdGlvbjEucG5nJykKfQpgYGAKCkxldCdzIGNyZWF0ZSBhIHJlYWxseSBsb25nIHZlY3RvciBhbmQgYXNrIFIgdG8gdGVsbCB1cyBhYm91dCBzcGVjaWZpYyBwb2ludHMgYWxvbmcgdGhhdCB2ZWN0b3IuCmBgYHtyfQojIENyZWF0ZSB0aHJlZSB2YXJpYWJsZXMsIGZpcnN0X251bSwgbGFzdF9udW0sIGFuZCBudW1fb2ZfZWxlbWVudHMKIyBUaGUgZmlyc3QgdHdvIGNhbiBiZSB3aGF0ZXZlciBudW1iZXJzIHlvdSB3YW50LCBudW1fb2ZfZWxlbWVudHMgc2hvdWxkIGJlIDEwMAojIERPTidUIHVzZSAxIGZvciBmaXJzdF9udW0sIGFuZCBkb24ndCB1c2UgMTAwIGZvciBsYXN0X251bS4gQmUgY3JlYXRpdmUuCgojIFVzZSB0aGUgZnVuY3Rpb24gd2UgbGVhcm5lZCBkdXJpbmcgdGhlIGxhc3QgY2xhc3MgdG8gbWFrZSBhIHNlcXVlbmNlIG9mIGxlbmd0aAojIG51bV9vZl9lbGVtZW50cyBzdGFydGluZyBhdCBmaXJzdF9udW0gYW5kIGdvaW5nIHRvIGxhc3RfbnVtLCBhbmQgcHV0IHRoYXQgaW4gYQojIHZlY3RvciBjYWxsZWQgbmV3X3ZlY3RvcgoKIyBDaGVjayB0aGUgbGVuZ3RoIG9mIHRoZSB2ZWN0b3IgeW91IGp1c3QgY3JlYXRlZAoKYGBgCgpUbyBhY2Nlc3MgdGhlIG51bWJlciBhdCBhIHNwZWNpZmljIHBvc2l0aW9uLCB3ZSBjYW4gdXNlIHNxdWFyZSBicmFja2V0cyEKYGBge3J9CiMgTWFrZSBhIHZlY3RvciBjYWxsZWQgbG9uZ192ZWN0b3IgdGhhdCBnb2VzIGZyb20gLTEgdG8gNTAgYW5kIGhhcyAxMDAgbnVtYmVycyBpbnNpZGUKCiMgTGV0J3MgY2hlY2sgd2hhdCB0aGUgZmlyc3QgbnVtYmVyIGluIGxvbmdfdmVjdG9yIGlzCnByaW50KGxvbmdfdmVjdG9yWzFdKQoKIyBOb3cgY2hlY2sgd2hhdCB0aGUgMzJuZCBudW1iZXIgaW4gbG9uZ192ZWN0b3IgaXMKCmBgYAoKCmBgYHtyfQojIE5vdyBjaGVjayB3aGF0IHRoZSBsYXN0IG51bWJlciBpbiBsb25nX3ZlY3RvciBpcwojIChib251czogZG8gdGhpcyB1c2luZyBhIHZhcmlhYmxlIHlvdSd2ZSBhbHJlYWR5IGNyZWF0ZWQsIHJhdGhlciB0aGFuIGp1c3QKIyB0eXBpbmcgb3V0IDEwMCkKCmBgYAoKWW91IGRvbid0IGhhdmUgdG8ganVzdCBwcm92aWRlIGEgc2luZ2xlIG51bWJlciBhcyBpbiBpbmRleCAodGhlIHRoaW5nIGluc2lkZSB0aGUgc3F1YXJlIGJyYWNrZXRzKTsgdmVjdG9ycyB3b3JrIHRvbyEKYGBge3J9CiMgUHJpbnQgb3V0IHRoZSA0dGgsIDV0aCwgNnRoLCA3dGgsIGFuZCA4dGggbnVtYmVyIGluIGxvbmdfdmVjdG9yCnByaW50KGxvbmdfdmVjdG9yW2MoNCw1LDYsNyw4KV0pCiMgTm93IGRvIHRoZSBzYW1lIHRoaW5nIGFzIGFib3ZlLCBidXQgdXNpbmcgYSBmdW5jdGlvbiB3ZSBoYXZlIGxlYXJuZWQgdG9kYXkgdG8KIyBzcGVjaWZpY3kgdGhlIGluZGljZXMgKDQsIDUsIDYsIDcsIDgpCgpgYGAKCkFjdHVhbGx5LCB3ZSBjYW4gZ2V0IGV2ZW4gbW9yZSBjcmVhdGl2ZSBoZXJlLiBMZXQncyBzYXkgeW91IHdhbnRlZCB0byBjcmVhdGUgYSB2ZWN0b3IgdGhhdCBoYWQgaW5zaWRlIGl0ICpldmVyeSBvdGhlciBudW1iZXIqIGZyb20gYSB2ZWN0b3IgKCppLmUuKiB0aGUgMXN0LCAzcmQsIDV0aCwgZXRjIG51bWJlcnMgdGhhdCBhcmUgaW4gdGhhdCB2ZWN0b3IpLiBMZXQncyB0cnkgdGhpcy4KSGludDogeW91IGNhbiB1c2UgYHNlcSgpYCB0byBjcmVhdGUgYSB2ZWN0b3Igb2YgcG9zaXRpb25zICgqaW5kaWNlcyopIHRoYXQgeW91IHRoZW4gdXNlIHRvIGdldCB0aGUgcG9zaXRpb25zIHlvdSB3YW50IGZyb20gdGhhdCB2ZWN0b3IKYGBge3J9CmxvbmdfdmVjdG9yXzJfc3RhcnQgPC0gLTEKbG9uZ192ZWN0b3JfMl9lbmQgPC0gNTAKbG9uZ192ZWN0b3JfMl9sZW5ndGggPC0gMjAKbG9uZ192ZWN0b3JfMiA8LQogIHNlcShsb25nX3ZlY3Rvcl8yX3N0YXJ0LCBsb25nX3ZlY3Rvcl8yX2VuZCwgbGVuZ3RoLm91dCA9IGxvbmdfdmVjdG9yXzJfbGVuZ3RoKQojIENyZWF0ZSBwb3NpdGlvbl92ZWN0b3IsIHdoaWNoIHdpbGwgaG9sZCB0aGUgcG9zaXRpb25zIHlvdSB3YW50IHRvIGdldCBvdXQgb2YKIyBsb25nX3ZlY3Rvcl8yIChpLmUuIGMoMSwzLDUsLi4uLikpCgojIFVzZSBsb25nX3ZlY3RvciB0b2dldGhlciB3aXRoIHBvc2l0aW9uX3ZlY3RvciB0byBjcmVhdGUgc2hvcnRlcl92ZWN0b3IsIHdoaWNoCiMgd2lsbCBob2xkIGV2ZXJ5IG90aGVybiBudW1iZXIgZnJvbSBsb25nX3ZlY3RvcgoKIyBwcmludCBvdXQgbG9uZ192ZWN0b3JfMiwgdGhlbiBzaG9ydGVyX3ZlY3RvcgoKYGBgCgojIFRoaW5ncyB3ZSBob3BlIHlvdSd2ZSBsZWFybmVkIHRvZGF5IChhbmQgd2lsbCBob3BlZnVsbHkgcmVtZW1iZXIgbmV4dCB0aW1lKQoKKiBWZWN0b3JzIGFyZSBsaXN0cyBvZiBlaXRoZXIgbnVtZXJpYyBvciBjaGFyYWN0ZXIgdHlwZQoqIFlvdSBjYW4gZG8gbWF0aCBvbiBudW1lcmljIHZlY3RvcnMKKiBZb3UgY2FuIGNvbnZlcnQgYmV0d2VlbiBudW1lcmljIGFuZCBjaGFyYWN0ZXIgdHlwZSB2ZWN0b3JzIHVzaW5nIGBhcy5udW1lcmljKClgIGFuZCBgYXMuY2hhcmFjdGVyKClgCiogWW91IGNhbiB1c2UgdGhlIGBzZXEoKWAgZnVuY3Rpb24gdG8gZ2VuZXJhdGUgdmVjdG9ycyBvZiBldmVubHkgc3BhY2VkIG51bWJlcnMKKiBJbmRleGluZyEhIQoKCg==