Question 1
acs <- read.csv("HW3data.csv")
state <- acs$State
data <- select(acs, -State)
a.
pca.sc <- prcomp(data, scale = TRUE)
data_pca <- pca.sc$x[ , 1:7]
row.names(data_pca) <- state
b.
dists <- dist(data_pca)
c.
hclust.sing <- hclust(dists, method = "single")
par(mar = c(.5, 2, .5, 1))
plot(hclust.sing, hang = -1, sub = "", main = "")
abline(h = hclust.sing$height[51 - 7], lty = 2)

d.
Under single linkage, clusters are considered close if just one of
their values is close to the value of another cluster. So clusters that
merge together only need to share one similar observation, and the
distance between those observations must be within our cut height
distance. Therefore, clusters that share no observations within the cut
height distance will not merge with each other, and so every cluster
that has merged into one, must have at least one observation within the
cut height distance to another observation in its cluster. Since cluster
1 and 3 obviously didn’t merge that means they share no observations
within the cut height distance, which we can check for here.
clus.sing <- cutree(hclust.sing, h = hclust.sing$height[51 - 7])
table(clus.sing)
clus.sing
1 2 3 4 5 6 7
41 1 5 1 1 1 1
d.mat <- as.matrix(dists)
min(d.mat[which(clus.sing == 1), which(clus.sing == 3)])
[1] 3.851532
The smallest distance between any two observations in cluster 1 and
cluster 3 is 3.85 which is greater than our cut height distance of
3.77.
e.
The distance between Arizona and Florida, and Texas and California,
are both less than the cut height distance.
d.mat[which(clus.sing == 3), which(clus.sing == 3)]
Arizona California Florida Nevada Texas
Arizona 0.000000 4.919295 2.837324 3.706277 3.994248
California 4.919295 0.000000 4.725443 7.192576 2.925050
Florida 2.837324 4.725443 0.000000 4.482842 3.770813
Nevada 3.706277 7.192576 4.482842 0.000000 6.559933
Texas 3.994248 2.925050 3.770813 6.559933 0.000000
f.Â
Complete linkage has stricter conditions than single linkage.
Complete linkage looks at the distance between the two farthest
observations in clusters. So instead of merging clusters with one
similar observation it merges clusters with all similar observations.
This results in a more spaced out dendrogram since clusters must be more
similar to merge than under single linkage. Under single linkage
clusters were able to merge much quicker.
hclust.com <- hclust(dists, method = "complete")
par(mar = c(.5, 2, .5, 1))
plot(hclust.com, hang = -1, sub = "", main = "")
abline(h = 7.5, lty = 2)

g.
With a cut height of 7.5, we would have 9 clusters. The three states
in their own clusters are the District of Columbia, Alaska, and Hawaii.
This tells us these states are fairly different than most states.
clus.com <- cutree(hclust.com, h = 7.5)
table(clus.com)
clus.com
1 2 3 4 5 6 7 8 9
7 1 6 13 1 14 1 4 4
h.
The maximum distance between observations in cluster 8 and 9 is 7.89
which is greater than our cut height distance. So these clusters can’t
and didn’t merge at our cut height.
max(d.mat[which(clus.com == 8), which(clus.com == 9)])
[1] 7.894893
i.
Looking at the distances between all the observations in cluster 8,
you’ll notice all distances are less than the cut height distance.
d.mat[which(clus.com == 8), which(clus.com == 8)]
Maine Minnesota New Hampshire Vermont
Maine 0.000000 4.240758 3.901416 2.949826
Minnesota 4.240758 0.000000 1.781645 4.887299
New Hampshire 3.901416 1.781645 0.000000 3.965155
Vermont 2.949826 4.887299 3.965155 0.000000
j.
The function choose 9 clusters. States with the lowest maximum
cluster probabilities are the ones the model is least confident about
assigning to a single cluster. Their probabilities are more spread out
across multiple clusters, meaning they don’t strongly fit into any one
cluster and may lie between clusters or have mixed characteristics. The
states with the min maxes are Oregon, Maryland, and Maine, so these
states didn’t strongly fit into one single cluster as well as the
others.
gmm_model <- Mclust(data_pca)
probs <- apply(gmm_model$z, 1, max)
sort(probs)[1:3]
Oregon Maryland Maine
0.7499619 0.8475613 0.9154546
k.
There does appear to be an elbow in the k-distance plot around 6.8.
We got 1 cluster and 3 noise points. To no surprise, the three outlier
states were Alaska, District of Columbia, and Hawaii.
minPts <- 2*ncol(data_pca)
kNNdistplot(data_pca, k = minPts - 1)
abline(h = 6.8, lty = 2)

db <- dbscan(data_pca, eps = 6.8, minPts = minPts)
print(db)
DBSCAN clustering for 51 objects.
Parameters: eps = 6.8, minPts = 14
Using euclidean distances and borderpoints = TRUE
The clustering contains 1 cluster(s) and 3 noise points.
0 1
3 48
Available fields: cluster, eps, minPts, metric, borderPoints
state[db$cluster == 0]
[1] "Alaska" "District of Columbia" "Hawaii"
l.
Once again, the three outlier states were Alaska, District of
Columbia, and Hawaii.
lof_scores <- lof(data_pca, minPts = 8)
sort(head(order(lof_scores, decreasing = TRUE), n = 3))
[1] 2 9 12
state[c(2,9,12)]
[1] "Alaska" "District of Columbia" "Hawaii"
LS0tCnRpdGxlOiAiSG9tZXdvcmsgNCIKYXV0aG9yOiAiQ2hhcmxpZSBNb3JnYW4iCmRhdGU6ICIgRHVlOiAwMy8yOS8yNiIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6IAogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNAogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogbm8KICAgIHRvY19jb2xsYXBzZWQ6IHllcwogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKICAgIHNtb290aF9zY3JvbGw6IHllcwogICAgdGhlbWU6IGx1bWVuCiAgcGRmX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICBmaWdfd2lkdGg6IDMKICAgIGZpZ19oZWlnaHQ6IDMKICB3b3JkX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIGtlZXBfbWQ6IHllcwplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0KI1RPQzo6YmVmb3JlIHsKICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGZvbnQtc2l6ZTogMS4yZW07CiAgZGlzcGxheTogYmxvY2s7CiAgY29sb3I6IG5hdnk7CiAgbWFyZ2luLWJvdHRvbTogMTBweDsKfQoKCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8KICAgIGxpc3Qtc3R5bGU6dXBwZXItcm9tYW47CiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7CiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOwogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOwp9CgpoMS50aXRsZSB7ICAgIC8qIGxldmVsIDEgaGVhZGVyIG9mIHRpdGxlICAqLwogIGZvbnQtc2l6ZTogMjJweDsKICBmb250LXdlaWdodDogYm9sZDsKICBjb2xvcjogRGFya1JlZDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7CiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOwp9CgpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogIGZvbnQtc2l6ZTogMTVweDsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LWZhbWlseTogc3lzdGVtLXVpOwogIGNvbG9yOiBuYXZ5OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKaDQuZGF0ZSB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgZm9udC1zaXplOiAxOHB4OwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsKICBjb2xvcjogRGFya0JsdWU7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDIwcHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IGRhcmtyZWQ7CiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMThweDsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogbmF2eTsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmgzIHsgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMTZweDsKICAgIGZvbnQtd2VpZ2h0OiBib2xkOwogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgICBjb2xvcjogbmF2eTsKICAgIHRleHQtYWxpZ246IGxlZnQ7Cn0KCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICAgIGZvbnQtc2l6ZTogMTRweDsKICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IGRhcmtyZWQ7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovCi5oZWFkZXItc2VjdGlvbi1udW1iZXI6OmFmdGVyIHsKICBjb250ZW50OiAiLiI7Cgpib2R5IHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQoKLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0KCnAgeyBiYWNrZ3JvdW5kLWNvbG9yOndoaXRlOyB9Cgp9CmBgYAoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCAKIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuCmlmICghcmVxdWlyZSgia25pdHIiKSkgewogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpCiAgIGxpYnJhcnkoa25pdHIpCn0KaWYgKCFyZXF1aXJlKCJmYWN0b2V4dHJhIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJmYWN0b2V4dHJhIikKICBsaWJyYXJ5KGZhY3RvZXh0cmEpCn0KCmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQogIGxpYnJhcnkodGlkeXZlcnNlKQp9CgppZiAoIXJlcXVpcmUoIkZhY3RvTWluZVIiKSkgewogIGluc3RhbGwucGFja2FnZXMoIkZhY3RvTWluZVIiKQogIGxpYnJhcnkoRmFjdG9NaW5lUikKfQoKaWYgKCFyZXF1aXJlKCJjb3JycGxvdCIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiY29ycnBsb3QiKQogIGxpYnJhcnkoY29ycnBsb3QpCn0KCmlmICghcmVxdWlyZSgibWljZSIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygibWljZSIpCiAgbGlicmFyeShtaWNlKQp9CgppZiAoIXJlcXVpcmUoImthYmxlRXh0cmEiKSkgewogIGluc3RhbGwucGFja2FnZXMoImthYmxlRXh0cmEiKQogIGxpYnJhcnkoa2FibGVFeHRyYSkKfQoKaWYgKCFyZXF1aXJlKCJjbHVzdGVyIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJjbHVzdGVyIikKICBsaWJyYXJ5KGNsdXN0ZXIpCn0KCmlmICghcmVxdWlyZSgibWNsdXN0IikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJtY2x1c3QiKQogIGxpYnJhcnkobWNsdXN0KQp9CgppZiAoIXJlcXVpcmUoImRic2NhbiIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiZGJzY2FuIikKICBsaWJyYXJ5KGRic2NhbikKfQojIyMjCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB5b3UgY2FuIGNob29zZSB0byBpbmNsdWRlIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGluCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIAogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgaW4gdGhlIG91dHB1dCBmaWxlLgogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BCiAgICAgICAgICAgICAgICAgICAgICApICAKCmBgYAoKIyBRdWVzdGlvbiAxCmBgYHtyLCByZXN1bHRzID0gJ2hpZGUnfQphY3MgPC0gcmVhZC5jc3YoIkhXM2RhdGEuY3N2IikKc3RhdGUgPC0gYWNzJFN0YXRlCmRhdGEgPC0gc2VsZWN0KGFjcywgLVN0YXRlKQpgYGAKCiMjIGEuCmBgYHtyfQpwY2Euc2MgPC0gcHJjb21wKGRhdGEsIHNjYWxlID0gVFJVRSkKZGF0YV9wY2EgPC0gcGNhLnNjJHhbICwgMTo3XQpyb3cubmFtZXMoZGF0YV9wY2EpIDwtIHN0YXRlCmBgYAoKIyMgYi4KYGBge3J9CmRpc3RzIDwtIGRpc3QoZGF0YV9wY2EpCmBgYAoKIyMgYy4KYGBge3J9CmhjbHVzdC5zaW5nIDwtIGhjbHVzdChkaXN0cywgbWV0aG9kID0gInNpbmdsZSIpCnBhcihtYXIgPSBjKC41LCAyLCAuNSwgMSkpIApwbG90KGhjbHVzdC5zaW5nLCBoYW5nID0gLTEsIHN1YiA9ICIiLCBtYWluID0gIiIpCiAgYWJsaW5lKGggPSBoY2x1c3Quc2luZyRoZWlnaHRbNTEgLSA3XSwgbHR5ID0gMikKYGBgCgojIyBkLgpVbmRlciBzaW5nbGUgbGlua2FnZSwgY2x1c3RlcnMgYXJlIGNvbnNpZGVyZWQgY2xvc2UgaWYganVzdCBvbmUgb2YgdGhlaXIgdmFsdWVzIGlzIGNsb3NlIHRvIHRoZSB2YWx1ZSBvZiBhbm90aGVyIGNsdXN0ZXIuIFNvIGNsdXN0ZXJzIHRoYXQgbWVyZ2UgdG9nZXRoZXIgb25seSBuZWVkIHRvIHNoYXJlIG9uZSBzaW1pbGFyIG9ic2VydmF0aW9uLCBhbmQgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhvc2Ugb2JzZXJ2YXRpb25zIG11c3QgYmUgd2l0aGluIG91ciBjdXQgaGVpZ2h0IGRpc3RhbmNlLiBUaGVyZWZvcmUsIGNsdXN0ZXJzIHRoYXQgc2hhcmUgbm8gb2JzZXJ2YXRpb25zIHdpdGhpbiB0aGUgY3V0IGhlaWdodCBkaXN0YW5jZSB3aWxsIG5vdCBtZXJnZSB3aXRoIGVhY2ggb3RoZXIsIGFuZCBzbyBldmVyeSBjbHVzdGVyIHRoYXQgaGFzIG1lcmdlZCBpbnRvIG9uZSwgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBvYnNlcnZhdGlvbiB3aXRoaW4gdGhlIGN1dCBoZWlnaHQgZGlzdGFuY2UgdG8gYW5vdGhlciBvYnNlcnZhdGlvbiBpbiBpdHMgY2x1c3Rlci4gU2luY2UgY2x1c3RlciAxIGFuZCAzIG9idmlvdXNseSBkaWRuJ3QgbWVyZ2UgdGhhdCBtZWFucyB0aGV5IHNoYXJlIG5vIG9ic2VydmF0aW9ucyB3aXRoaW4gdGhlIGN1dCBoZWlnaHQgZGlzdGFuY2UsIHdoaWNoIHdlIGNhbiBjaGVjayBmb3IgaGVyZS4KYGBge3J9CmNsdXMuc2luZyA8LSBjdXRyZWUoaGNsdXN0LnNpbmcsIGggPSBoY2x1c3Quc2luZyRoZWlnaHRbNTEgLSA3XSkKICB0YWJsZShjbHVzLnNpbmcpCmQubWF0IDwtIGFzLm1hdHJpeChkaXN0cykKbWluKGQubWF0W3doaWNoKGNsdXMuc2luZyA9PSAxKSwgd2hpY2goY2x1cy5zaW5nID09IDMpXSkKYGBgClRoZSBzbWFsbGVzdCBkaXN0YW5jZSBiZXR3ZWVuIGFueSB0d28gb2JzZXJ2YXRpb25zIGluIGNsdXN0ZXIgMSBhbmQgY2x1c3RlciAzIGlzIDMuODUgd2hpY2ggaXMgZ3JlYXRlciB0aGFuIG91ciBjdXQgaGVpZ2h0IGRpc3RhbmNlIG9mIDMuNzcuCgojIyBlLgpUaGUgZGlzdGFuY2UgYmV0d2VlbiBBcml6b25hIGFuZCBGbG9yaWRhLCBhbmQgVGV4YXMgYW5kIENhbGlmb3JuaWEsIGFyZSBib3RoIGxlc3MgdGhhbiB0aGUgY3V0IGhlaWdodCBkaXN0YW5jZS4KYGBge3J9CmQubWF0W3doaWNoKGNsdXMuc2luZyA9PSAzKSwgd2hpY2goY2x1cy5zaW5nID09IDMpXQpgYGAKIyMgZi4gCkNvbXBsZXRlIGxpbmthZ2UgaGFzIHN0cmljdGVyIGNvbmRpdGlvbnMgdGhhbiBzaW5nbGUgbGlua2FnZS4gQ29tcGxldGUgbGlua2FnZSBsb29rcyBhdCB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgdHdvIGZhcnRoZXN0IG9ic2VydmF0aW9ucyBpbiBjbHVzdGVycy4gU28gaW5zdGVhZCBvZiBtZXJnaW5nIGNsdXN0ZXJzIHdpdGggb25lIHNpbWlsYXIgb2JzZXJ2YXRpb24gaXQgbWVyZ2VzIGNsdXN0ZXJzIHdpdGggYWxsIHNpbWlsYXIgb2JzZXJ2YXRpb25zLiBUaGlzIHJlc3VsdHMgaW4gYSBtb3JlIHNwYWNlZCBvdXQgZGVuZHJvZ3JhbSBzaW5jZSBjbHVzdGVycyBtdXN0IGJlIG1vcmUgc2ltaWxhciB0byBtZXJnZSB0aGFuIHVuZGVyIHNpbmdsZSBsaW5rYWdlLiBVbmRlciBzaW5nbGUgbGlua2FnZSBjbHVzdGVycyB3ZXJlIGFibGUgdG8gbWVyZ2UgbXVjaCBxdWlja2VyLgpgYGB7cn0KaGNsdXN0LmNvbSA8LSBoY2x1c3QoZGlzdHMsIG1ldGhvZCA9ICJjb21wbGV0ZSIpCnBhcihtYXIgPSBjKC41LCAyLCAuNSwgMSkpIApwbG90KGhjbHVzdC5jb20sIGhhbmcgPSAtMSwgc3ViID0gIiIsIG1haW4gPSAiIikKICBhYmxpbmUoaCA9IDcuNSwgbHR5ID0gMikKYGBgCgojIyBnLgpXaXRoIGEgY3V0IGhlaWdodCBvZiA3LjUsIHdlIHdvdWxkIGhhdmUgOSBjbHVzdGVycy4gVGhlIHRocmVlIHN0YXRlcyBpbiB0aGVpciBvd24gY2x1c3RlcnMgYXJlIHRoZSBEaXN0cmljdCBvZiBDb2x1bWJpYSwgQWxhc2thLCBhbmQgSGF3YWlpLiBUaGlzIHRlbGxzIHVzIHRoZXNlIHN0YXRlcyBhcmUgZmFpcmx5IGRpZmZlcmVudCB0aGFuIG1vc3Qgc3RhdGVzLiAKYGBge3J9CmNsdXMuY29tIDwtIGN1dHJlZShoY2x1c3QuY29tLCBoID0gNy41KQogIHRhYmxlKGNsdXMuY29tKQpgYGAKCiMjIGguClRoZSBtYXhpbXVtIGRpc3RhbmNlIGJldHdlZW4gb2JzZXJ2YXRpb25zIGluIGNsdXN0ZXIgOCBhbmQgOSBpcyA3Ljg5IHdoaWNoIGlzIGdyZWF0ZXIgdGhhbiBvdXIgY3V0IGhlaWdodCBkaXN0YW5jZS4gU28gdGhlc2UgY2x1c3RlcnMgY2FuJ3QgYW5kIGRpZG4ndCBtZXJnZSBhdCBvdXIgY3V0IGhlaWdodC4KYGBge3J9Cm1heChkLm1hdFt3aGljaChjbHVzLmNvbSA9PSA4KSwgd2hpY2goY2x1cy5jb20gPT0gOSldKQpgYGAKCiMjIGkuCkxvb2tpbmcgYXQgdGhlIGRpc3RhbmNlcyBiZXR3ZWVuIGFsbCB0aGUgb2JzZXJ2YXRpb25zIGluIGNsdXN0ZXIgOCwgeW91J2xsIG5vdGljZSBhbGwgZGlzdGFuY2VzIGFyZSBsZXNzIHRoYW4gdGhlIGN1dCBoZWlnaHQgZGlzdGFuY2UuIApgYGB7cn0KZC5tYXRbd2hpY2goY2x1cy5jb20gPT0gOCksIHdoaWNoKGNsdXMuY29tID09IDgpXQpgYGAKIyMgai4KVGhlIGZ1bmN0aW9uIGNob29zZSA5IGNsdXN0ZXJzLiBTdGF0ZXMgd2l0aCB0aGUgbG93ZXN0IG1heGltdW0gY2x1c3RlciBwcm9iYWJpbGl0aWVzIGFyZSB0aGUgb25lcyB0aGUgbW9kZWwgaXMgbGVhc3QgY29uZmlkZW50IGFib3V0IGFzc2lnbmluZyB0byBhIHNpbmdsZSBjbHVzdGVyLiBUaGVpciBwcm9iYWJpbGl0aWVzIGFyZSBtb3JlIHNwcmVhZCBvdXQgYWNyb3NzIG11bHRpcGxlIGNsdXN0ZXJzLCBtZWFuaW5nIHRoZXkgZG9u4oCZdCBzdHJvbmdseSBmaXQgaW50byBhbnkgb25lIGNsdXN0ZXIgYW5kIG1heSBsaWUgYmV0d2VlbiBjbHVzdGVycyBvciBoYXZlIG1peGVkIGNoYXJhY3RlcmlzdGljcy4gVGhlIHN0YXRlcyB3aXRoIHRoZSBtaW4gbWF4ZXMgYXJlIE9yZWdvbiwgTWFyeWxhbmQsIGFuZCBNYWluZSwgc28gdGhlc2Ugc3RhdGVzIGRpZG4ndCBzdHJvbmdseSBmaXQgaW50byBvbmUgc2luZ2xlIGNsdXN0ZXIgYXMgd2VsbCBhcyB0aGUgb3RoZXJzLgpgYGB7cn0KZ21tX21vZGVsIDwtIE1jbHVzdChkYXRhX3BjYSkKcHJvYnMgPC0gYXBwbHkoZ21tX21vZGVsJHosIDEsIG1heCkKc29ydChwcm9icylbMTozXQpgYGAKCiMjIGsuClRoZXJlIGRvZXMgYXBwZWFyIHRvIGJlIGFuIGVsYm93IGluIHRoZSBrLWRpc3RhbmNlIHBsb3QgYXJvdW5kIDYuOC4gV2UgZ290IDEgY2x1c3RlciBhbmQgMyBub2lzZSBwb2ludHMuIFRvIG5vIHN1cnByaXNlLCB0aGUgdGhyZWUgb3V0bGllciBzdGF0ZXMgd2VyZSBBbGFza2EsIERpc3RyaWN0IG9mIENvbHVtYmlhLCBhbmQgSGF3YWlpLgpgYGB7cn0KbWluUHRzIDwtIDIqbmNvbChkYXRhX3BjYSkKa05OZGlzdHBsb3QoZGF0YV9wY2EsIGsgPSBtaW5QdHMgLSAxKQogIGFibGluZShoID0gNi44LCBsdHkgPSAyKQpkYiA8LSBkYnNjYW4oZGF0YV9wY2EsIGVwcyA9IDYuOCwgbWluUHRzID0gbWluUHRzKQogIHByaW50KGRiKQogIApzdGF0ZVtkYiRjbHVzdGVyID09IDBdCmBgYAojIyBsLgpPbmNlIGFnYWluLCB0aGUgdGhyZWUgb3V0bGllciBzdGF0ZXMgd2VyZSBBbGFza2EsIERpc3RyaWN0IG9mIENvbHVtYmlhLCBhbmQgSGF3YWlpLgpgYGB7cn0KbG9mX3Njb3JlcyA8LSBsb2YoZGF0YV9wY2EsIG1pblB0cyA9IDgpCnNvcnQoaGVhZChvcmRlcihsb2Zfc2NvcmVzLCBkZWNyZWFzaW5nID0gVFJVRSksIG4gPSAzKSkKc3RhdGVbYygyLDksMTIpXQpgYGA=