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"
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=