Mode Function
my_mode<-function(x){
unique_x<-unique(x)
tabulate_x<-tabulate(match(x,unique_x))
unique_x[tabulate_x==max(tabulate_x)]
}
my_mode(c(10,20,30,40,50,20,2222222,13,342))
[1] 20
Correlation coefficient Function
cor.coeff<-function(x,y){
avg_x<-mean(x)
avg_y<-mean(y)
nom<-sum((x-avg_x)*(y-avg_y))
ssx<-sum((x-avg_x)^2)
ssy<-sum((y-avg_y)^2)
denom<-sqrt(ssx*ssy)
r<-nom/denom
r
}
cor.coeff(c(1,2,3,4,5,6,7,8,9), c(10,20,30,40,50,20,2222222,13,342))
[1] 0.273945
Custom (Range of a vector) Function
own.range <- function(x){
n<-length(x)
for (i in 1:n){
for (j in 1:(n-1)){
if (x[j] > x[j+1]){
temp <- x[j]
x[j] <- x[j+1]
x[j+1] <- temp
}
}
}
range <- x[n]-x[1]
range
}
own.range(c(10,20,30,40,50,20,2222222,13,342))
[1] 2222212
Suppose a box contains 10 identical items and the probability of
having a defective item is 0.2.Then
i)Prob. of having no defective item ii)Find the number of defective
items in 1000 such boxes iii)Estimate the probability of containing
exactly 1 defective item iv)Estimate the probability of containing at
most 1 defective item
# Given
n <- 10 # items per box
p <- 0.2 # probability of defect
# i) Probability of no defective item
prob_0 <- dbinom(0, size = n, prob = p)
prob_0
[1] 0.1073742
# ii) Expected number of defective items in 1000 boxes
expected_defects <- 1000 * (n * p)
expected_defects
[1] 2000
# iii) Probability of exactly 1 defective item
prob_1 <- dbinom(1, size = n, prob = p)
prob_1
[1] 0.2684355
# iv) Probability of at most 1 defective item
prob_at_most_1 <- pbinom(1, size = n, prob = p)
prob_at_most_1
[1] 0.3758096
Plotting PMF and CDF of X~binomial(5,0.6)
x<-0:5
y<-dbinom(x,5,0.6)
z<-pbinom(x,5,0.6)
plot(x,y,type="h",xlab="x",ylab="f(x)",
main="PMF of X")

plot(x,z,type="s",xlab="x",ylab="F(x)",
main="CDF of X")

Log Likelihood of Bernoulli Distribution
LL.Ber<-function(x,p){
sum(x)*log(p)+(length(x)-sum(x))*log(1-p)
}
sample <- rbinom(10, size = 1, prob = 0.3)
LL.Ber(x = sample, p)
[1] -6.390319
Sum function
sum_value<-function(x){
n<-length(x)
s<-0
for(i in 1:n){
s<-s+x[i]
}
s
}
sum_value(c(10,20,30,40,50,20,2222222,13,342))
[1] 2222747
Factorial function
own.factorial<-function(n){
x<-1:n
L<-length(x)
prod<-1
for(i in 1:L){
prod<-prod*x[i]
}
prod
}
own.factorial(5)
[1] 120
Write a function that finds absolute value of a vector
bs_value<-function(x){
ifelse(x<0,-x,x)}
abs_value(c(10,20,30,40,50,20,-2222222,13,-342))
[1] 10 20 30 40 50
[6] 20 2222222 13 342
Ascending(sort) function
asc.sort <- function(x){
n<-length(x)
for (i in 1:n){
for (j in 1:(n-1)){
if (x[j] > x[j+1]){
temp <- x[j]
x[j] <- x[j+1]
x[j+1] <- temp
}
}
}
x
}
asc.sort(c(10,20,30,40,50,20,-2222222,13,-342))
[1] -2222222 -342 10 13
[5] 20 20 30 40
[9] 50
Descending(sort)function
des.sort <- function(x){
n<-length(x)
for (i in 1:n){
for (j in 1:(n-1)){
if (x[j] < x[j+1]){
temp <- x[j]
x[j] <- x[j+1]
x[j+1] <- temp
}
}
}
x
}
des.sort(c(10,20,30,40,50,20,-2222222,13,-342))
[1] 50 40 30 20
[5] 20 13 10 -342
[9] -2222222
Write a function to find maximum value of a function
max_value<-function(x){
n<-length(x)
for(i in 2:n){
if(x[1]<x[i]){
x[1]<-x[i]
}
}
x[1]
}
max_value(c(10,20,30,40,50,20,-2222222,13,-342))
[1] 50
Write a function that counts length without missing value
non.na.count<-function(x){
i=1
count=0
n<- length(x)
while (i<=n){
if (!is.na(x[i])){
count<-count+1
}
i=i+1
}
count
}
non.na.count(c(NA,20,30,40,50,NA,20,-2222222,13,-342))
[1] 8
Let X1,…,Xn be a sequence of n random integers between 1 and 10 and
let Yn=ΣXi.Find n so that max(Yn)<100
max100<- function(x){
set.seed(209)
sum=0
i=1
n=length(x)
while (sum<100){
sum<-sum+x[i]
i<-i+1
}
cat("n =",i,"\n")
cat("Sum =",sum)
}
max100(sample(1:10, 100, replace=TRUE))
n = 19
Sum = 100
Create a user-defined function to compute the mean of numeric
variables only and apply it to the birthwt dataset.
data.mean<-function(x){
if(is.numeric(x)==T){
mean(x)}
else{
NA
}
}
library(MASS)
head(birthwt)
attach(birthwt)
birthwt$low<-as.factor(birthwt$low)
birthwt$race<-as.factor(birthwt$race)
birthwt$smoke<-as.factor(birthwt$smoke)
birthwt$ui<-as.factor(birthwt$ui)
birthwt$ht<-as.factor(birthwt$ht)
sapply(birthwt,data.mean)
low age lwt
NA 23.2380952 129.8148148
race smoke ptl
NA NA 0.1957672
ht ui ftv
NA NA 0.7936508
bwt
2944.5873016
INC_2024-1
Part-1
"(a)"
[1] "(a)"
x <- seq(3, 6, by = 0.1)
v <- exp(x) * cos(x^2)
sum_v <- sum(v)
sum_v
[1] -339.2342
"(b)"
[1] "(b)"
# y<-rnorm(15, 0, 1)
n <- length(y)
avg_y <- mean(y)
for (i in 1:n){
v <- sqrt(abs(y - avg_y))
}
print(v)
[1] 1.1653621 0.8584013 0.9961283 0.9553444
[5] 0.5351151 1.0487096 1.1013675 0.5778597
[9] 0.4415788 1.2865604 0.6413056 0.7041377
[13] 1.0721042 0.8403968 0.4679993
avg_v <- mean(v)
print(avg_v)
[1] 0.8461581
"(c)"
[1] "(c)"
# v <- c(5.2, 7.0, 9.1, 3.8, 7.5, 5.9, 6.5)
picked <- v[v < 6]
indices <- which(v > 6 & v < 8)
print(picked)
[1] 1.1653621 0.8584013 0.9961283 0.9553444
[5] 0.5351151 1.0487096 1.1013675 0.5778597
[9] 0.4415788 1.2865604 0.6413056 0.7041377
[13] 1.0721042 0.8403968 0.4679993
print(indices)
integer(0)
"(d)"
[1] "(d)"
int.v <- round(v)
sum(int.v %% 3 == 0)
[1] 2
"(e)"
[1] "(e)"
my.means <- function(x){
am <- mean(x)
gm <- exp(mean(log(x[x>0]))) # GM requires positive values
hm <- length(x) / sum(1/x[x!=0])
c(AM = am, GM = gm, HM = hm)
}
"(f)"
[1] "(f)"
my.means(v)
AM GM HM
0.8461581 0.8023689 0.7569923
Part-2
# (a)
set.seed(75)
x <- sample(1:100, 60, replace = TRUE)
M <- matrix(x, nrow = 6, ncol = 10, byrow = TRUE)
rowtotals <- rowSums(M)
rowtotals
[1] 565 623 392 506 539 542
# (b)
count.over <- function(vec, k) {
sum(vec > k)
}
# (c)
apply(M, MARGIN = 1, count.over, k = 4) # 1 means by row, 2 means by column
[1] 10 10 10 10 9 9
Part-3
# -----------------------------
# Simulate sample (given)
# -----------------------------
"(a)"
[1] "(a)"
set.seed(123)
Y <- rbinom(2000, size = 15, prob = 0.25)
# (i) Estimated P(2 < Y < 10)
est_prob <- mean(Y > 2 & Y < 10)
est_prob
[1] 0.7665
# (ii)
quantile(Y, 0.75)
75%
5
"(b)"
[1] "(b)"
# (i) Actual P(2 < Y < 10)
actual_prob <- pbinom(9, 15, 0.25) - pbinom(2, 15, 0.25)
actual_prob
[1] 0.7631172
# (ii) Actual Q3 from the exact distribution
actual_Q3 <- qbinom(0.75, 15, 0.25)
actual_Q3
[1] 5
INC_2023-1
Part 1
- Create a vector x that stores the sequence {1.1, 1.5, 1.9, …,
111.1}
x <- seq(1.1,111.1, by=0.4)
- Create a vector y where y=logx
y <- log(x)
- Find the number of observations in y
n <- length(y)
n
[1] 276
- Create vector y12 with every 12th element
y12 <- y[seq(12, length(y), by = 12)]
- Display the positions (indices) of the elements in vector Y that lie
between 0.5 and 2.
indices <- which((y > 0.5) & (y < 2))
print(indices)
[1] 3 4 5 6 7 8 9 10 11 12 13 14 15
[14] 16
- Sum of elements in y that are below 3
sum_below_3 <- sum(y[y < 3])
sum_below_3
[1] 103.0407
Part 2 (regression context)
'(a)'
[1] "(a)"
# Set seed for reproducibility
set.seed(123)
# Generate data
n <- 1000
# X ~ N(0, 4) (variance = 4, so sd = 2)
X <- rnorm(n, mean = 0, sd = sqrt(4))
# ε ~ N(10, 2) (variance = 2, so sd = sqrt(2))
# Note: This error term with mean 10 seems unusual for regression
e <- rnorm(n, mean = 0, sd = sqrt(2))
# Generate Y = 0.5 + 0.8*X + e
Y <- 0.5 + 0.8 * X + e
# Store the values of X as x and Y as y, as requested
x <- X
y <- Y
'(b)'
[1] "(b)"
# 1. Create matrix D:
# First column: constant 1 (1000 rows)
# Second column: vector x from part (a)
D <- matrix(c(rep(1, n), x), ncol = 2)
# 2. Create column matrix M using vector y from part (a)
M <- matrix(y, ncol = 1)
'(C)'
[1] "(C)"
# 1. Calculate b = (D^T D)^{-1} D^T M
D_transpose <- t(D)
D_transpose_D <- D_transpose %*% D
D_transpose_M <- D_transpose %*% M
# Calculate inverse and b
D_transpose_D_inv <- solve(D_transpose_D)
b <- D_transpose_D_inv %*% D_transpose_M
print(b)
[,1]
[1,] 0.5580467
[2,] 0.8622588
# 2. True parameter vector B from part (a)
B <- c(0.5, 0.8)
print(B)
[1] 0.5 0.8
# 3. Calculate absolute differences |b - B|
abs_difference <- abs(b-B)
cat("Absolute differences:\n")
Absolute differences:
print(abs_difference)
[,1]
[1,] 0.05804673
[2,] 0.06225884
LS0tDQp0aXRsZTogIjJEZWMiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KIyMjIE1lZGlhbiBGdW5jdGlvbg0KYGBge3J9DQptZWRfdmFsIDwtIGZ1bmN0aW9uKHgpew0KICBuIDwtIGxlbmd0aCh4KQ0KICB5IDwtIHNvcnQoeCkNCiAgaWYgKG4lJTI9PTEpew0KICAgIG1lZCA8LSB5WyhuKzEpLzJdDQogIH0NCiAgZWxzZXsNCiAgICBtZWQgPC0gbWVhbihjKHlbbi8yXSwgeVsobi8yKSsxXSkpDQogIH0NCiAgbWVkDQp9DQpgYGANCg0KYGBge3J9DQptZWRfdmFsKGMoMTAsMjAsMzAsNDAsNTAsMjAsMjIyMjIyMiwxMywzNDIpKQ0KYGBgDQojIyMgTW9kZSBGdW5jdGlvbg0KYGBge3J9DQpteV9tb2RlPC1mdW5jdGlvbih4KXsNCiAgdW5pcXVlX3g8LXVuaXF1ZSh4KQ0KICB0YWJ1bGF0ZV94PC10YWJ1bGF0ZShtYXRjaCh4LHVuaXF1ZV94KSkNCiAgdW5pcXVlX3hbdGFidWxhdGVfeD09bWF4KHRhYnVsYXRlX3gpXQ0KfQ0KbXlfbW9kZShjKDEwLDIwLDMwLDQwLDUwLDIwLDIyMjIyMjIsMTMsMzQyKSkNCmBgYA0KIyMjIENvcnJlbGF0aW9uIGNvZWZmaWNpZW50IEZ1bmN0aW9uDQpgYGB7cn0NCmNvci5jb2VmZjwtZnVuY3Rpb24oeCx5KXsNCiAgYXZnX3g8LW1lYW4oeCkNCiAgYXZnX3k8LW1lYW4oeSkNCiAgbm9tPC1zdW0oKHgtYXZnX3gpKih5LWF2Z195KSkNCiAgc3N4PC1zdW0oKHgtYXZnX3gpXjIpDQogIHNzeTwtc3VtKCh5LWF2Z195KV4yKQ0KICBkZW5vbTwtc3FydChzc3gqc3N5KQ0KICByPC1ub20vZGVub20NCiAgcg0KfQ0KDQpjb3IuY29lZmYoYygxLDIsMyw0LDUsNiw3LDgsOSksIGMoMTAsMjAsMzAsNDAsNTAsMjAsMjIyMjIyMiwxMywzNDIpKQ0KYGBgDQojIyMgQ3VzdG9tIChSYW5nZSBvZiBhIHZlY3RvcikgRnVuY3Rpb24NCmBgYHtyfQ0Kb3duLnJhbmdlIDwtIGZ1bmN0aW9uKHgpew0KICBuPC1sZW5ndGgoeCkNCiAgZm9yIChpIGluIDE6bil7DQogICAgZm9yIChqIGluIDE6KG4tMSkpew0KICAgICAgaWYgKHhbal0gPiB4W2orMV0pew0KICAgICAgICB0ZW1wIDwtIHhbal0NCiAgICAgICAgeFtqXSA8LSB4W2orMV0NCiAgICAgICAgeFtqKzFdIDwtIHRlbXANCiAgICAgIH0NCiAgICB9DQogIH0NCiAgcmFuZ2UgPC0geFtuXS14WzFdDQogIHJhbmdlDQp9DQoNCm93bi5yYW5nZShjKDEwLDIwLDMwLDQwLDUwLDIwLDIyMjIyMjIsMTMsMzQyKSkNCmBgYA0KU3VwcG9zZSBhIGJveCBjb250YWlucyAxMCBpZGVudGljYWwNCml0ZW1zIGFuZCB0aGUgcHJvYmFiaWxpdHkgb2YgaGF2aW5nIGENCmRlZmVjdGl2ZSBpdGVtIGlzIDAuMi5UaGVuDQoNCmkpUHJvYi4gb2YgaGF2aW5nIG5vIGRlZmVjdGl2ZSBpdGVtDQppaSlGaW5kIHRoZSBudW1iZXIgb2YgZGVmZWN0aXZlIGl0ZW1zDQppbiAxMDAwIHN1Y2ggYm94ZXMNCmlpaSlFc3RpbWF0ZSB0aGUgcHJvYmFiaWxpdHkgb2YNCmNvbnRhaW5pbmcgZXhhY3RseSAxIGRlZmVjdGl2ZSBpdGVtDQppdilFc3RpbWF0ZSB0aGUgcHJvYmFiaWxpdHkgb2YNCmNvbnRhaW5pbmcgYXQgbW9zdCAxIGRlZmVjdGl2ZSBpdGVtDQpgYGB7cn0NCiMgR2l2ZW4NCm4gPC0gMTAgICAgICAgICMgaXRlbXMgcGVyIGJveA0KcCA8LSAwLjIgICAgICAgIyBwcm9iYWJpbGl0eSBvZiBkZWZlY3QNCg0KIyBpKSBQcm9iYWJpbGl0eSBvZiBubyBkZWZlY3RpdmUgaXRlbQ0KcHJvYl8wIDwtIGRiaW5vbSgwLCBzaXplID0gbiwgcHJvYiA9IHApDQpwcm9iXzANCg0KIyBpaSkgRXhwZWN0ZWQgbnVtYmVyIG9mIGRlZmVjdGl2ZSBpdGVtcyBpbiAxMDAwIGJveGVzDQpleHBlY3RlZF9kZWZlY3RzIDwtIDEwMDAgKiAobiAqIHApDQpleHBlY3RlZF9kZWZlY3RzDQoNCiMgaWlpKSBQcm9iYWJpbGl0eSBvZiBleGFjdGx5IDEgZGVmZWN0aXZlIGl0ZW0NCnByb2JfMSA8LSBkYmlub20oMSwgc2l6ZSA9IG4sIHByb2IgPSBwKQ0KcHJvYl8xDQoNCiMgaXYpIFByb2JhYmlsaXR5IG9mIGF0IG1vc3QgMSBkZWZlY3RpdmUgaXRlbQ0KcHJvYl9hdF9tb3N0XzEgPC0gcGJpbm9tKDEsIHNpemUgPSBuLCBwcm9iID0gcCkNCnByb2JfYXRfbW9zdF8xDQoNCmBgYA0KIyMjIFBsb3R0aW5nIFBNRiBhbmQgQ0RGIG9mIFh+Ymlub21pYWwoNSwwLjYpDQpgYGB7cn0NCng8LTA6NQ0KeTwtZGJpbm9tKHgsNSwwLjYpDQp6PC1wYmlub20oeCw1LDAuNikNCnBsb3QoeCx5LHR5cGU9ImgiLHhsYWI9IngiLHlsYWI9ImYoeCkiLA0KICAgICBtYWluPSJQTUYgb2YgWCIpDQpwbG90KHgseix0eXBlPSJzIix4bGFiPSJ4Iix5bGFiPSJGKHgpIiwNCiAgICAgbWFpbj0iQ0RGIG9mIFgiKQ0KYGBgDQojIyMgTG9nIExpa2VsaWhvb2Qgb2YgQmVybm91bGxpIERpc3RyaWJ1dGlvbg0KYGBge3J9DQpMTC5CZXI8LWZ1bmN0aW9uKHgscCl7DQogIHN1bSh4KSpsb2cocCkrKGxlbmd0aCh4KS1zdW0oeCkpKmxvZygxLXApDQp9DQoNCnNhbXBsZSA8LSByYmlub20oMTAsIHNpemUgPSAxLCBwcm9iID0gMC4zKQ0KTEwuQmVyKHggPSBzYW1wbGUsIHApDQpgYGANCiMjIyBTdW0gZnVuY3Rpb24NCmBgYHtyfQ0Kc3VtX3ZhbHVlPC1mdW5jdGlvbih4KXsNCiAgbjwtbGVuZ3RoKHgpDQogIHM8LTANCiAgZm9yKGkgaW4gMTpuKXsNCiAgICBzPC1zK3hbaV0NCiAgfQ0KICBzDQp9DQoNCnN1bV92YWx1ZShjKDEwLDIwLDMwLDQwLDUwLDIwLDIyMjIyMjIsMTMsMzQyKSkNCmBgYA0KIyMjIEZhY3RvcmlhbCBmdW5jdGlvbg0KYGBge3J9DQpvd24uZmFjdG9yaWFsPC1mdW5jdGlvbihuKXsNCng8LTE6bg0KTDwtbGVuZ3RoKHgpDQpwcm9kPC0xDQpmb3IoaSBpbiAxOkwpew0KcHJvZDwtcHJvZCp4W2ldDQp9DQpwcm9kDQp9DQoNCm93bi5mYWN0b3JpYWwoNSkNCmBgYA0KIyMjIFdyaXRlIGEgZnVuY3Rpb24gdGhhdCBmaW5kcyBhYnNvbHV0ZSB2YWx1ZSBvZiBhIHZlY3Rvcg0KYGBge3J9DQpic192YWx1ZTwtZnVuY3Rpb24oeCl7DQogIGlmZWxzZSh4PDAsLXgseCl9DQphYnNfdmFsdWUoYygxMCwyMCwzMCw0MCw1MCwyMCwtMjIyMjIyMiwxMywtMzQyKSkNCmBgYA0KIyMjIEFzY2VuZGluZyhzb3J0KSBmdW5jdGlvbg0KYGBge3J9DQphc2Muc29ydCA8LSBmdW5jdGlvbih4KXsNCiAgbjwtbGVuZ3RoKHgpDQogIGZvciAoaSBpbiAxOm4pew0KICAgIGZvciAoaiBpbiAxOihuLTEpKXsNCiAgICAgIGlmICh4W2pdID4geFtqKzFdKXsNCiAgICAgICAgdGVtcCA8LSB4W2pdDQogICAgICAgIHhbal0gPC0geFtqKzFdDQogICAgICAgIHhbaisxXSA8LSB0ZW1wDQogICAgICB9DQogICAgfQ0KICB9DQogIHgNCn0NCg0KYXNjLnNvcnQoYygxMCwyMCwzMCw0MCw1MCwyMCwtMjIyMjIyMiwxMywtMzQyKSkNCmBgYA0KIyMjIERlc2NlbmRpbmcoc29ydClmdW5jdGlvbg0KYGBge3J9DQpkZXMuc29ydCA8LSBmdW5jdGlvbih4KXsNCiAgbjwtbGVuZ3RoKHgpDQogIGZvciAoaSBpbiAxOm4pew0KICAgIGZvciAoaiBpbiAxOihuLTEpKXsNCiAgICAgIGlmICh4W2pdIDwgeFtqKzFdKXsNCiAgICAgICAgdGVtcCA8LSB4W2pdDQogICAgICAgIHhbal0gPC0geFtqKzFdDQogICAgICAgIHhbaisxXSA8LSB0ZW1wDQogICAgICB9DQogICAgfQ0KICB9DQogIHgNCn0NCg0KZGVzLnNvcnQoYygxMCwyMCwzMCw0MCw1MCwyMCwtMjIyMjIyMiwxMywtMzQyKSkNCmBgYA0KIyMjIFdyaXRlIGEgZnVuY3Rpb24gdG8gZmluZCBtYXhpbXVtIHZhbHVlIG9mIGEgZnVuY3Rpb24NCmBgYHtyfQ0KbWF4X3ZhbHVlPC1mdW5jdGlvbih4KXsNCiAgbjwtbGVuZ3RoKHgpDQogIGZvcihpIGluIDI6bil7DQogICAgaWYoeFsxXTx4W2ldKXsNCiAgICAgIHhbMV08LXhbaV0NCiAgICB9DQogIH0NCiAgeFsxXQ0KfQ0KDQptYXhfdmFsdWUoYygxMCwyMCwzMCw0MCw1MCwyMCwtMjIyMjIyMiwxMywtMzQyKSkNCmBgYA0KIyMjIFdyaXRlIGEgZnVuY3Rpb24gdGhhdCBjb3VudHMgbGVuZ3RoIHdpdGhvdXQgbWlzc2luZyB2YWx1ZQ0KYGBge3J9DQpub24ubmEuY291bnQ8LWZ1bmN0aW9uKHgpew0KICBpPTENCiAgY291bnQ9MA0KICBuPC0gbGVuZ3RoKHgpDQogIHdoaWxlIChpPD1uKXsNCiAgICBpZiAoIWlzLm5hKHhbaV0pKXsNCiAgICAgIGNvdW50PC1jb3VudCsxDQogICAgfQ0KICAgIGk9aSsxDQogIH0NCiAgY291bnQgDQp9DQoNCm5vbi5uYS5jb3VudChjKE5BLDIwLDMwLDQwLDUwLE5BLDIwLC0yMjIyMjIyLDEzLC0zNDIpKQ0KYGBgDQpMZXQgWDEsLi4uLFhuIGJlIGEgc2VxdWVuY2Ugb2YgbiByYW5kb20NCmludGVnZXJzIGJldHdlZW4gMSBhbmQgMTAgYW5kIGxldA0KWW49zqNYaS5GaW5kIG4gc28gdGhhdCBtYXgoWW4pPDEwMA0KYGBge3J9DQptYXgxMDA8LSBmdW5jdGlvbih4KXsNCiAgc2V0LnNlZWQoMjA5KQ0KICBzdW09MA0KICBpPTENCiAgbj1sZW5ndGgoeCkNCiAgd2hpbGUgKHN1bTwxMDApew0KICAgIHN1bTwtc3VtK3hbaV0NCiAgICBpPC1pKzENCiAgfQ0KICBjYXQoIm4gPSIsaSwiXG4iKQ0KICBjYXQoIlN1bSA9IixzdW0pDQp9DQoNCm1heDEwMChzYW1wbGUoMToxMCwgMTAwLCByZXBsYWNlPVRSVUUpKQ0KYGBgDQpDcmVhdGUgYSB1c2VyLWRlZmluZWQgZnVuY3Rpb24gdG8gY29tcHV0ZSB0aGUgbWVhbiBvZiBudW1lcmljIHZhcmlhYmxlcyBvbmx5IGFuZCBhcHBseSBpdCB0byB0aGUgYmlydGh3dCBkYXRhc2V0Lg0KYGBge3J9DQpkYXRhLm1lYW48LWZ1bmN0aW9uKHgpew0KICBpZihpcy5udW1lcmljKHgpPT1UKXsNCiAgICBtZWFuKHgpfQ0KICBlbHNlew0KICAgIE5BDQogIH0NCn0NCmxpYnJhcnkoTUFTUykNCmhlYWQoYmlydGh3dCkNCmF0dGFjaChiaXJ0aHd0KQ0KYmlydGh3dCRsb3c8LWFzLmZhY3RvcihiaXJ0aHd0JGxvdykNCmJpcnRod3QkcmFjZTwtYXMuZmFjdG9yKGJpcnRod3QkcmFjZSkNCmJpcnRod3Qkc21va2U8LWFzLmZhY3RvcihiaXJ0aHd0JHNtb2tlKQ0KYmlydGh3dCR1aTwtYXMuZmFjdG9yKGJpcnRod3QkdWkpDQpiaXJ0aHd0JGh0PC1hcy5mYWN0b3IoYmlydGh3dCRodCkNCnNhcHBseShiaXJ0aHd0LGRhdGEubWVhbikNCg0KYGBgDQojIElOQ18yMDI0LTENCg0KIyMjIFBhcnQtMQ0KYGBge3J9DQoiKGEpIg0KeCA8LSBzZXEoMywgNiwgYnkgPSAwLjEpDQp2IDwtIGV4cCh4KSAqIGNvcyh4XjIpDQpzdW1fdiA8LSBzdW0odikNCnN1bV92DQoNCiIoYikiDQojIHk8LXJub3JtKDE1LCAwLCAxKQ0KbiA8LSBsZW5ndGgoeSkNCmF2Z195IDwtIG1lYW4oeSkNCmZvciAoaSBpbiAxOm4pew0KICB2IDwtIHNxcnQoYWJzKHkgLSBhdmdfeSkpDQp9DQpwcmludCh2KQ0KYXZnX3YgPC0gbWVhbih2KQ0KcHJpbnQoYXZnX3YpDQoNCg0KIihjKSINCiMgdiA8LSBjKDUuMiwgNy4wLCA5LjEsIDMuOCwgNy41LCA1LjksIDYuNSkNCnBpY2tlZCA8LSB2W3YgPCA2XQ0KaW5kaWNlcyA8LSB3aGljaCh2ID4gNiAmIHYgPCA4KQ0KcHJpbnQocGlja2VkKQ0KcHJpbnQoaW5kaWNlcykNCg0KIihkKSINCmludC52IDwtIHJvdW5kKHYpDQpzdW0oaW50LnYgJSUgMyA9PSAwKQ0KDQoiKGUpIg0KbXkubWVhbnMgPC0gZnVuY3Rpb24oeCl7DQogIGFtIDwtIG1lYW4oeCkNCiAgZ20gPC0gZXhwKG1lYW4obG9nKHhbeD4wXSkpKSAgICMgR00gcmVxdWlyZXMgcG9zaXRpdmUgdmFsdWVzDQogIGhtIDwtIGxlbmd0aCh4KSAvIHN1bSgxL3hbeCE9MF0pDQogIGMoQU0gPSBhbSwgR00gPSBnbSwgSE0gPSBobSkNCn0NCg0KIihmKSINCm15Lm1lYW5zKHYpDQpgYGANCiMjIyBQYXJ0LTINCmBgYHtyfQ0KIyAoYSkNCnNldC5zZWVkKDc1KQ0KeCA8LSBzYW1wbGUoMToxMDAsIDYwLCByZXBsYWNlID0gVFJVRSkNCk0gPC0gbWF0cml4KHgsIG5yb3cgPSA2LCBuY29sID0gMTAsIGJ5cm93ID0gVFJVRSkNCnJvd3RvdGFscyA8LSByb3dTdW1zKE0pDQpyb3d0b3RhbHMNCg0KIyAoYikNCmNvdW50Lm92ZXIgPC0gZnVuY3Rpb24odmVjLCBrKSB7DQogIHN1bSh2ZWMgPiBrKQ0KfQ0KDQojIChjKQ0KYXBwbHkoTSwgTUFSR0lOID0gMSwgY291bnQub3ZlciwgayA9IDQpICMgMSBtZWFucyBieSByb3csIDIgbWVhbnMgYnkgY29sdW1uDQpgYGANCiMjIyBQYXJ0LTMNCmBgYHtyfQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyBTaW11bGF0ZSBzYW1wbGUgKGdpdmVuKQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIihhKSINCnNldC5zZWVkKDEyMykNClkgPC0gcmJpbm9tKDIwMDAsIHNpemUgPSAxNSwgcHJvYiA9IDAuMjUpDQoNCiMgKGkpIEVzdGltYXRlZCBQKDIgPCBZIDwgMTApDQplc3RfcHJvYiA8LSBtZWFuKFkgPiAyICYgWSA8IDEwKQ0KZXN0X3Byb2INCiMgKGlpKQ0KcXVhbnRpbGUoWSwgMC43NSkNCg0KIihiKSINCg0KIyAoaSkgQWN0dWFsIFAoMiA8IFkgPCAxMCkNCmFjdHVhbF9wcm9iIDwtIHBiaW5vbSg5LCAxNSwgMC4yNSkgLSBwYmlub20oMiwgMTUsIDAuMjUpDQphY3R1YWxfcHJvYg0KDQojIChpaSkgQWN0dWFsIFEzIGZyb20gdGhlIGV4YWN0IGRpc3RyaWJ1dGlvbg0KYWN0dWFsX1EzIDwtIHFiaW5vbSgwLjc1LCAxNSwgMC4yNSkNCmFjdHVhbF9RMw0KDQpgYGANCiMgSU5DXzIwMjMtMQ0KIyMjIFBhcnQgMQ0KKGEpIENyZWF0ZSBhIHZlY3RvciB4IHRoYXQgc3RvcmVzIHRoZSBzZXF1ZW5jZSB7MS4xLCAxLjUsIDEuOSwgLi4uLCAxMTEuMX0NCmBgYHtyfQ0KeCA8LSBzZXEoMS4xLDExMS4xLCBieT0wLjQpDQpgYGANCihiKSBDcmVhdGUgYSB2ZWN0b3IgeSB3aGVyZSB5PWxvZ3gNCmBgYHtyfQ0KeSA8LSBsb2coeCkNCg0KYGBgDQooYykgRmluZCB0aGUgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyBpbiB5DQpgYGB7cn0NCm4gPC0gbGVuZ3RoKHkpDQpuDQpgYGANCihkKSBDcmVhdGUgdmVjdG9yIHkxMiB3aXRoIGV2ZXJ5IDEydGggZWxlbWVudA0KYGBge3J9DQp5MTIgPC0geVtzZXEoMTIsIGxlbmd0aCh5KSwgYnkgPSAxMildDQpgYGANCihlKSBEaXNwbGF5IHRoZSBwb3NpdGlvbnMgKGluZGljZXMpIG9mIHRoZSBlbGVtZW50cyBpbiB2ZWN0b3IgWSB0aGF0IGxpZSBiZXR3ZWVuIDAuNSBhbmQgMi4NCmBgYHtyfQ0KaW5kaWNlcyA8LSB3aGljaCgoeSA+IDAuNSkgJiAoeSA8IDIpKQ0KcHJpbnQoaW5kaWNlcykNCmBgYA0KKGYpIFN1bSBvZiBlbGVtZW50cyBpbiB5IHRoYXQgYXJlIGJlbG93IDMNCmBgYHtyfQ0Kc3VtX2JlbG93XzMgPC0gc3VtKHlbeSA8IDNdKQ0Kc3VtX2JlbG93XzMNCmBgYA0KIyMjIFBhcnQgMiAocmVncmVzc2lvbiBjb250ZXh0KQ0KYGBge3J9DQonKGEpJw0KIyBTZXQgc2VlZCBmb3IgcmVwcm9kdWNpYmlsaXR5DQpzZXQuc2VlZCgxMjMpDQoNCiMgR2VuZXJhdGUgZGF0YQ0KbiA8LSAxMDAwDQoNCiMgWCB+IE4oMCwgNCkgKHZhcmlhbmNlID0gNCwgc28gc2QgPSAyKQ0KWCA8LSBybm9ybShuLCBtZWFuID0gMCwgc2QgPSBzcXJ0KDQpKQ0KDQojIM61IH4gTigxMCwgMikgKHZhcmlhbmNlID0gMiwgc28gc2QgPSBzcXJ0KDIpKQ0KIyBOb3RlOiBUaGlzIGVycm9yIHRlcm0gd2l0aCBtZWFuIDEwIHNlZW1zIHVudXN1YWwgZm9yIHJlZ3Jlc3Npb24NCmUgPC0gcm5vcm0obiwgbWVhbiA9IDAsIHNkID0gc3FydCgyKSkNCg0KIyBHZW5lcmF0ZSBZID0gMC41ICsgMC44KlggKyBlDQpZIDwtIDAuNSArIDAuOCAqIFggKyBlDQoNCiMgU3RvcmUgdGhlIHZhbHVlcyBvZiBYIGFzIHggYW5kIFkgYXMgeSwgYXMgcmVxdWVzdGVkDQp4IDwtIFgNCnkgPC0gWQ0KYGBgDQpgYGB7cn0NCicoYiknDQojIDEuIENyZWF0ZSBtYXRyaXggRDoNCiMgRmlyc3QgY29sdW1uOiBjb25zdGFudCAxICgxMDAwIHJvd3MpDQojIFNlY29uZCBjb2x1bW46IHZlY3RvciB4IGZyb20gcGFydCAoYSkNCkQgPC0gbWF0cml4KGMocmVwKDEsIG4pLCB4KSwgbmNvbCA9IDIpDQoNCiMgMi4gQ3JlYXRlIGNvbHVtbiBtYXRyaXggTSB1c2luZyB2ZWN0b3IgeSBmcm9tIHBhcnQgKGEpDQpNIDwtIG1hdHJpeCh5LCBuY29sID0gMSkNCmBgYA0KYGBge3J9DQonKEMpJw0KIyAxLiBDYWxjdWxhdGUgYiA9IChEXlQgRCleey0xfSBEXlQgTQ0KRF90cmFuc3Bvc2UgPC0gdChEKQ0KRF90cmFuc3Bvc2VfRCA8LSBEX3RyYW5zcG9zZSAlKiUgRA0KRF90cmFuc3Bvc2VfTSA8LSBEX3RyYW5zcG9zZSAlKiUgTQ0KDQojIENhbGN1bGF0ZSBpbnZlcnNlIGFuZCBiDQpEX3RyYW5zcG9zZV9EX2ludiA8LSBzb2x2ZShEX3RyYW5zcG9zZV9EKQ0KYiA8LSBEX3RyYW5zcG9zZV9EX2ludiAlKiUgRF90cmFuc3Bvc2VfTQ0KcHJpbnQoYikNCiMgMi4gVHJ1ZSBwYXJhbWV0ZXIgdmVjdG9yIEIgZnJvbSBwYXJ0IChhKQ0KQiA8LSBjKDAuNSwgMC44KQ0KcHJpbnQoQikNCg0KIyAzLiBDYWxjdWxhdGUgYWJzb2x1dGUgZGlmZmVyZW5jZXMgfGIgLSBCfA0KYWJzX2RpZmZlcmVuY2UgPC0gYWJzKGItQikNCg0KY2F0KCJBYnNvbHV0ZSBkaWZmZXJlbmNlczpcbiIpDQpwcmludChhYnNfZGlmZmVyZW5jZSkNCmBgYA0KDQoNCg0KDQoNCg==