Ejercicio 10

library("ISLR")
library("MASS")
library("class")
set.seed(0)

a)

Direction <- Weekly$Direction
Weekly$Direction <- NULL
Weekly$NumericDirection <- as.numeric(Direction)  
Weekly$NumericDirection[Weekly$NumericDirection == 1] <- -1 
Weekly$NumericDirection[Weekly$NumericDirection == 2] <- +1  
Weekly.cor <- cor(Weekly)

b)

Weekly$NumericDirection <- NULL
Weekly$Direction <- Direction
five_lag_model <- glm(Direction ~ Lag1 + Lag2 + Lag3 + Lag4 + Lag5 + Volume, data = Weekly, family = binomial)
summary(five_lag_model)

Call:
glm(formula = Direction ~ Lag1 + Lag2 + Lag3 + Lag4 + Lag5 + 
    Volume, family = binomial, data = Weekly)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-1.6949  -1.2565   0.9913   1.0849   1.4579  

Coefficients:
            Estimate Std. Error z value Pr(>|z|)   
(Intercept)  0.26686    0.08593   3.106   0.0019 **
Lag1        -0.04127    0.02641  -1.563   0.1181   
Lag2         0.05844    0.02686   2.175   0.0296 * 
Lag3        -0.01606    0.02666  -0.602   0.5469   
Lag4        -0.02779    0.02646  -1.050   0.2937   
Lag5        -0.01447    0.02638  -0.549   0.5833   
Volume      -0.02274    0.03690  -0.616   0.5377   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 1496.2  on 1088  degrees of freedom
Residual deviance: 1486.4  on 1082  degrees of freedom
AIC: 1500.4

Number of Fisher Scoring iterations: 4
contrasts(Weekly$Direction)
     Up
Down  0
Up    1

c)

p_hat <- predict(five_lag_model, newdata = Weekly, type = "response")
y_hat <- rep("Down", length(p_hat))
y_hat[p_hat > 0.5] <- "Up"
CM <- table(predicted = y_hat, truth = Weekly$Direction)
CM
         truth
predicted Down  Up
     Down   54  48
     Up    430 557
sprintf("LR (all features): overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "LR (all features): overall fraction correct=   0.561065"

d)

Weekly.train <- (Weekly$Year >= 1990) & (Weekly$Year <= 2008) 
Weekly.test <- (Weekly$Year >= 2009)  # our testing set 
lag2_model <- glm(Direction ~ Lag2, data = Weekly, family = binomial, subset = Weekly.train)
p_hat <- predict(lag2_model, newdata = Weekly[Weekly.test, ], type = "response")
y_hat <- rep("Down", length(p_hat))
y_hat[p_hat > 0.5] <- "Up"
CM <- table(predicted = y_hat, truth = Weekly[Weekly.test, ]$Direction)
CM
         truth
predicted Down Up
     Down    9  5
     Up     34 56
sprintf("LR (only Lag2): overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "LR (only Lag2): overall fraction correct=   0.625000"

e)

lda.fit <- lda(Direction ~ Lag2, data = Weekly, subset = Weekly.train)
lda.predict <- predict(lda.fit, newdata = Weekly[Weekly.test, ])
CM <- table(predicted = lda.predict$class, truth = Weekly[Weekly.test, ]$Direction)
CM
         truth
predicted Down Up
     Down    9  5
     Up     34 56
sprintf("LDA (only Lag2): overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "LDA (only Lag2): overall fraction correct=   0.625000"

f)

qda.fit <- qda(Direction ~ Lag2, data = Weekly, subset = Weekly.train)
qda.predict <- predict(qda.fit, newdata = Weekly[Weekly.test, ])
CM <- table(predicted = qda.predict$class, truth = Weekly[Weekly.test, ]$Direction)
CM
         truth
predicted Down Up
     Down    0  0
     Up     43 61
sprintf("QDA (only Lag2): overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "QDA (only Lag2): overall fraction correct=   0.586538"

g)

X.train <- data.frame(Lag2 = Weekly[Weekly.train, ]$Lag2)
Y.train <- Weekly[Weekly.train, ]$Direction
X.test <- data.frame(Lag2 = Weekly[Weekly.test, ]$Lag2)
y_hat_k_1 <- knn(X.train, X.test, Y.train, k = 1)
CM <- table(predicted = y_hat_k_1, truth = Weekly[Weekly.test, ]$Direction)
CM
         truth
predicted Down Up
     Down   21 29
     Up     22 32
sprintf("KNN (k=1): overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "KNN (k=1): overall fraction correct=   0.509615"
y_hat_k_3 <- knn(X.train, X.test, Y.train, k = 3)
CM <- table(predicted = y_hat_k_3, truth = Weekly[Weekly.test, ]$Direction)
CM
         truth
predicted Down Up
     Down   15 19
     Up     28 42
sprintf("KNN (k=1): overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "KNN (k=1): overall fraction correct=   0.548077"

Ejercicio 11

attach(Auto)
set.seed(0)

a)

mpg01 <- rep(0, dim(Auto)[1])  
mpg01[Auto$mpg > median(Auto$mpg)] <- 1
Auto$mpg01 <- mpg01
Auto$mpg <- NULL

b)

pairs(Auto)

Auto$mpg01 <- as.factor(mpg01)

c)

n <- dim(Auto)[1]
inds.train <- sample(1:n, 3 * n/4)
Auto.train <- Auto[inds.train, ]
inds.test <- (1:n)[-inds.train]
Auto.test <- Auto[inds.test, ]

d)

lda.fit <- lda(mpg01 ~ cylinders + displacement + weight, data = Auto.train)
lda.predict <- predict(lda.fit, newdata = Auto.test)
CM <- table(predicted = lda.predict$class, truth = Auto.test$mpg01)
CM
         truth
predicted  0  1
        0 42  1
        1  5 50
sprintf("LDA: overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "LDA: overall fraction correct=   0.938776"

e)

qda.fit <- qda(mpg01 ~ cylinders + displacement + weight, data = Auto.train)
qda.predict <- predict(qda.fit, newdata = Auto.test)
CM <- table(predicted = qda.predict$class, truth = Auto.test$mpg01)
CM
         truth
predicted  0  1
        0 44  2
        1  3 49
sprintf("QDA: overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "QDA: overall fraction correct=   0.948980"

f)

lr.fit <- glm(mpg01 ~ cylinders + displacement + weight, data = Auto.train, family = binomial)
p_hat <- predict(lr.fit, newdata = Auto.test, type = "response")
y_hat <- rep(0, length(p_hat))
y_hat[p_hat > 0.5] <- 1
CM <- table(predicted = as.factor(y_hat), truth = Auto.test$mpg01)
CM
         truth
predicted  0  1
        0 43  3
        1  4 48
sprintf("LR (all features): overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "LR (all features): overall fraction correct=   0.928571"

Ejercicio 12

a)

Power <- function() {
    print(2^3)
}

b)

Power2 <- function(x, a) {
    print(x^a)
}

Ejercicio 13

a)

set.seed(0)
n <- dim(Boston)[1]
Boston$crim01 <- rep(0, n)
Boston$crim01[Boston$crim >= median(Boston$crim)] <- 1
Boston$crim <- NULL
Boston.cor <- cor(Boston)
the standard deviation is zero
print(sort(Boston.cor[, "crim01"]))
crim01 
     1 
inds.train <- sample(1:n, 3 * n/4)
inds.test <- (1:n)[-inds.train]
Boston.train <- Boston[inds.train, ]
Boston.test <- Boston[inds.test, ]
lr_model <- glm(crim01 ~ nox + rad + dis, data = Boston.train, family = binomial)
glm.fit: algorithm did not converge
p_hat <- predict(lr_model, newdata = Boston.test, type = "response")
y_hat <- rep(0, length(p_hat))
y_hat[p_hat > 0.5] <- 1
CM <- table(predicted = y_hat, truth = Boston.test$crim01)
CM
         truth
predicted   1
        1 127
sprintf("LR: overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
Error in `[.default`(CM, 2, 2) : subscript out of bounds

b)

sprintf("LDA: overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "LDA: overall fraction correct=   0.811024"
qda.fit <- qda(crim01 ~ nox + rad + dis, data = Boston.train)
qda.predict <- predict(qda.fit, newdata = Boston.test)
CM <- table(predicted = qda.predict$class, truth = Boston.test$crim01)
CM
         truth
predicted  0  1
        0 58 22
        1  2 45
sprintf("QDA: overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "QDA: overall fraction correct=   0.811024"

c)

X.train <- Boston.train
X.train$crim01 <- NULL
Y.train <- Boston.train$crim01
X.test <- Boston.test
X.test$crim01 <- NULL
y_hat_k_1 <- knn(X.train, X.test, Y.train, k = 1)
CM <- table(predicted = y_hat_k_1, truth = Boston.test$crim01)
CM
         truth
predicted  0  1
        0 59  9
        1  1 58
sprintf("KNN (k=1): overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "KNN (k=1): overall fraction correct=   0.921260"
y_hat_k_3 <- knn(X.train, X.test, Y.train, k = 3)
CM <- table(predicted = y_hat_k_3, truth = Boston.test$crim01)
CM
         truth
predicted  0  1
        0 58 10
        1  2 57
sprintf("KNN (k=3): overall fraction correct= %10.6f", (CM[1, 1] + CM[2, 2])/sum(CM))
[1] "KNN (k=3): overall fraction correct=   0.905512"
LS0tDQp0aXRsZTogIkxhYm9yYXRvcmlvICMgMyAtIE9zY2FyIFBhZGlsbGEiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIyMgRWplcmNpY2lvIDEwDQpgYGB7cn0NCmxpYnJhcnkoIklTTFIiKQ0KbGlicmFyeSgiTUFTUyIpDQpsaWJyYXJ5KCJjbGFzcyIpDQpzZXQuc2VlZCgwKQ0KYGBgDQoNCiMjIyMgYSkNCmBgYHtyfQ0KDQpEaXJlY3Rpb24gPC0gV2Vla2x5JERpcmVjdGlvbg0KV2Vla2x5JERpcmVjdGlvbiA8LSBOVUxMDQpXZWVrbHkkTnVtZXJpY0RpcmVjdGlvbiA8LSBhcy5udW1lcmljKERpcmVjdGlvbikgIA0KV2Vla2x5JE51bWVyaWNEaXJlY3Rpb25bV2Vla2x5JE51bWVyaWNEaXJlY3Rpb24gPT0gMV0gPC0gLTEgDQpXZWVrbHkkTnVtZXJpY0RpcmVjdGlvbltXZWVrbHkkTnVtZXJpY0RpcmVjdGlvbiA9PSAyXSA8LSArMSAgDQpXZWVrbHkuY29yIDwtIGNvcihXZWVrbHkpDQpgYGANCiMjIyMgYikNCmBgYHtyfQ0KV2Vla2x5JE51bWVyaWNEaXJlY3Rpb24gPC0gTlVMTA0KV2Vla2x5JERpcmVjdGlvbiA8LSBEaXJlY3Rpb24NCmZpdmVfbGFnX21vZGVsIDwtIGdsbShEaXJlY3Rpb24gfiBMYWcxICsgTGFnMiArIExhZzMgKyBMYWc0ICsgTGFnNSArIFZvbHVtZSwgZGF0YSA9IFdlZWtseSwgZmFtaWx5ID0gYmlub21pYWwpDQpzdW1tYXJ5KGZpdmVfbGFnX21vZGVsKQ0KY29udHJhc3RzKFdlZWtseSREaXJlY3Rpb24pDQpgYGANCiMjIyMgYykNCmBgYHtyfQ0KcF9oYXQgPC0gcHJlZGljdChmaXZlX2xhZ19tb2RlbCwgbmV3ZGF0YSA9IFdlZWtseSwgdHlwZSA9ICJyZXNwb25zZSIpDQp5X2hhdCA8LSByZXAoIkRvd24iLCBsZW5ndGgocF9oYXQpKQ0KeV9oYXRbcF9oYXQgPiAwLjVdIDwtICJVcCINCkNNIDwtIHRhYmxlKHByZWRpY3RlZCA9IHlfaGF0LCB0cnV0aCA9IFdlZWtseSREaXJlY3Rpb24pDQpDTQ0Kc3ByaW50ZigiTFIgKGFsbCBmZWF0dXJlcyk6IG92ZXJhbGwgZnJhY3Rpb24gY29ycmVjdD0gJTEwLjZmIiwgKENNWzEsIDFdICsgQ01bMiwgMl0pL3N1bShDTSkpDQpgYGANCiMjIyMgZCkNCmBgYHtyfQ0KV2Vla2x5LnRyYWluIDwtIChXZWVrbHkkWWVhciA+PSAxOTkwKSAmIChXZWVrbHkkWWVhciA8PSAyMDA4KSANCldlZWtseS50ZXN0IDwtIChXZWVrbHkkWWVhciA+PSAyMDA5KSAgIyBvdXIgdGVzdGluZyBzZXQgDQpsYWcyX21vZGVsIDwtIGdsbShEaXJlY3Rpb24gfiBMYWcyLCBkYXRhID0gV2Vla2x5LCBmYW1pbHkgPSBiaW5vbWlhbCwgc3Vic2V0ID0gV2Vla2x5LnRyYWluKQ0KcF9oYXQgPC0gcHJlZGljdChsYWcyX21vZGVsLCBuZXdkYXRhID0gV2Vla2x5W1dlZWtseS50ZXN0LCBdLCB0eXBlID0gInJlc3BvbnNlIikNCnlfaGF0IDwtIHJlcCgiRG93biIsIGxlbmd0aChwX2hhdCkpDQp5X2hhdFtwX2hhdCA+IDAuNV0gPC0gIlVwIg0KQ00gPC0gdGFibGUocHJlZGljdGVkID0geV9oYXQsIHRydXRoID0gV2Vla2x5W1dlZWtseS50ZXN0LCBdJERpcmVjdGlvbikNCkNNDQpzcHJpbnRmKCJMUiAob25seSBMYWcyKTogb3ZlcmFsbCBmcmFjdGlvbiBjb3JyZWN0PSAlMTAuNmYiLCAoQ01bMSwgMV0gKyBDTVsyLCAyXSkvc3VtKENNKSkNCmBgYA0KIyMjIyBlKQ0KYGBge3J9DQpsZGEuZml0IDwtIGxkYShEaXJlY3Rpb24gfiBMYWcyLCBkYXRhID0gV2Vla2x5LCBzdWJzZXQgPSBXZWVrbHkudHJhaW4pDQpsZGEucHJlZGljdCA8LSBwcmVkaWN0KGxkYS5maXQsIG5ld2RhdGEgPSBXZWVrbHlbV2Vla2x5LnRlc3QsIF0pDQpDTSA8LSB0YWJsZShwcmVkaWN0ZWQgPSBsZGEucHJlZGljdCRjbGFzcywgdHJ1dGggPSBXZWVrbHlbV2Vla2x5LnRlc3QsIF0kRGlyZWN0aW9uKQ0KQ00NCnNwcmludGYoIkxEQSAob25seSBMYWcyKTogb3ZlcmFsbCBmcmFjdGlvbiBjb3JyZWN0PSAlMTAuNmYiLCAoQ01bMSwgMV0gKyBDTVsyLCAyXSkvc3VtKENNKSkNCmBgYA0KIyMjIyBmKQ0KYGBge3J9DQpxZGEuZml0IDwtIHFkYShEaXJlY3Rpb24gfiBMYWcyLCBkYXRhID0gV2Vla2x5LCBzdWJzZXQgPSBXZWVrbHkudHJhaW4pDQpxZGEucHJlZGljdCA8LSBwcmVkaWN0KHFkYS5maXQsIG5ld2RhdGEgPSBXZWVrbHlbV2Vla2x5LnRlc3QsIF0pDQpDTSA8LSB0YWJsZShwcmVkaWN0ZWQgPSBxZGEucHJlZGljdCRjbGFzcywgdHJ1dGggPSBXZWVrbHlbV2Vla2x5LnRlc3QsIF0kRGlyZWN0aW9uKQ0KQ00NCnNwcmludGYoIlFEQSAob25seSBMYWcyKTogb3ZlcmFsbCBmcmFjdGlvbiBjb3JyZWN0PSAlMTAuNmYiLCAoQ01bMSwgMV0gKyBDTVsyLCAyXSkvc3VtKENNKSkNCmBgYA0KIyMjIyBnKQ0KYGBge3J9DQpYLnRyYWluIDwtIGRhdGEuZnJhbWUoTGFnMiA9IFdlZWtseVtXZWVrbHkudHJhaW4sIF0kTGFnMikNClkudHJhaW4gPC0gV2Vla2x5W1dlZWtseS50cmFpbiwgXSREaXJlY3Rpb24NClgudGVzdCA8LSBkYXRhLmZyYW1lKExhZzIgPSBXZWVrbHlbV2Vla2x5LnRlc3QsIF0kTGFnMikNCnlfaGF0X2tfMSA8LSBrbm4oWC50cmFpbiwgWC50ZXN0LCBZLnRyYWluLCBrID0gMSkNCkNNIDwtIHRhYmxlKHByZWRpY3RlZCA9IHlfaGF0X2tfMSwgdHJ1dGggPSBXZWVrbHlbV2Vla2x5LnRlc3QsIF0kRGlyZWN0aW9uKQ0KQ00NCnNwcmludGYoIktOTiAoaz0xKTogb3ZlcmFsbCBmcmFjdGlvbiBjb3JyZWN0PSAlMTAuNmYiLCAoQ01bMSwgMV0gKyBDTVsyLCAyXSkvc3VtKENNKSkNCnlfaGF0X2tfMyA8LSBrbm4oWC50cmFpbiwgWC50ZXN0LCBZLnRyYWluLCBrID0gMykNCkNNIDwtIHRhYmxlKHByZWRpY3RlZCA9IHlfaGF0X2tfMywgdHJ1dGggPSBXZWVrbHlbV2Vla2x5LnRlc3QsIF0kRGlyZWN0aW9uKQ0KQ00NCnNwcmludGYoIktOTiAoaz0xKTogb3ZlcmFsbCBmcmFjdGlvbiBjb3JyZWN0PSAlMTAuNmYiLCAoQ01bMSwgMV0gKyBDTVsyLCAyXSkvc3VtKENNKSkNCmBgYA0KDQojIyMgRWplcmNpY2lvIDExDQoNCmBgYHtyfQ0KYXR0YWNoKEF1dG8pDQpzZXQuc2VlZCgwKQ0KYGBgDQoNCiMjIyNhKQ0KYGBge3J9DQptcGcwMSA8LSByZXAoMCwgZGltKEF1dG8pWzFdKSAgDQptcGcwMVtBdXRvJG1wZyA+IG1lZGlhbihBdXRvJG1wZyldIDwtIDENCkF1dG8kbXBnMDEgPC0gbXBnMDENCkF1dG8kbXBnIDwtIE5VTEwNCmBgYA0KDQojIyMjYikNCmBgYHtyfQ0KcGFpcnMoQXV0bykNCkF1dG8kbXBnMDEgPC0gYXMuZmFjdG9yKG1wZzAxKQ0KYGBgDQoNCiMjIyNjKQ0KYGBge3J9DQpuIDwtIGRpbShBdXRvKVsxXQ0KaW5kcy50cmFpbiA8LSBzYW1wbGUoMTpuLCAzICogbi80KQ0KQXV0by50cmFpbiA8LSBBdXRvW2luZHMudHJhaW4sIF0NCmluZHMudGVzdCA8LSAoMTpuKVstaW5kcy50cmFpbl0NCkF1dG8udGVzdCA8LSBBdXRvW2luZHMudGVzdCwgXQ0KYGBgDQoNCiMjIyNkKQ0KYGBge3J9DQpsZGEuZml0IDwtIGxkYShtcGcwMSB+IGN5bGluZGVycyArIGRpc3BsYWNlbWVudCArIHdlaWdodCwgZGF0YSA9IEF1dG8udHJhaW4pDQpsZGEucHJlZGljdCA8LSBwcmVkaWN0KGxkYS5maXQsIG5ld2RhdGEgPSBBdXRvLnRlc3QpDQpDTSA8LSB0YWJsZShwcmVkaWN0ZWQgPSBsZGEucHJlZGljdCRjbGFzcywgdHJ1dGggPSBBdXRvLnRlc3QkbXBnMDEpDQpDTQ0Kc3ByaW50ZigiTERBOiBvdmVyYWxsIGZyYWN0aW9uIGNvcnJlY3Q9ICUxMC42ZiIsIChDTVsxLCAxXSArIENNWzIsIDJdKS9zdW0oQ00pKQ0KYGBgDQoNCiMjIyNlKQ0KYGBge3J9DQpxZGEuZml0IDwtIHFkYShtcGcwMSB+IGN5bGluZGVycyArIGRpc3BsYWNlbWVudCArIHdlaWdodCwgZGF0YSA9IEF1dG8udHJhaW4pDQpxZGEucHJlZGljdCA8LSBwcmVkaWN0KHFkYS5maXQsIG5ld2RhdGEgPSBBdXRvLnRlc3QpDQpDTSA8LSB0YWJsZShwcmVkaWN0ZWQgPSBxZGEucHJlZGljdCRjbGFzcywgdHJ1dGggPSBBdXRvLnRlc3QkbXBnMDEpDQpDTQ0Kc3ByaW50ZigiUURBOiBvdmVyYWxsIGZyYWN0aW9uIGNvcnJlY3Q9ICUxMC42ZiIsIChDTVsxLCAxXSArIENNWzIsIDJdKS9zdW0oQ00pKQ0KYGBgDQoNCiMjIyNmKQ0KYGBge3J9DQpsci5maXQgPC0gZ2xtKG1wZzAxIH4gY3lsaW5kZXJzICsgZGlzcGxhY2VtZW50ICsgd2VpZ2h0LCBkYXRhID0gQXV0by50cmFpbiwgZmFtaWx5ID0gYmlub21pYWwpDQpwX2hhdCA8LSBwcmVkaWN0KGxyLmZpdCwgbmV3ZGF0YSA9IEF1dG8udGVzdCwgdHlwZSA9ICJyZXNwb25zZSIpDQp5X2hhdCA8LSByZXAoMCwgbGVuZ3RoKHBfaGF0KSkNCnlfaGF0W3BfaGF0ID4gMC41XSA8LSAxDQpDTSA8LSB0YWJsZShwcmVkaWN0ZWQgPSBhcy5mYWN0b3IoeV9oYXQpLCB0cnV0aCA9IEF1dG8udGVzdCRtcGcwMSkNCkNNDQpzcHJpbnRmKCJMUiAoYWxsIGZlYXR1cmVzKTogb3ZlcmFsbCBmcmFjdGlvbiBjb3JyZWN0PSAlMTAuNmYiLCAoQ01bMSwgMV0gKyBDTVsyLCAyXSkvc3VtKENNKSkNCmBgYA0KDQojIyMgRWplcmNpY2lvIDEyDQoNCiMjIyNhKQ0KYGBge3J9DQpQb3dlciA8LSBmdW5jdGlvbigpIHsNCiAgICBwcmludCgyXjMpDQp9DQpgYGANCg0KIyMjI2IpDQpgYGB7cn0NClBvd2VyMiA8LSBmdW5jdGlvbih4LCBhKSB7DQogICAgcHJpbnQoeF5hKQ0KfQ0KYGBgDQoNCiMjIyBFamVyY2ljaW8gMTMNCg0KIyMjYSkNCmBgYHtyfQ0Kc2V0LnNlZWQoMCkNCm4gPC0gZGltKEJvc3RvbilbMV0NCkJvc3RvbiRjcmltMDEgPC0gcmVwKDAsIG4pDQpCb3N0b24kY3JpbTAxW0Jvc3RvbiRjcmltID49IG1lZGlhbihCb3N0b24kY3JpbSldIDwtIDENCkJvc3RvbiRjcmltIDwtIE5VTEwNCkJvc3Rvbi5jb3IgPC0gY29yKEJvc3RvbikNCnByaW50KHNvcnQoQm9zdG9uLmNvclssICJjcmltMDEiXSkpDQppbmRzLnRyYWluIDwtIHNhbXBsZSgxOm4sIDMgKiBuLzQpDQppbmRzLnRlc3QgPC0gKDE6bilbLWluZHMudHJhaW5dDQpCb3N0b24udHJhaW4gPC0gQm9zdG9uW2luZHMudHJhaW4sIF0NCkJvc3Rvbi50ZXN0IDwtIEJvc3RvbltpbmRzLnRlc3QsIF0NCmxyX21vZGVsIDwtIGdsbShjcmltMDEgfiBub3ggKyByYWQgKyBkaXMsIGRhdGEgPSBCb3N0b24udHJhaW4sIGZhbWlseSA9IGJpbm9taWFsKQ0KcF9oYXQgPC0gcHJlZGljdChscl9tb2RlbCwgbmV3ZGF0YSA9IEJvc3Rvbi50ZXN0LCB0eXBlID0gInJlc3BvbnNlIikNCnlfaGF0IDwtIHJlcCgwLCBsZW5ndGgocF9oYXQpKQ0KeV9oYXRbcF9oYXQgPiAwLjVdIDwtIDENCkNNIDwtIHRhYmxlKHByZWRpY3RlZCA9IHlfaGF0LCB0cnV0aCA9IEJvc3Rvbi50ZXN0JGNyaW0wMSkNCkNNDQpzcHJpbnRmKCJMUjogb3ZlcmFsbCBmcmFjdGlvbiBjb3JyZWN0PSAlMTAuNmYiLCAoQ01bMSwgMV0gKyBDTVsyLCAyXSkvc3VtKENNKSkNCmxkYS5maXQgPC0gbGRhKGNyaW0wMSB+IG5veCArIHJhZCArIGRpcywgZGF0YSA9IEJvc3Rvbi50cmFpbikNCmxkYS5maXQgPC0gbGRhKGNyaW0wMSB+IG5veCArIHJhZCArIGRpcywgZGF0YSA9IEJvc3Rvbi50cmFpbikNCmxkYS5wcmVkaWN0IDwtIHByZWRpY3QobGRhLmZpdCwgbmV3ZGF0YSA9IEJvc3Rvbi50ZXN0KQ0KQ00gPC0gdGFibGUocHJlZGljdGVkID0gbGRhLnByZWRpY3QkY2xhc3MsIHRydXRoID0gQm9zdG9uLnRlc3QkY3JpbTAxKQ0KQ00NCg0KYGBgDQoNCiMjIyNiKQ0KYGBge3J9DQpzcHJpbnRmKCJMREE6IG92ZXJhbGwgZnJhY3Rpb24gY29ycmVjdD0gJTEwLjZmIiwgKENNWzEsIDFdICsgQ01bMiwgMl0pL3N1bShDTSkpDQpxZGEuZml0IDwtIHFkYShjcmltMDEgfiBub3ggKyByYWQgKyBkaXMsIGRhdGEgPSBCb3N0b24udHJhaW4pDQoNCnFkYS5wcmVkaWN0IDwtIHByZWRpY3QocWRhLmZpdCwgbmV3ZGF0YSA9IEJvc3Rvbi50ZXN0KQ0KQ00gPC0gdGFibGUocHJlZGljdGVkID0gcWRhLnByZWRpY3QkY2xhc3MsIHRydXRoID0gQm9zdG9uLnRlc3QkY3JpbTAxKQ0KQ00NCnNwcmludGYoIlFEQTogb3ZlcmFsbCBmcmFjdGlvbiBjb3JyZWN0PSAlMTAuNmYiLCAoQ01bMSwgMV0gKyBDTVsyLCAyXSkvc3VtKENNKSkNCmBgYA0KDQojIyMjYykNCmBgYHtyfQ0KWC50cmFpbiA8LSBCb3N0b24udHJhaW4NClgudHJhaW4kY3JpbTAxIDwtIE5VTEwNClkudHJhaW4gPC0gQm9zdG9uLnRyYWluJGNyaW0wMQ0KDQpYLnRlc3QgPC0gQm9zdG9uLnRlc3QNClgudGVzdCRjcmltMDEgPC0gTlVMTA0KDQp5X2hhdF9rXzEgPC0ga25uKFgudHJhaW4sIFgudGVzdCwgWS50cmFpbiwgayA9IDEpDQoNCkNNIDwtIHRhYmxlKHByZWRpY3RlZCA9IHlfaGF0X2tfMSwgdHJ1dGggPSBCb3N0b24udGVzdCRjcmltMDEpDQpDTQ0Kc3ByaW50ZigiS05OIChrPTEpOiBvdmVyYWxsIGZyYWN0aW9uIGNvcnJlY3Q9ICUxMC42ZiIsIChDTVsxLCAxXSArIENNWzIsIDJdKS9zdW0oQ00pKQ0KeV9oYXRfa18zIDwtIGtubihYLnRyYWluLCBYLnRlc3QsIFkudHJhaW4sIGsgPSAzKQ0KQ00gPC0gdGFibGUocHJlZGljdGVkID0geV9oYXRfa18zLCB0cnV0aCA9IEJvc3Rvbi50ZXN0JGNyaW0wMSkNCkNNDQpzcHJpbnRmKCJLTk4gKGs9Myk6IG92ZXJhbGwgZnJhY3Rpb24gY29ycmVjdD0gJTEwLjZmIiwgKENNWzEsIDFdICsgQ01bMiwgMl0pL3N1bShDTSkpDQpgYGANCg0KDQo=