Load dataset
df <- read_csv("data.csv")
Rows: 466 Columns: 4── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
dbl (4): Pysics, Science, Statistics, Math
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(df)
glimpse(df)
Rows: 466
Columns: 4
$ Pysics <dbl> 64, 74, 60, 84, 80, 75, 66, 77, 70, 89, 73, 78, 67, 80, 72, 68, 81, 64, 79, 70, 76, 71, 81, 85, 61, 74, 85, 60, 83, 85, …
$ Science <dbl> 67, 74, 59, 88, 88, 68, 59, 71, 71, 84, 76, 74, 63, 81, 75, 63, 89, 66, 81, 76, 80, 64, 77, 83, 67, 71, 82, 60, 88, 80, …
$ Statistics <dbl> 69, 63, 55, 89, 78, 68, 55, 66, 60, 80, 69, 63, 67, 83, 73, 76, 80, 59, 79, 69, 68, 75, 84, 87, 70, 75, 78, 57, 80, 76, …
$ Math <dbl> 68, 67, 57, 91, 82, 63, 65, 73, 67, 85, 82, 67, 57, 74, 83, 71, 85, 69, 87, 71, 80, 66, 73, 90, 61, 73, 84, 52, 92, 87, …
Modelling
Split train-test
set.seed(123)
index <- createDataPartition(df$Math, p = 0.8, list = FALSE)
df_train <- df[index,]
df_test <- df[-index,]
p <- list()
for (name in colnames(df)){
p[[name]] <- ggplot() +
geom_density(data=df_train, aes_string(x=name),alpha=.2, color="blue") +
geom_density(data=df_test, aes_string(x=name),alpha=.2, color="red")
}
grid.arrange(p[[1]], p[[2]], p[[3]], p[[4]], ncol=2)

Regression Model
m.reg <- lm(Math ~., data = df_train)
summary(m.reg)
Call:
lm(formula = Math ~ ., data = df_train)
Residuals:
Min 1Q Median 3Q Max
-50.954 -7.878 -0.254 7.956 27.443
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 52.415608 4.820313 10.874 < 2e-16 ***
Pysics -0.004225 0.036979 -0.114 0.9091
Science 0.090978 0.040450 2.249 0.0251 *
Statistics 0.213926 0.049076 4.359 1.69e-05 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 11.18 on 370 degrees of freedom
Multiple R-squared: 0.06903, Adjusted R-squared: 0.06148
F-statistic: 9.145 on 3 and 370 DF, p-value: 7.492e-06
Stepwise Regression (Variable Selection)
m.stepreg <- stepAIC(m.reg, direction = "both", trace = TRUE)
Start: AIC=1810.02
Math ~ Pysics + Science + Statistics
Df Sum of Sq RSS AIC
- Pysics 1 1.63 46283 1808.0
<none> 46282 1810.0
- Science 1 632.76 46914 1813.1
- Statistics 1 2376.82 48658 1826.8
Step: AIC=1808.04
Math ~ Science + Statistics
Df Sum of Sq RSS AIC
<none> 46283 1808.0
+ Pysics 1 1.63 46282 1810.0
- Science 1 631.37 46915 1811.1
- Statistics 1 2391.08 48674 1824.9
summary(m.stepreg)
Call:
lm(formula = Math ~ Science + Statistics, data = df_train)
Residuals:
Min 1Q Median 3Q Max
-50.952 -7.830 -0.204 7.954 27.437
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 52.18010 4.35144 11.991 < 2e-16 ***
Science 0.09065 0.04030 2.250 0.0251 *
Statistics 0.21332 0.04873 4.378 1.56e-05 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 11.17 on 371 degrees of freedom
Multiple R-squared: 0.069, Adjusted R-squared: 0.06398
F-statistic: 13.75 on 2 and 371 DF, p-value: 1.74e-06
Generalized Additive Model (GAM)
m.gam <- gam(Math ~ s(Pysics, k = 50) + s(Science, k = 50) + s(Statistics, k = 50),
data = df, method = "REML")
summary(m.gam)
Family: gaussian
Link function: identity
Formula:
Math ~ s(Pysics, k = 50) + s(Science, k = 50) + s(Statistics,
k = 50)
Parametric coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 74.5408 0.4985 149.5 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Approximate significance of smooth terms:
edf Ref.df F p-value
s(Pysics) 1.699 2.125 0.652 0.5786
s(Science) 2.227 2.820 3.467 0.0158 *
s(Statistics) 3.497 4.391 8.064 1.86e-06 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
R-sq.(adj) = 0.113 Deviance explained = 12.7%
-REML = 1769.5 Scale est. = 115.82 n = 466
draw(m.gam, residuals = TRUE)

Decision Tree
m.tree <- rpart(formula = Math ~.,
data = df_train,
method = "anova")
rpart.plot(m.tree)

Random Forest
m.rf <- randomForest(Math ~ ., data = df_train)
m.rf
Call:
randomForest(formula = Math ~ ., data = df_train)
Type of random forest: regression
Number of trees: 500
No. of variables tried at each split: 1
Mean of squared residuals: 125.8585
% Var explained: 5.31
Support Vector Machine (SVM)
m.svm <- ksvm(data = df_train, Math ~., kernel = "rbfdot")
m.svm
Support Vector Machine object of class "ksvm"
SV type: eps-svr (regression)
parameter : epsilon = 0.1 cost C = 1
Gaussian Radial Basis kernel function.
Hyperparameter : sigma = 0.738963400401823
Number of Support Vectors : 349
Objective Function Value : -204.2063
Training error : 0.735014
Variable Importance
grid.arrange(arrangeGrob(vip(m.reg), top ="Linear Regression"),
arrangeGrob(vip(m.stepreg), top ="Stepwise Regression"),
arrangeGrob(vip(m.tree), top ="Decision Tree"),
arrangeGrob(vip(m.rf), top ="Random Forest"),
ncol=2)

Model Evaluation
df_pred <- data.frame(actual=y_test, reg=predict.reg, stepreg=predict.stepreg,
gam=predict.gam, tree=predict.tree, rf=predict.rf,
svm=predict.svm)
df_pred
RMSE
apply(X = df_pred[,-1], MARGIN = 2, FUN = rmse, actual = df_pred$actual) %>% sort()
rf gam stepreg reg tree svm
10.16479 10.31009 10.65697 10.66888 10.68761 10.74176
Actual vs Predicted plots
p1 <- ggplot(data=df_pred) +
geom_point(aes(x=reg, y=actual)) +
geom_abline(intercept=0, slope=1, color="red", size=2) +
xlab("predicted") + ggtitle("Linear Regression") +
xlim(25,100) + ylim(25,100)
p2 <- ggplot(data=df_pred) +
geom_point(aes(x=stepreg, y=actual)) +
geom_abline(intercept=0, slope=1, color="red", size=2) +
xlab("predicted") + ggtitle("Stepwise Regression") +
xlim(25,100) + ylim(25,100)
p3 <- ggplot(data=df_pred) +
geom_point(aes(x=gam, y=actual)) +
geom_abline(intercept=0, slope=1, color="red", size=2) +
xlab("predicted") + ggtitle("GAM") +
xlim(25,100) + ylim(25,100)
p4 <- ggplot(data=df_pred) +
geom_point(aes(x=tree, y=actual)) +
geom_abline(intercept=0, slope=1, color="red", size=2) +
xlab("predicted") + ggtitle("Decision Tree") +
xlim(25,100) + ylim(25,100)
p5 <- ggplot(data=df_pred) +
geom_point(aes(x=rf, y=actual)) +
geom_abline(intercept=0, slope=1, color="red", size=2) +
xlab("predicted") + ggtitle("Random Forest") +
xlim(25,100) + ylim(25,100)
p6 <- ggplot(data=df_pred) +
geom_point(aes(x=svm, y=actual)) +
geom_abline(intercept=0, slope=1, color="red", size=2) +
xlab("predicted") + ggtitle("SVM") +
xlim(25,100) + ylim(25,100)
grid.arrange(p1,p2,p3,p4,p5,p6,ncol=3)

LS0tCnRpdGxlOiAiTWFjaGluZSBMZWFybmluZyBSZWdyZXNzaW9uIDIiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIHRvY19jb2xsYXBzZWQ6IHRydWUKLS0tCgojIyBJbXBvcnQgbGlicmFyeQpgYGB7ciBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KE1BU1MpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KHBzeWNoKQpsaWJyYXJ5KG1nY3YpCmxpYnJhcnkoZ3JhdGlhKQpsaWJyYXJ5KHJwYXJ0KQpsaWJyYXJ5KHJwYXJ0LnBsb3QpIApsaWJyYXJ5KHZpcCkKbGlicmFyeShyYW5kb21Gb3Jlc3QpCmxpYnJhcnkoa2VybmxhYikKbGlicmFyeShNZXRyaWNzKQpgYGAKCiMjIExvYWQgZGF0YXNldApgYGB7cn0KZGYgPC0gcmVhZF9jc3YoImRhdGEuY3N2IikKYGBgCgpgYGB7cn0KaGVhZChkZikKYGBgCgpgYGB7cn0KZ2xpbXBzZShkZikKYGBgCgoKCiMjIEV4cGxvcmF0b3J5IEFuYWx5c2lzCgojIyMgU3VtbWFyeSBTdGF0aXN0aWNzCgpgYGB7cn0KZGVzY3JpYmUoZGYpW2MoMiwzLDQsNSw4LDksMTApXQpgYGAKCgojIyMgRGF0YSBWaXN1YWxpemF0aW9uCgojIyMjIENvcnJlbGF0aW9uIG1hdHJpeApgYGB7cn0KcGFpcnMucGFuZWxzKGRmLCBtZXRob2QgPSAicGVhcnNvbiIsIGhpc3QuY29sID0gIiMwMEFGQkIiKQpgYGAKCiMjIyMgRGF0YSBkaXN0cmlidXRpb24KYGBge3J9CnAgPC0gbGlzdCgpCmZvciAobmFtZSBpbiBjb2xuYW1lcyhkZikpewogIHBbW25hbWVdXSA8LSBnZ3Bsb3QoZGF0YSA9IGRmLCBhZXNfc3RyaW5nKHg9bmFtZSkpICsgCiAgICAgICAgICAgICAgICBnZW9tX2hpc3RvZ3JhbShhZXMoeT0uLmRlbnNpdHkuLiksIGJpbndpZHRoID0gMTAsIGNvbG91cj0iYmxhY2siLCBmaWxsPSJ3aGl0ZSIpICsgCiAgICAgICAgICAgICAgICBnZW9tX2RlbnNpdHkoYWxwaGE9LjIsIGZpbGw9IiNGRjY2NjYiKSAKfQpncmlkLmFycmFuZ2UocFtbMV1dLCBwW1syXV0sIHBbWzNdXSwgcFtbNF1dLCBuY29sPTIpCmBgYAoKYGBge3J9CmFwcGx5KFggPSBkZiwgTUFSR0lOID0gMiwgRlVOID0gc2hhcGlyby50ZXN0KQpgYGAKCgojIyMjIFNjYXR0ZXIgcGxvdApgYGB7cn0KcCA8LSBsaXN0KCkKdmFyX2xpc3QgPC0gbmFtZXMoZGYpWy00XQpmb3IobmFtZSBpbiB2YXJfbGlzdCl7CiAgcFtbbmFtZV1dIDwtIGdncGxvdChkYXRhPWRmLCBhZXNfc3RyaW5nKHg9bmFtZSwgeT0iTWF0aCIpKSArIGdlb21fcG9pbnQoKSArIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgZm9ybXVsYSA9IHkgfiB4KQp9CgpncmlkLmFycmFuZ2UocFtbMV1dLCBwW1syXV0sIHBbWzNdXSwgbmNvbD0yKQpgYGAKCiMjIyMgRGlzY292ZXIgbm9ubGluZWFyIHBhdHRlcm4KYGBge3J9CmdyaWQuYXJyYW5nZShkcmF3KGdhbShNYXRoIH4gcyhQeXNpY3MsIGsgPSA1MCksIGRhdGEgPSBkZiwgbWV0aG9kID0gIlJFTUwiKSwgcmVzaWR1YWxzID0gVFJVRSksCiAgICAgICAgICAgICBkcmF3KGdhbShNYXRoIH4gcyhTY2llbmNlLCBrID0gNTApLCBkYXRhID0gZGYsIG1ldGhvZCA9ICJSRU1MIiksIHJlc2lkdWFscyA9IFRSVUUpLAogICAgICAgICAgICAgZHJhdyhnYW0oTWF0aCB+IHMoU3RhdGlzdGljcywgayA9IDUwKSwgZGF0YSA9IGRmLCBtZXRob2QgPSAiUkVNTCIpLCByZXNpZHVhbHMgPSBUUlVFKSwKbmNvbD0yKQpgYGAKCgojIyBNb2RlbGxpbmcKCiMjIyBTcGxpdCB0cmFpbi10ZXN0IApgYGB7cn0Kc2V0LnNlZWQoMTIzKQppbmRleCAgICA8LSBjcmVhdGVEYXRhUGFydGl0aW9uKGRmJE1hdGgsIHAgPSAwLjgsIGxpc3QgPSBGQUxTRSkKZGZfdHJhaW4gPC0gZGZbaW5kZXgsXQpkZl90ZXN0ICA8LSBkZlstaW5kZXgsXQpgYGAKCgpgYGB7cn0KcCA8LSBsaXN0KCkKZm9yIChuYW1lIGluIGNvbG5hbWVzKGRmKSl7CiAgcFtbbmFtZV1dIDwtIGdncGxvdCgpICsgCiAgICAgICAgICAgICAgIGdlb21fZGVuc2l0eShkYXRhPWRmX3RyYWluLCBhZXNfc3RyaW5nKHg9bmFtZSksYWxwaGE9LjIsIGNvbG9yPSJibHVlIikgKwogICAgICAgICAgICAgICBnZW9tX2RlbnNpdHkoZGF0YT1kZl90ZXN0LCBhZXNfc3RyaW5nKHg9bmFtZSksYWxwaGE9LjIsIGNvbG9yPSJyZWQiKQp9CmdyaWQuYXJyYW5nZShwW1sxXV0sIHBbWzJdXSwgcFtbM11dLCBwW1s0XV0sIG5jb2w9MikKYGBgCgojIyMgUmVncmVzc2lvbiBNb2RlbApgYGB7cn0KbS5yZWcgPC0gbG0oTWF0aCB+LiwgZGF0YSA9IGRmX3RyYWluKQpzdW1tYXJ5KG0ucmVnKQpgYGAKCiMjIyBTdGVwd2lzZSBSZWdyZXNzaW9uIChWYXJpYWJsZSBTZWxlY3Rpb24pCmBgYHtyfQptLnN0ZXByZWcgPC0gc3RlcEFJQyhtLnJlZywgZGlyZWN0aW9uID0gImJvdGgiLCB0cmFjZSA9IFRSVUUpCmBgYAoKYGBge3J9CnN1bW1hcnkobS5zdGVwcmVnKQpgYGAKCiMjIyBHZW5lcmFsaXplZCBBZGRpdGl2ZSBNb2RlbCAoR0FNKQpgYGB7cn0KbS5nYW0gPC0gZ2FtKE1hdGggfiBzKFB5c2ljcywgayA9IDUwKSArIHMoU2NpZW5jZSwgayA9IDUwKSArIHMoU3RhdGlzdGljcywgayA9IDUwKSwgCiAgICAgICAgICBkYXRhID0gZGYsIG1ldGhvZCA9ICJSRU1MIikKc3VtbWFyeShtLmdhbSkKYGBgCgpgYGB7cn0KZHJhdyhtLmdhbSwgcmVzaWR1YWxzID0gVFJVRSkKYGBgCgojIyMgRGVjaXNpb24gVHJlZQpgYGB7cn0KbS50cmVlIDwtIHJwYXJ0KGZvcm11bGEgPSBNYXRoIH4uLAogICAgICAgICAgICAgICAgZGF0YSA9IGRmX3RyYWluLAogICAgICAgICAgICAgICAgbWV0aG9kID0gImFub3ZhIikKcnBhcnQucGxvdChtLnRyZWUpCmBgYAoKCiMjIyBSYW5kb20gRm9yZXN0CmBgYHtyfQptLnJmIDwtIHJhbmRvbUZvcmVzdChNYXRoIH4gLiwgZGF0YSA9IGRmX3RyYWluKQptLnJmCmBgYAoKCiMjIyBTdXBwb3J0IFZlY3RvciBNYWNoaW5lIChTVk0pCmBgYHtyfQptLnN2bSA8LSBrc3ZtKGRhdGEgPSBkZl90cmFpbiwgTWF0aCB+Liwga2VybmVsID0gInJiZmRvdCIpCm0uc3ZtCmBgYAoKIyMjIFZhcmlhYmxlIEltcG9ydGFuY2UKCmBgYHtyfQpncmlkLmFycmFuZ2UoYXJyYW5nZUdyb2IodmlwKG0ucmVnKSwgdG9wID0iTGluZWFyIFJlZ3Jlc3Npb24iKSwgCiAgICAgICAgICAgICBhcnJhbmdlR3JvYih2aXAobS5zdGVwcmVnKSwgdG9wID0iU3RlcHdpc2UgUmVncmVzc2lvbiIpLCAKICAgICAgICAgICAgIGFycmFuZ2VHcm9iKHZpcChtLnRyZWUpLCB0b3AgPSJEZWNpc2lvbiBUcmVlIiksCiAgICAgICAgICAgICBhcnJhbmdlR3JvYih2aXAobS5yZiksIHRvcCA9IlJhbmRvbSBGb3Jlc3QiKSwKICAgICAgICAgICAgIG5jb2w9MikKYGBgCgojIyBQcmVkaWN0aW9uCmBgYHtyfQp4X3Rlc3QgPC0gZGZfdGVzdFssLTRdCnlfdGVzdCA8LSBhcy5udW1lcmljKGFzLm1hdHJpeChkZl90ZXN0Wyw0XSkpCnByZWRpY3QucmVnICAgICA8LSBwcmVkaWN0KG0ucmVnLHhfdGVzdCkKcHJlZGljdC5zdGVwcmVnIDwtIHByZWRpY3QobS5zdGVwcmVnLHhfdGVzdCkKcHJlZGljdC5nYW0gICAgIDwtIHByZWRpY3QobS5nYW0seF90ZXN0KQpwcmVkaWN0LnRyZWUgICAgPC0gcHJlZGljdChtLnRyZWUseF90ZXN0KQpwcmVkaWN0LnJmICAgICAgPC0gcHJlZGljdChtLnJmLHhfdGVzdCkKcHJlZGljdC5zdm0gICAgIDwtIHByZWRpY3QobS5zdm0seF90ZXN0KQpgYGAKCgojIyBNb2RlbCBFdmFsdWF0aW9uCmBgYHtyfQpkZl9wcmVkIDwtIGRhdGEuZnJhbWUoYWN0dWFsPXlfdGVzdCwgcmVnPXByZWRpY3QucmVnLCBzdGVwcmVnPXByZWRpY3Quc3RlcHJlZywKICAgICAgICAgICAgICAgICAgICAgIGdhbT1wcmVkaWN0LmdhbSwgdHJlZT1wcmVkaWN0LnRyZWUsIHJmPXByZWRpY3QucmYsCiAgICAgICAgICAgICAgICAgICAgICBzdm09cHJlZGljdC5zdm0pCmRmX3ByZWQKYGBgCgojIyMgUk1TRQoKYGBge3J9CmFwcGx5KFggPSBkZl9wcmVkWywtMV0sIE1BUkdJTiA9IDIsIEZVTiA9IHJtc2UsIGFjdHVhbCA9IGRmX3ByZWQkYWN0dWFsKSAlPiUgc29ydCgpCmBgYAoKCiMjIyBBY3R1YWwgdnMgUHJlZGljdGVkIHBsb3RzCmBgYHtyfQpwMSA8LSBnZ3Bsb3QoZGF0YT1kZl9wcmVkKSArCiAgICAgICAgZ2VvbV9wb2ludChhZXMoeD1yZWcsIHk9YWN0dWFsKSkgKwogICAgICAgIGdlb21fYWJsaW5lKGludGVyY2VwdD0wLCBzbG9wZT0xLCBjb2xvcj0icmVkIiwgc2l6ZT0yKSArCiAgICAgICAgeGxhYigicHJlZGljdGVkIikgKyBnZ3RpdGxlKCJMaW5lYXIgUmVncmVzc2lvbiIpICsKICAgICAgICB4bGltKDI1LDEwMCkgKyB5bGltKDI1LDEwMCkKcDIgPC0gZ2dwbG90KGRhdGE9ZGZfcHJlZCkgKwogICAgICAgIGdlb21fcG9pbnQoYWVzKHg9c3RlcHJlZywgeT1hY3R1YWwpKSArCiAgICAgICAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0PTAsIHNsb3BlPTEsIGNvbG9yPSJyZWQiLCBzaXplPTIpICsKICAgICAgICB4bGFiKCJwcmVkaWN0ZWQiKSArIGdndGl0bGUoIlN0ZXB3aXNlIFJlZ3Jlc3Npb24iKSArCiAgICAgICAgeGxpbSgyNSwxMDApICsgeWxpbSgyNSwxMDApCnAzIDwtIGdncGxvdChkYXRhPWRmX3ByZWQpICsKICAgICAgICBnZW9tX3BvaW50KGFlcyh4PWdhbSwgeT1hY3R1YWwpKSArCiAgICAgICAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0PTAsIHNsb3BlPTEsIGNvbG9yPSJyZWQiLCBzaXplPTIpICsKICAgICAgICB4bGFiKCJwcmVkaWN0ZWQiKSArIGdndGl0bGUoIkdBTSIpICsKICAgICAgICB4bGltKDI1LDEwMCkgKyB5bGltKDI1LDEwMCkKcDQgPC0gZ2dwbG90KGRhdGE9ZGZfcHJlZCkgKwogICAgICAgIGdlb21fcG9pbnQoYWVzKHg9dHJlZSwgeT1hY3R1YWwpKSArCiAgICAgICAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0PTAsIHNsb3BlPTEsIGNvbG9yPSJyZWQiLCBzaXplPTIpICsKICAgICAgICB4bGFiKCJwcmVkaWN0ZWQiKSArIGdndGl0bGUoIkRlY2lzaW9uIFRyZWUiKSArCiAgICAgICAgeGxpbSgyNSwxMDApICsgeWxpbSgyNSwxMDApCnA1IDwtIGdncGxvdChkYXRhPWRmX3ByZWQpICsKICAgICAgICBnZW9tX3BvaW50KGFlcyh4PXJmLCB5PWFjdHVhbCkpICsKICAgICAgICBnZW9tX2FibGluZShpbnRlcmNlcHQ9MCwgc2xvcGU9MSwgY29sb3I9InJlZCIsIHNpemU9MikgKwogICAgICAgIHhsYWIoInByZWRpY3RlZCIpICsgZ2d0aXRsZSgiUmFuZG9tIEZvcmVzdCIpICsKICAgICAgICB4bGltKDI1LDEwMCkgKyB5bGltKDI1LDEwMCkKcDYgPC0gZ2dwbG90KGRhdGE9ZGZfcHJlZCkgKwogICAgICAgIGdlb21fcG9pbnQoYWVzKHg9c3ZtLCB5PWFjdHVhbCkpICsKICAgICAgICBnZW9tX2FibGluZShpbnRlcmNlcHQ9MCwgc2xvcGU9MSwgY29sb3I9InJlZCIsIHNpemU9MikgKwogICAgICAgIHhsYWIoInByZWRpY3RlZCIpICsgZ2d0aXRsZSgiU1ZNIikgKwogICAgICAgIHhsaW0oMjUsMTAwKSArIHlsaW0oMjUsMTAwKQpncmlkLmFycmFuZ2UocDEscDIscDMscDQscDUscDYsbmNvbD0zKQpgYGAKCgoKCgoKCgo=