1+1
[1] 2
7-8
[1] -1
#Complex Numbers
(2+5i) + (3-1i)
[1] 5+4i
#addition
2-3
[1] -1
#Division
2/3
[1] 0.6666667
#Exponentiation
2^3
[1] 8
#Square Root
sqrt(2)
[1] 1.414214
#Logarithms
log(2)
[1] 0.6931472
#Question _1: Compute the log base 5 of 10 and the log of 10
log10(10) #log of 10, base 10
[1] 1
log(10,5)#log of 10, base 5
[1] 1.430677
log(100,10) #log of 100, base 10
[1] 2
log(10,2) #log of 10, base 2
[1] 3.321928
Computing some offensive metrics in Baseball
#Battling Average=(No of Hits)/(No. of Bats)
#What is the battling average of a player that bats 29 hits in 112 at bats?
BA=(29)/(112)
BA
[1] 0.2589286
Battling_Average=round(BA,digits = 3)
Battling_Average
[1] 0.259
#Question_2:What is the battling average of a player that bats 42 hits in 212 at bats?
#On Base Percentage
#OBP=(H+BB+HBP)/(At Bats+BB+HBP+SF)
#Let us compute the OBP for a player with the following general stats
#AB=515,H=172,BB=84,HBP=5,SF=6
OBP=(172+84+5)/(515+84+5+6)
OBP
[1] 0.4278689
On_Base_Percentage=round(OBP,digits = 3)
On_Base_Percentage
[1] 0.428
#Question_3:Compute the OBP for a player with the following general stats:
#AB=565,H=156,BB=65HBP=3,SF=7
OBP=(156+65+3)/(565+65+3+7)
OBP
[1] 0.35
Often you will want to test whether something is less than, greater
than or equal to something
3 == 8 #Does 3 equal 8
[1] FALSE
3 != 8 # Is 3 different from 8?
[1] TRUE
3 <= 8 #Is less than or equal to 8?
[1] TRUE
3>4 #Is 3 greater than 4
[1] FALSE
#The logical operators are & for logical AND, | for logical OR, and ! for NOT. These are some examples:
#Logical Disjunction (or)
FALSE|FALSE #False OR False
[1] FALSE
#Logical Conjunction (and)
TRUE&FALSE #True AND False
[1] FALSE
#Negation
!FALSE #NOT False
[1] TRUE
#Combination of statements
2<3|1==5 #2<3 is True, 1==5 is False, True or False is True
[1] TRUE
Assigning Values to Variables
# In R, you create a variable and assign it a value using <- as follows
Total_Bases<-6+5
Total_Bases*3
[1] 33
#To see the variables that are currently defined, use ls (as in "list")
ls()
[1] "BA" "Battling_Average" "OBP" "On_Base_Percentage"
[5] "pitches_by_innings" "player_positions" "strikes_by_innings" "Total_Bases"
# to delete the variables that are currently defined, use rm (as in "remove")
rm(Total_Bases)
ls()
[1] "BA" "Battling_Average" "OBP" "On_Base_Percentage"
[5] "pitches_by_innings" "player_positions" "strikes_by_innings"
Either <- or = can be used to assign a value to a variable,but I
prefer <- because is less likely to be confused with the logical
operator ==
Vectors
#The basic type of object in R is a vector, which is an ordered list of values of the same type. You can create a vector using the c() function (as in "concatenate")
pitches_by_innings <- c(12, 15, 10, 20, 10)
pitches_by_innings
[1] 12 15 10 20 10
strikes_by_innings <- c(9, 12, 6, 14, 9)
strikes_by_innings
#Question_4:Define two vectors, runs_per_9inings and hits_per_9innings, each with five elements
runs_per_9inings <-c(67,87,76,45,67)
runs_per_9inings
[1] 67 87 76 45 67
hits_per_9inings <-c(30,27,26,23,15)
hits_per_9inings
[1] 30 27 26 23 15
#There are also some functions that will create vectors with regular patterns, like repeated elements.
#replicate function
rep(2,5)
[1] 2 2 2 2 2
rep(1,4)
[1] 1 1 1 1
rep(3,3)
[1] 3 3 3
#consecutive numbers
1:5
[1] 1 2 3 4 5
2:10
#sequence from 1 to 10 with a step of 2
seq(1,10, by=2)
[1] 1 3 5 7 9
seq(2, 13, by=3)
[1] 2 5 8 11
seq(5, 25,by=5)
[1] 5 10 15 20 25
#Many functions and operators like + or - will work on all elements of the vector.
#add vectors
pitches_by_innings+strikes_by_innings
[1] 21 27 16 34 19
#compare vectors
pitches_by_innings
[1] 12 15 10 20 10
strikes_by_innings
[1] 9 12 6 14 9
pitches_by_innings == strikes_by_innings
[1] FALSE FALSE FALSE FALSE FALSE
#find length of vector
length(pitches_by_innings)
[1] 5
#find minimum value in vector
min(pitches_by_innings)
[1] 10
#find average value in vector
mean(pitches_by_innings)
[1] 13.4
#You can access parts of a vector by using. Recall what the value is of the vector pitches_by_innings
pitches_by_innings
[1] 12 15 10 20 10
#If you want to get the first element
pitches_by_innings[1]
[1] 12
#Question_5:Get the first element of hits_per_9innings
hits_per_9inings[1]
[1] 30
hits_per_9inings
[1] 30 27 26 23 15
hits_per_9inings[c(2,3,4)]
[1] 27 26 23
hits_per_9inings[c(2:4)]
[1] 27 26 23
#If you want to get the last element of pitches_by_innings without explicitly typing the number of elements of pitches_by_innings, make use of the length function, which calculates the length of a vector
pitches_by_innings[length(pitches_by_innings)]
[1] 10
#Question_6:Get the last element of hits_per_9innings.
hits_per_9inings[5]
[1] 15
#You can also extract multiple values from a vector. For instance to get the 2nd through 4th values use:
pitches_by_innings
[1] 12 15 10 20 10
pitches_by_innings[c(2,3,4)]
[1] 15 10 20
pitches_by_innings[c(2:4)]
[1] 15 10 20
#Vectors can also be strings or logical values
player_positions <-c("catcher","pitcher","infielders","outfielders")
player_positions
[1] "catcher" "pitcher" "infielders" "outfielders"
Data Frames
#In statistical applications, data is often stored as a data frame, which is like a spreadsheet, with rows as observations and columns as variables
#To manually create a data frame, use the data.frame() function
data.frame(bonus = c(2,3,1),#in millions
active_roster = c("yes","no","yes"),
salary = c(1.5,2.5,1))#in millions
Most often you will be using data frames loaded from a file. For
example, load the results of a fan’s survey. The function load or
read.table can be used for this.
How to Make a Random Sample
#To randomly select a sample use the function sample(). The following code selects 5 numbers beweeen 1 and 10 at random (without duplication)
sample(1:10, size=5)
[1] 9 5 7 10 4
The first argument gives the vector of data to select elements form
The second argument (size=) gives the size of the sample to select.
Taking a simple random sample from a data frame is only slightly more
complicated, having two steps: 1. Use sample() to select a sample of
size n from a vector of the row numbers of the data frame. 2. Use the
index operator [ to select those rows from the data frame.
#Consider the following example with fake data. First, make up a data frame with two columns. (LETTERS is a character vector of length 26 with capital letters a to z and A to Z. LETTERS is automatically defined and pre-loaded in R)
bar<- data.frame(var1 = LETTERS[1:10], var2 =1:10)
#Check data frame
bar
Suppose you want to select a random sample of size 5. First, define a
variable n with the size of the sample, i.e.5
n<-5
n
[1] 5
Now, select a sample of size 5 from the vector with 1 to 10 (the
number of rows in bar). Use the function nrow() to find the number of
rows in bar instead of manually entering that number.
#Use:to create a vector with all the integers between 1 and the number of rows in bar.
samplerows <- sample(1:nrow(bar),size=n)
samplerows
[1] 10 2 3 9 1
The variable samplerows contains the rows of bar which make a random
sample from all the rows in bar. Extract those rows from bar with
#extract rows
barsample <- bar[samplerows, ]
print(barsample)
The code above creates a new data frame called barsample with a
random sample of rows from bar. In a single line of code.
bar[sample(1:nrow(bar),n),]
Using Tables
The table()command allows us to look at tables. Its simplest usage
looks like table(x) where x is a categorical variable.
For example, a survey asks people if they support the home team or
not. The data is Yes, No, No, Yes, Yes
#We can enter this into R with the c() command, and summarize with the table() command as follows
x<-c("Yes","No","No","Yes","Yes")
table(x)
x
No Yes
2 3
Numerical measures of center and spread Suppose MLB Teams’ CEOs
yearly compensations are sampled and the following are found (in
millions) 12 .4 5 2 50 8 3 1 4 0.25
sals<-c(12,.4,5,2,50,8,3, 1, 4, 0.25)
# the average
mean(sals)
# the variance
var(sals)
#the standard deviation
sd(sals)
#the median
median(sals)
Tukey’s five number summary, useful for boxplots five
numbers:min,lower hinge, median, upper hinge,max
fivenum(sals)
#summary statistics
summary(sals)
How about the mode?
In R we can write our own functions, and a first example of a
function is shown below in order to compute the mode of a vector of
observations x
#Function to find the mode, i.e. most frequent value
getMode <-function(x){
ux<-unique(x)
ux[which.max(tabulate(match(x, ux)))]
}
As an example, we can use the function defined above to find the most
frequent value of the number of pitches_by_inings
#Most frequent value in pitches _by_inings
getMode(pitches_by_innings)
#Question_7:Find the most frequent value of hits_per_9inings
hits_per_9inings
[1] 30 27 26 23 15
getMode(hits_per_9inings)
[1] 30
runs_per_9inings
[1] 67 87 76 45 67
getMode(runs_per_9inings)
[1] 67
Question_8:Summarize the following survey with ‘table’ command:
#What is your favorite day of the week to watch baseball? A total of 10 fans submitted this survey.
#Saturday, Saturday, Sunday, Monday, Saturday, Tuesday, Sunday, Friday, Friday, Monday
game_day<-c("Saturday", "Saturday", "Sunday", "Monday", "Saturday", "Tuesday", "Sunday", "Friday", "Friday", "Monday")
game_day
Question_9:What is the most frequent answer recorded in the survey?
Use the getMode function to compute results
getMode(game_day)
[1] "Saturday"
LS0tCnRpdGxlOiAiR2V0dGluZyBTdGFydGVkIHdpdGggUiIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CgpgYGAKYGBge3J9CjErMQpgYGAKCgpgYGB7cn0KNy04CmBgYApgYGB7cn0KI0NvbXBsZXggTnVtYmVycwooMis1aSkgKyAoMy0xaSkKYGBgCmBgYHtyfQojYWRkaXRpb24KMi0zCmBgYApgYGB7cn0KI0RpdmlzaW9uCjIvMwpgYGAKYGBge3J9CiNFeHBvbmVudGlhdGlvbgoyXjMKYGBgCmBgYHtyfQojU3F1YXJlIFJvb3QKc3FydCgyKQpgYGAKYGBge3J9CiNMb2dhcml0aG1zCmxvZygyKQpgYGAKYGBge3J9CiNRdWVzdGlvbiBfMTogQ29tcHV0ZSB0aGUgbG9nIGJhc2UgNSBvZiAxMCBhbmQgdGhlIGxvZyBvZiAxMApsb2cxMCgxMCkgI2xvZyBvZiAxMCwgYmFzZSAxMApsb2coMTAsNSkjbG9nIG9mIDEwLCBiYXNlIDUKbG9nKDEwMCwxMCkgI2xvZyBvZiAxMDAsIGJhc2UgMTAKbG9nKDEwLDIpICNsb2cgb2YgMTAsIGJhc2UgMgpgYGAKQ29tcHV0aW5nIHNvbWUgb2ZmZW5zaXZlIG1ldHJpY3MgaW4gQmFzZWJhbGwKYGBge3J9CiNCYXR0bGluZyBBdmVyYWdlPShObyBvZiBIaXRzKS8oTm8uIG9mIEJhdHMpCiNXaGF0IGlzIHRoZSBiYXR0bGluZyBhdmVyYWdlIG9mIGEgcGxheWVyIHRoYXQgYmF0cyAyOSBoaXRzIGluIDExMiBhdCBiYXRzPwpCQT0oMjkpLygxMTIpCkJBCmBgYApgYGB7cn0KQmF0dGxpbmdfQXZlcmFnZT1yb3VuZChCQSxkaWdpdHMgPSAzKQpCYXR0bGluZ19BdmVyYWdlCmBgYApgYGB7cn0KI1F1ZXN0aW9uXzI6V2hhdCBpcyB0aGUgYmF0dGxpbmcgYXZlcmFnZSBvZiBhIHBsYXllciB0aGF0IGJhdHMgNDIgaGl0cyBpbiAyMTIgYXQgYmF0cz8KI09uIEJhc2UgUGVyY2VudGFnZQojT0JQPShIK0JCK0hCUCkvKEF0IEJhdHMrQkIrSEJQK1NGKQojTGV0IHVzIGNvbXB1dGUgdGhlIE9CUCBmb3IgYSBwbGF5ZXIgd2l0aCB0aGUgZm9sbG93aW5nIGdlbmVyYWwgc3RhdHMKI0FCPTUxNSxIPTE3MixCQj04NCxIQlA9NSxTRj02Ck9CUD0oMTcyKzg0KzUpLyg1MTUrODQrNSs2KQpPQlAKYGBgCmBgYHtyfQpPbl9CYXNlX1BlcmNlbnRhZ2U9cm91bmQoT0JQLGRpZ2l0cyA9IDMpCk9uX0Jhc2VfUGVyY2VudGFnZQpgYGAKYGBge3J9CiNRdWVzdGlvbl8zOkNvbXB1dGUgdGhlIE9CUCBmb3IgYSBwbGF5ZXIgd2l0aCB0aGUgZm9sbG93aW5nIGdlbmVyYWwgc3RhdHM6CiNBQj01NjUsSD0xNTYsQkI9NjVIQlA9MyxTRj03Ck9CUD0oMTU2KzY1KzMpLyg1NjUrNjUrMys3KQpPQlAKYGBgCk9mdGVuIHlvdSB3aWxsIHdhbnQgdG8gdGVzdCB3aGV0aGVyIHNvbWV0aGluZyBpcyBsZXNzIHRoYW4sIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBzb21ldGhpbmcKYGBge3J9CjMgPT0gOCAjRG9lcyAzIGVxdWFsIDgKYGBgCmBgYHtyfQozICE9IDggIyBJcyAzIGRpZmZlcmVudCBmcm9tIDg/CmBgYApgYGB7cn0KMyA8PSA4ICNJcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gOD8KYGBgCmBgYHtyfQozPjQgI0lzIDMgZ3JlYXRlciB0aGFuIDQKYGBgCmBgYHtyfQojVGhlIGxvZ2ljYWwgb3BlcmF0b3JzIGFyZSAmIGZvciBsb2dpY2FsIEFORCwgfCBmb3IgbG9naWNhbCBPUiwgYW5kICEgZm9yIE5PVC4gVGhlc2UgYXJlIHNvbWUgZXhhbXBsZXM6CiNMb2dpY2FsIERpc2p1bmN0aW9uIChvcikKRkFMU0V8RkFMU0UgI0ZhbHNlIE9SIEZhbHNlCiAgCmBgYApgYGB7cn0KI0xvZ2ljYWwgQ29uanVuY3Rpb24gKGFuZCkKVFJVRSZGQUxTRSAjVHJ1ZSBBTkQgRmFsc2UKYGBgCmBgYHtyfQojTmVnYXRpb24KIUZBTFNFICNOT1QgRmFsc2UKYGBgCmBgYHtyfQojQ29tYmluYXRpb24gb2Ygc3RhdGVtZW50cwoyPDN8MT09NSAjMjwzIGlzIFRydWUsIDE9PTUgaXMgRmFsc2UsIFRydWUgb3IgRmFsc2UgaXMgVHJ1ZQpgYGAKQXNzaWduaW5nIFZhbHVlcyB0byBWYXJpYWJsZXMKYGBge3J9CiMgSW4gUiwgeW91IGNyZWF0ZSBhIHZhcmlhYmxlIGFuZCBhc3NpZ24gaXQgYSB2YWx1ZSB1c2luZyA8LSBhcyBmb2xsb3dzClRvdGFsX0Jhc2VzPC02KzUKVG90YWxfQmFzZXMqMwpgYGAKYGBge3J9CiNUbyBzZWUgdGhlIHZhcmlhYmxlcyB0aGF0IGFyZSBjdXJyZW50bHkgZGVmaW5lZCwgdXNlIGxzIChhcyBpbiAibGlzdCIpCmxzKCkKYGBgCmBgYHtyfQojIHRvIGRlbGV0ZSB0aGUgdmFyaWFibGVzIHRoYXQgYXJlIGN1cnJlbnRseSBkZWZpbmVkLCB1c2Ugcm0gKGFzIGluICJyZW1vdmUiKQpybShUb3RhbF9CYXNlcykKbHMoKQpgYGAKRWl0aGVyIDwtIG9yID0gY2FuIGJlIHVzZWQgdG8gYXNzaWduIGEgdmFsdWUgdG8gYSB2YXJpYWJsZSxidXQgSSBwcmVmZXIgPC0gYmVjYXVzZSBpcyBsZXNzIGxpa2VseSB0byBiZSBjb25mdXNlZCB3aXRoIHRoZSBsb2dpY2FsIG9wZXJhdG9yID09CgpWZWN0b3JzCmBgYHtyfQojVGhlIGJhc2ljIHR5cGUgb2Ygb2JqZWN0IGluIFIgaXMgYSB2ZWN0b3IsIHdoaWNoIGlzIGFuIG9yZGVyZWQgbGlzdCBvZiB2YWx1ZXMgb2YgdGhlIHNhbWUgdHlwZS4gWW91IGNhbiBjcmVhdGUgYSB2ZWN0b3IgdXNpbmcgdGhlIGMoKSBmdW5jdGlvbiAoYXMgaW4gImNvbmNhdGVuYXRlIikKcGl0Y2hlc19ieV9pbm5pbmdzIDwtIGMoMTIsIDE1LCAxMCwgMjAsIDEwKQpwaXRjaGVzX2J5X2lubmluZ3MKYGBgCmBgYHtyfQpzdHJpa2VzX2J5X2lubmluZ3MgPC0gYyg5LCAxMiwgNiwgMTQsIDkpCmBgYAoKCmBgYHtyfQpzdHJpa2VzX2J5X2lubmluZ3MKYGBgCmBgYHtyfQpgYGAKCgpgYGB7cn0KYGBgCgoKYGBge3J9CiNRdWVzdGlvbl80OkRlZmluZSB0d28gdmVjdG9ycywgcnVuc19wZXJfOWluaW5ncyBhbmQgaGl0c19wZXJfOWlubmluZ3MsIGVhY2ggd2l0aCBmaXZlIGVsZW1lbnRzCmBgYApgYGB7cn0KcnVuc19wZXJfOWluaW5ncyA8LWMoNjcsODcsNzYsNDUsNjcpI3J1bnNfcGVyXzlpbmluZ3MgdmVjdG9ycwpydW5zX3Blcl85aW5pbmdzCmBgYAoKYGBge3J9CmhpdHNfcGVyXzlpbmluZ3MgPC1jKDMwLDI3LDI2LDIzLDE1KSNoaXRzX3Blcl85aW5uaW5ncyB2ZWN0b3JzCmhpdHNfcGVyXzlpbmluZ3MKYGBgCgpgYGB7cn0KI1RoZXJlIGFyZSBhbHNvIHNvbWUgZnVuY3Rpb25zIHRoYXQgd2lsbCBjcmVhdGUgdmVjdG9ycyB3aXRoIHJlZ3VsYXIgcGF0dGVybnMsIGxpa2UgcmVwZWF0ZWQgZWxlbWVudHMuCmBgYAoKCmBgYHtyfQojcmVwbGljYXRlIGZ1bmN0aW9uCmBgYAoKCmBgYHtyfQpyZXAoMiw1KQpgYGAKYGBge3J9CnJlcCgxLDQpCmBgYAoKCmBgYHtyfQpyZXAoMywzKQojY29uc2VjdXRpdmUgbnVtYmVycwoxOjUKYGBgCmBgYHtyfQoyOjEwCmBgYApgYGB7cn0KI3NlcXVlbmNlIGZyb20gMSB0byAxMCB3aXRoIGEgc3RlcCBvZiAyCnNlcSgxLDEwLCBieT0yKQpgYGAKYGBge3J9CnNlcSgyLCAxMywgYnk9MykKYGBgCgpgYGB7cn0Kc2VxKDUsIDI1LGJ5PTUpCgpgYGAKYGBge3J9CiNNYW55IGZ1bmN0aW9ucyBhbmQgb3BlcmF0b3JzIGxpa2UgKyBvciAtIHdpbGwgd29yayBvbiBhbGwgZWxlbWVudHMgb2YgdGhlIHZlY3Rvci4KI2FkZCB2ZWN0b3JzCnBpdGNoZXNfYnlfaW5uaW5ncytzdHJpa2VzX2J5X2lubmluZ3MKYGBgCgoKYGBge3J9CiNjb21wYXJlIHZlY3RvcnMKcGl0Y2hlc19ieV9pbm5pbmdzCnN0cmlrZXNfYnlfaW5uaW5ncwpwaXRjaGVzX2J5X2lubmluZ3MgPT0gc3RyaWtlc19ieV9pbm5pbmdzCmBgYAoKYGBge3J9CiNmaW5kIGxlbmd0aCBvZiB2ZWN0b3IKbGVuZ3RoKHBpdGNoZXNfYnlfaW5uaW5ncykKYGBgCmBgYHtyfQojZmluZCBtaW5pbXVtIHZhbHVlIGluIHZlY3RvcgptaW4ocGl0Y2hlc19ieV9pbm5pbmdzKQpgYGAKYGBge3J9CiNmaW5kIGF2ZXJhZ2UgdmFsdWUgaW4gdmVjdG9yCm1lYW4ocGl0Y2hlc19ieV9pbm5pbmdzKQpgYGAKYGBge3J9CiNZb3UgY2FuIGFjY2VzcyBwYXJ0cyBvZiBhIHZlY3RvciBieSB1c2luZy4gUmVjYWxsIHdoYXQgdGhlIHZhbHVlIGlzIG9mIHRoZSB2ZWN0b3IgcGl0Y2hlc19ieV9pbm5pbmdzCnBpdGNoZXNfYnlfaW5uaW5ncwpgYGAKYGBge3J9CiNJZiB5b3Ugd2FudCB0byBnZXQgdGhlIGZpcnN0IGVsZW1lbnQKcGl0Y2hlc19ieV9pbm5pbmdzWzFdCmBgYApgYGB7cn0KI1F1ZXN0aW9uXzU6R2V0IHRoZSBmaXJzdCBlbGVtZW50IG9mIGhpdHNfcGVyXzlpbm5pbmdzCmBgYAoKCmBgYHtyfQpoaXRzX3Blcl85aW5pbmdzWzFdCgpgYGAKYGBge3J9CmhpdHNfcGVyXzlpbmluZ3MKaGl0c19wZXJfOWluaW5nc1tjKDIsMyw0KV0KaGl0c19wZXJfOWluaW5nc1tjKDI6NCldCmBgYAoKYGBge3J9CiNJZiB5b3Ugd2FudCB0byBnZXQgdGhlIGxhc3QgZWxlbWVudCBvZiBwaXRjaGVzX2J5X2lubmluZ3Mgd2l0aG91dCBleHBsaWNpdGx5IHR5cGluZyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIG9mIHBpdGNoZXNfYnlfaW5uaW5ncywgbWFrZSB1c2Ugb2YgdGhlIGxlbmd0aCBmdW5jdGlvbiwgd2hpY2ggY2FsY3VsYXRlcyB0aGUgbGVuZ3RoIG9mIGEgdmVjdG9yCnBpdGNoZXNfYnlfaW5uaW5nc1tsZW5ndGgocGl0Y2hlc19ieV9pbm5pbmdzKV0KYGBgCgoKYGBge3J9CiNRdWVzdGlvbl82OkdldCB0aGUgbGFzdCBlbGVtZW50IG9mIGhpdHNfcGVyXzlpbm5pbmdzLgpoaXRzX3Blcl85aW5pbmdzWzVdCmBgYAoKCmBgYHtyfQojWW91IGNhbiBhbHNvIGV4dHJhY3QgbXVsdGlwbGUgdmFsdWVzIGZyb20gYSB2ZWN0b3IuIEZvciBpbnN0YW5jZSB0byBnZXQgdGhlIDJuZCB0aHJvdWdoIDR0aCB2YWx1ZXMgdXNlOgpwaXRjaGVzX2J5X2lubmluZ3MKcGl0Y2hlc19ieV9pbm5pbmdzW2MoMiwzLDQpXQpwaXRjaGVzX2J5X2lubmluZ3NbYygyOjQpXQpgYGAKYGBge3J9CiNWZWN0b3JzIGNhbiBhbHNvIGJlIHN0cmluZ3Mgb3IgbG9naWNhbCB2YWx1ZXMKcGxheWVyX3Bvc2l0aW9ucyA8LWMoImNhdGNoZXIiLCJwaXRjaGVyIiwiaW5maWVsZGVycyIsIm91dGZpZWxkZXJzIikKcGxheWVyX3Bvc2l0aW9ucwpgYGAKRGF0YSBGcmFtZXMKCmBgYHtyfQojSW4gc3RhdGlzdGljYWwgYXBwbGljYXRpb25zLCBkYXRhIGlzIG9mdGVuIHN0b3JlZCBhcyBhIGRhdGEgZnJhbWUsIHdoaWNoIGlzIGxpa2UgYSBzcHJlYWRzaGVldCwgd2l0aCByb3dzIGFzIG9ic2VydmF0aW9ucyBhbmQgY29sdW1ucyBhcyB2YXJpYWJsZXMKI1RvIG1hbnVhbGx5IGNyZWF0ZSBhIGRhdGEgZnJhbWUsIHVzZSB0aGUgZGF0YS5mcmFtZSgpIGZ1bmN0aW9uCmRhdGEuZnJhbWUoYm9udXMgPSBjKDIsMywxKSwjaW4gbWlsbGlvbnMKICAgICAgICAgICBhY3RpdmVfcm9zdGVyID0gYygieWVzIiwibm8iLCJ5ZXMiKSwKICAgICAgICAgICBzYWxhcnkgPSBjKDEuNSwyLjUsMSkpI2luIG1pbGxpb25zCmBgYApNb3N0IG9mdGVuIHlvdSB3aWxsIGJlIHVzaW5nIGRhdGEgZnJhbWVzIGxvYWRlZCBmcm9tIGEgZmlsZS4gRm9yIGV4YW1wbGUsIGxvYWQgdGhlIHJlc3VsdHMgb2YgYSBmYW4ncyBzdXJ2ZXkuIFRoZSBmdW5jdGlvbiBsb2FkIG9yIHJlYWQudGFibGUgY2FuIGJlIHVzZWQgZm9yIHRoaXMuCgpIb3cgdG8gTWFrZSBhIFJhbmRvbSBTYW1wbGUKCmBgYHtyfQojVG8gcmFuZG9tbHkgc2VsZWN0ICBhIHNhbXBsZSB1c2UgdGhlIGZ1bmN0aW9uIHNhbXBsZSgpLiBUaGUgZm9sbG93aW5nIGNvZGUgc2VsZWN0cyA1IG51bWJlcnMgYmV3ZWVlbiAxIGFuZCAxMCBhdCByYW5kb20gKHdpdGhvdXQgZHVwbGljYXRpb24pCnNhbXBsZSgxOjEwLCBzaXplPTUpCmBgYApUaGUgZmlyc3QgYXJndW1lbnQgZ2l2ZXMgdGhlIHZlY3RvciBvZiBkYXRhIHRvIHNlbGVjdCBlbGVtZW50cyBmb3JtClRoZSBzZWNvbmQgYXJndW1lbnQgKHNpemU9KSBnaXZlcyB0aGUgc2l6ZSBvZiB0aGUgc2FtcGxlIHRvIHNlbGVjdC4KClRha2luZyBhIHNpbXBsZSByYW5kb20gc2FtcGxlIGZyb20gYSBkYXRhIGZyYW1lIGlzIG9ubHkgc2xpZ2h0bHkgbW9yZSBjb21wbGljYXRlZCwgaGF2aW5nIHR3byBzdGVwczoKMS4gVXNlIHNhbXBsZSgpIHRvIHNlbGVjdCBhIHNhbXBsZSBvZiBzaXplIG4gZnJvbSBhIHZlY3RvciBvZiB0aGUgcm93IG51bWJlcnMgb2YgdGhlIGRhdGEgZnJhbWUuCjIuIFVzZSB0aGUgaW5kZXggb3BlcmF0b3IgWyB0byBzZWxlY3QgdGhvc2Ugcm93cyBmcm9tIHRoZSBkYXRhIGZyYW1lLgoKYGBge3J9CiNDb25zaWRlciB0aGUgZm9sbG93aW5nIGV4YW1wbGUgd2l0aCBmYWtlIGRhdGEuIEZpcnN0LCBtYWtlIHVwIGEgZGF0YSBmcmFtZSB3aXRoIHR3byBjb2x1bW5zLiAoTEVUVEVSUyBpcyBhIGNoYXJhY3RlciB2ZWN0b3Igb2YgbGVuZ3RoIDI2IHdpdGggY2FwaXRhbCBsZXR0ZXJzIGEgdG8geiBhbmQgQSB0byBaLiBMRVRURVJTIGlzIGF1dG9tYXRpY2FsbHkgZGVmaW5lZCBhbmQgcHJlLWxvYWRlZCBpbiBSKQpiYXI8LSBkYXRhLmZyYW1lKHZhcjEgPSBMRVRURVJTWzE6MTBdLCB2YXIyID0xOjEwKQojQ2hlY2sgZGF0YSBmcmFtZQpiYXIKYGBgClN1cHBvc2UgeW91IHdhbnQgdG8gc2VsZWN0IGEgcmFuZG9tIHNhbXBsZSBvZiBzaXplIDUuIEZpcnN0LCBkZWZpbmUgYSB2YXJpYWJsZSBuIHdpdGggdGhlIHNpemUgb2YgdGhlIHNhbXBsZSwgaS5lLjUKCmBgYHtyfQpuPC01Cm4KYGBgCgoKTm93LCBzZWxlY3QgYSBzYW1wbGUgb2Ygc2l6ZSA1IGZyb20gdGhlIHZlY3RvciB3aXRoIDEgdG8gMTAgKHRoZSBudW1iZXIgb2Ygcm93cyBpbiBiYXIpLiBVc2UgdGhlIGZ1bmN0aW9uIG5yb3coKSB0byBmaW5kIHRoZSBudW1iZXIgb2Ygcm93cyBpbiBiYXIgaW5zdGVhZCBvZiBtYW51YWxseSBlbnRlcmluZyB0aGF0IG51bWJlci4KCmBgYHtyfQojVXNlOnRvIGNyZWF0ZSBhIHZlY3RvciB3aXRoIGFsbCB0aGUgaW50ZWdlcnMgYmV0d2VlbiAxIGFuZCB0aGUgbnVtYmVyIG9mIHJvd3MgaW4gYmFyLgoKc2FtcGxlcm93cyA8LSBzYW1wbGUoMTpucm93KGJhciksc2l6ZT1uKQpzYW1wbGVyb3dzCmBgYAoKVGhlIHZhcmlhYmxlIHNhbXBsZXJvd3MgY29udGFpbnMgdGhlIHJvd3Mgb2YgYmFyIHdoaWNoIG1ha2UgYSByYW5kb20gc2FtcGxlIGZyb20gYWxsIHRoZSByb3dzIGluIGJhci4gRXh0cmFjdCB0aG9zZSByb3dzIGZyb20gYmFyIHdpdGgKCmBgYHtyfQojZXh0cmFjdCByb3dzCmJhcnNhbXBsZSA8LSBiYXJbc2FtcGxlcm93cywgXQpwcmludChiYXJzYW1wbGUpCmBgYApUaGUgY29kZSBhYm92ZSBjcmVhdGVzICBhIG5ldyBkYXRhICBmcmFtZSBjYWxsZWQgYmFyc2FtcGxlIHdpdGggYSByYW5kb20gc2FtcGxlIG9mIHJvd3MgZnJvbSBiYXIuIEluIGEgc2luZ2xlIGxpbmUgb2YgY29kZS4KYGBge3J9CmJhcltzYW1wbGUoMTpucm93KGJhciksbiksXQpgYGAKClVzaW5nIFRhYmxlcwoKVGhlIHRhYmxlKCljb21tYW5kIGFsbG93cyB1cyB0byBsb29rIGF0IHRhYmxlcy4gSXRzIHNpbXBsZXN0IHVzYWdlIGxvb2tzIGxpa2UgdGFibGUoeCkgd2hlcmUgeCBpcyBhIGNhdGVnb3JpY2FsICB2YXJpYWJsZS4KCkZvciBleGFtcGxlLCBhIHN1cnZleSBhc2tzIHBlb3BsZSBpZiB0aGV5IHN1cHBvcnQgdGhlIGhvbWUgdGVhbSBvciBub3QuIFRoZSBkYXRhIGlzIFllcywgTm8sIE5vLCBZZXMsIFllcwpgYGB7cn0KI1dlIGNhbiBlbnRlciB0aGlzIGludG8gUiB3aXRoIHRoZSBjKCkgY29tbWFuZCwgYW5kIHN1bW1hcml6ZSB3aXRoIHRoZSB0YWJsZSgpIGNvbW1hbmQgYXMgZm9sbG93cwp4PC1jKCJZZXMiLCJObyIsIk5vIiwiWWVzIiwiWWVzIikKdGFibGUoeCkKYGBgCk51bWVyaWNhbCBtZWFzdXJlcyBvZiBjZW50ZXIgYW5kIHNwcmVhZApTdXBwb3NlIE1MQiBUZWFtcycgQ0VPcyB5ZWFybHkgY29tcGVuc2F0aW9ucyBhcmUgc2FtcGxlZCBhbmQgdGhlIGZvbGxvd2luZyBhcmUgZm91bmQgKGluIG1pbGxpb25zKQoxMiAuNCA1IDIgNTAgOCAzIDEgNCAwLjI1CmBgYHtyfQpzYWxzPC1jKDEyLC40LDUsMiw1MCw4LDMsIDEsIDQsIDAuMjUpCiMgdGhlIGF2ZXJhZ2UKbWVhbihzYWxzKQojIHRoZSB2YXJpYW5jZQp2YXIoc2FscykKI3RoZSBzdGFuZGFyZCBkZXZpYXRpb24Kc2Qoc2FscykKI3RoZSBtZWRpYW4KbWVkaWFuKHNhbHMpCgpgYGAKVHVrZXkncyBmaXZlIG51bWJlciBzdW1tYXJ5LCB1c2VmdWwgZm9yIGJveHBsb3RzCmZpdmUgbnVtYmVyczptaW4sbG93ZXIgaGluZ2UsIG1lZGlhbiwgdXBwZXIgaGluZ2UsbWF4CmBgYHtyfQpmaXZlbnVtKHNhbHMpCiNzdW1tYXJ5IHN0YXRpc3RpY3MKc3VtbWFyeShzYWxzKQpgYGAKCkhvdyBhYm91dCB0aGUgbW9kZT8KCkluIFIgd2UgY2FuIHdyaXRlIG91ciBvd24gZnVuY3Rpb25zLCBhbmQgYSBmaXJzdCBleGFtcGxlIG9mIGEgZnVuY3Rpb24gaXMgc2hvd24gYmVsb3cgaW4gb3JkZXIgdG8gY29tcHV0ZSB0aGUgbW9kZSBvZiBhIHZlY3RvciBvZiBvYnNlcnZhdGlvbnMgeApgYGB7cn0KI0Z1bmN0aW9uIHRvIGZpbmQgdGhlIG1vZGUsIGkuZS4gbW9zdCBmcmVxdWVudCB2YWx1ZQpnZXRNb2RlIDwtZnVuY3Rpb24oeCl7CiAgdXg8LXVuaXF1ZSh4KQogIHV4W3doaWNoLm1heCh0YWJ1bGF0ZShtYXRjaCh4LCB1eCkpKV0KfQpgYGAKCkFzIGFuIGV4YW1wbGUsIHdlIGNhbiB1c2UgdGhlIGZ1bmN0aW9uIGRlZmluZWQgYWJvdmUgdG8gZmluZCB0aGUgbW9zdCBmcmVxdWVudCB2YWx1ZSBvZiB0aGUgbnVtYmVyIG9mIHBpdGNoZXNfYnlfaW5pbmdzCmBgYHtyfQojTW9zdCBmcmVxdWVudCB2YWx1ZSBpbiBwaXRjaGVzIF9ieV9pbmluZ3MKZ2V0TW9kZShwaXRjaGVzX2J5X2lubmluZ3MpCmBgYAoKYGBge3J9CiNRdWVzdGlvbl83OkZpbmQgdGhlIG1vc3QgZnJlcXVlbnQgdmFsdWUgb2YgaGl0c19wZXJfOWluaW5ncwpoaXRzX3Blcl85aW5pbmdzCmdldE1vZGUoaGl0c19wZXJfOWluaW5ncykKYGBgCmBgYHtyfQpydW5zX3Blcl85aW5pbmdzCmdldE1vZGUocnVuc19wZXJfOWluaW5ncykKYGBgCgpRdWVzdGlvbl84OlN1bW1hcml6ZSB0aGUgZm9sbG93aW5nIHN1cnZleSB3aXRoICd0YWJsZScgY29tbWFuZDoKYGBge3J9CiNXaGF0IGlzIHlvdXIgZmF2b3JpdGUgZGF5IG9mIHRoZSB3ZWVrIHRvIHdhdGNoIGJhc2ViYWxsPyBBIHRvdGFsIG9mIDEwIGZhbnMgc3VibWl0dGVkIHRoaXMgc3VydmV5LgojU2F0dXJkYXksIFNhdHVyZGF5LCBTdW5kYXksIE1vbmRheSwgU2F0dXJkYXksIFR1ZXNkYXksIFN1bmRheSwgRnJpZGF5LCBGcmlkYXksIE1vbmRheQpnYW1lX2RheTwtYygiU2F0dXJkYXkiLCAiU2F0dXJkYXkiLCAiU3VuZGF5IiwgIk1vbmRheSIsICJTYXR1cmRheSIsICJUdWVzZGF5IiwgIlN1bmRheSIsICJGcmlkYXkiLCAiRnJpZGF5IiwgIk1vbmRheSIpCmdhbWVfZGF5CmBgYApRdWVzdGlvbl85OldoYXQgaXMgdGhlIG1vc3QgZnJlcXVlbnQgYW5zd2VyIHJlY29yZGVkIGluIHRoZSBzdXJ2ZXk/IFVzZSB0aGUgZ2V0TW9kZSBmdW5jdGlvbiB0byBjb21wdXRlIHJlc3VsdHMKYGBge3J9CmdldE1vZGUoZ2FtZV9kYXkpCmBgYAoK