1. Explore the distribution of each of the x
, y
, and z
variables in diamonds
. What do you learn? Think about a diamond and how you might decide which dimension is the length, width, and depth.
First, I’ll calculate summary statistics for these variables and plot their distributions.
summary(select(diamonds, x, y, z))
x y z
Min. : 0.000 Min. : 0.000 Min. : 0.000
1st Qu.: 4.710 1st Qu.: 4.720 1st Qu.: 2.910
Median : 5.700 Median : 5.710 Median : 3.530
Mean : 5.731 Mean : 5.735 Mean : 3.539
3rd Qu.: 6.540 3rd Qu.: 6.540 3rd Qu.: 4.040
Max. :10.740 Max. :58.900 Max. :31.800
ggplot(diamonds) +
geom_histogram(mapping = aes(x = x), binwidth = 0.01)

ggplot(diamonds) +
geom_histogram(mapping = aes(x = y), binwidth = 0.01)

ggplot(diamonds) +
geom_histogram(mapping = aes(x = z), binwidth = 0.01)

There several noticeable features of the distributions:
x
and y
are larger than z
,
- there are outliers,
- they are all right skewed, and
- they are multimodal or “spiky”.
The typical values of x
and y
are larger than z
, with x
and y
having inter-quartile ranges of 4.7-5.7, while z
has an inter-quartile range of 2.9-4.0.
There are two types of outliers in this data. Some diamonds have values of zero and some have abnormally large values of x
, y
, or z
.
summary(select(diamonds, x, y, z))
x y z
Min. : 0.000 Min. : 0.000 Min. : 0.000
1st Qu.: 4.710 1st Qu.: 4.720 1st Qu.: 2.910
Median : 5.700 Median : 5.710 Median : 3.530
Mean : 5.731 Mean : 5.735 Mean : 3.539
3rd Qu.: 6.540 3rd Qu.: 6.540 3rd Qu.: 4.040
Max. :10.740 Max. :58.900 Max. :31.800
These appear to be either data entry errors, or an undocumented convention in the dataset for indicating missing values. An alternative hypothesis would be that values of zero are the result of rounding values like 0.002
down, but since there are no diamonds with values of 0.01, that does not seem to be the case.
filter(diamonds, x == 0 | y == 0 | z == 0)
There are also some diamonds with values of y
and z
that are abnormally large. There are diamonds with y == 58.9
and y == 31.8
, and one with z == 31.8
. These are probably data errors since the values do not seem in line with the values of the other variables.
diamonds %>%
arrange(desc(y)) %>%
head()
diamonds %>%
arrange(desc(z)) %>%
head()
Initially, I only considered univariate outliers. However, to check the plausibility of those outliers I would informally consider how consistent their values are with the values of the other variables. In this case, scatter plots of each combination of x
, y
, and z
shows these outliers much more clearly.
ggplot(diamonds, aes(x = x, y = y)) +
geom_point()

ggplot(diamonds, aes(x = x, y = z)) +
geom_point()

ggplot(diamonds, aes(x = y, y = z)) +
geom_point()

Removing the outliers from x
, y
, and z
makes the distribution easier to see. The right skewness of these distributions is unsurprising; there should be more smaller diamonds than larger ones and these values can never be negative. More interestingly, there are spikes in the distribution at certain values. These spikes often, but not exclusively, occur near integer values. Without knowing more about diamond cutting, I can’t say more about what these spikes represent. If you know, add a comment. I would guess that some diamond sizes are used more often than others, and these spikes correspond to those sizes. Also, I would guess that a diamond cut and carat value of a diamond imply values of x
, y
, and z
. Since there are spikes in the distribution of carat sizes, and only a few different cuts, that could result in these spikes. I’ll leave it to you to figure out if that’s the case.
filter(diamonds, x > 0, x < 10) %>%
ggplot() +
geom_histogram(mapping = aes(x = x), binwidth = 0.01) +
scale_x_continuous(breaks = 1:10)

filter(diamonds, y > 0, y < 10) %>%
ggplot() +
geom_histogram(mapping = aes(x = y), binwidth = 0.01) +
scale_x_continuous(breaks = 1:10)

filter(diamonds, z > 0, z < 10) %>%
ggplot() +
geom_histogram(mapping = aes(x = z), binwidth = 0.01) +
scale_x_continuous(breaks = 1:10)

According to the documentation for diamonds, x
is length, y
is width, and z
is depth. If documentation were unavailable, I would compare the values of the variables to match them to the length, width, and depth. I would expect length to always be less than width, otherwise the length would be called the width. I would also search for the definitions of length, width, and depth with respect to diamond cuts. Depth can be expressed as a percentage of the length/width of the diamond, which means it should be less than both the length and the width.
summarise(diamonds, mean(x > y), mean(x > z), mean(y > z))
It appears that depth (z
) is always smaller than length (x
) or width (y
), perhaps because a shallower depth helps when setting diamonds in jewelry and due to how it affect the reflection of light. Length is more than width in less than half the observations, the opposite of my expectations.
LS0tDQp0aXRsZTogIkV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXM6IFZhcmlhdGlvbiINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCg0KYGBge3IgbG9hZGxpYnJhcnl9DQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeSgidGlkeXZlcnNlIikpDQpgYGANCg0KIyMjIDEuIEV4cGxvcmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBlYWNoIG9mIHRoZSBgeGAsIGB5YCwgYW5kIGB6YCB2YXJpYWJsZXMgaW4gYGRpYW1vbmRzYC4gV2hhdCBkbyB5b3UgbGVhcm4/IFRoaW5rIGFib3V0IGEgZGlhbW9uZCBhbmQgaG93IHlvdSBtaWdodCBkZWNpZGUgd2hpY2ggZGltZW5zaW9uIGlzIHRoZSBsZW5ndGgsIHdpZHRoLCBhbmQgZGVwdGguDQoNCkZpcnN0LCBJ4oCZbGwgY2FsY3VsYXRlIHN1bW1hcnkgc3RhdGlzdGljcyBmb3IgdGhlc2UgdmFyaWFibGVzIGFuZCBwbG90IHRoZWlyIGRpc3RyaWJ1dGlvbnMuDQoNCmBgYHtyfQ0Kc3VtbWFyeShzZWxlY3QoZGlhbW9uZHMsIHgsIHksIHopKQ0KDQpnZ3Bsb3QoZGlhbW9uZHMpICsNCiAgZ2VvbV9oaXN0b2dyYW0obWFwcGluZyA9IGFlcyh4ID0geCksIGJpbndpZHRoID0gMC4wMSkNCg0KZ2dwbG90KGRpYW1vbmRzKSArDQogIGdlb21faGlzdG9ncmFtKG1hcHBpbmcgPSBhZXMoeCA9IHkpLCBiaW53aWR0aCA9IDAuMDEpDQoNCmdncGxvdChkaWFtb25kcykgKw0KICBnZW9tX2hpc3RvZ3JhbShtYXBwaW5nID0gYWVzKHggPSB6KSwgYmlud2lkdGggPSAwLjAxKQ0KYGBgDQoNClRoZXJlIHNldmVyYWwgbm90aWNlYWJsZSBmZWF0dXJlcyBvZiB0aGUgZGlzdHJpYnV0aW9uczoNCg0KMS4gYHhgIGFuZCBgeWAgYXJlIGxhcmdlciB0aGFuIGB6YCwNCjIuIHRoZXJlIGFyZSBvdXRsaWVycywNCjMuIHRoZXkgYXJlIGFsbCByaWdodCBza2V3ZWQsIGFuZA0KNC4gdGhleSBhcmUgbXVsdGltb2RhbCBvciDigJxzcGlreeKAnS4NCg0KVGhlIHR5cGljYWwgdmFsdWVzIG9mIGB4YCBhbmQgYHlgIGFyZSBsYXJnZXIgdGhhbiBgemAsIHdpdGggYHhgIGFuZCBgeWAgaGF2aW5nIGludGVyLXF1YXJ0aWxlIHJhbmdlcyBvZiA0LjctNS43LCB3aGlsZSBgemAgaGFzIGFuIGludGVyLXF1YXJ0aWxlIHJhbmdlIG9mIDIuOS00LjAuDQoNClRoZXJlIGFyZSB0d28gdHlwZXMgb2Ygb3V0bGllcnMgaW4gdGhpcyBkYXRhLiBTb21lIGRpYW1vbmRzIGhhdmUgdmFsdWVzIG9mIHplcm8gYW5kIHNvbWUgaGF2ZSBhYm5vcm1hbGx5IGxhcmdlIHZhbHVlcyBvZiBgeGAsIGB5YCwgb3IgYHpgLg0KDQpgYGB7cn0NCnN1bW1hcnkoc2VsZWN0KGRpYW1vbmRzLCB4LCB5LCB6KSkNCmBgYA0KDQpUaGVzZSBhcHBlYXIgdG8gYmUgZWl0aGVyIGRhdGEgZW50cnkgZXJyb3JzLCBvciBhbiB1bmRvY3VtZW50ZWQgY29udmVudGlvbiBpbiB0aGUgZGF0YXNldCBmb3IgaW5kaWNhdGluZyBtaXNzaW5nIHZhbHVlcy4gQW4gYWx0ZXJuYXRpdmUgaHlwb3RoZXNpcyB3b3VsZCBiZSB0aGF0IHZhbHVlcyBvZiB6ZXJvIGFyZSB0aGUgcmVzdWx0IG9mIHJvdW5kaW5nIHZhbHVlcyBsaWtlIGAwLjAwMmAgZG93biwgYnV0IHNpbmNlIHRoZXJlIGFyZSBubyBkaWFtb25kcyB3aXRoIHZhbHVlcyBvZiAwLjAxLCB0aGF0IGRvZXMgbm90IHNlZW0gdG8gYmUgdGhlIGNhc2UuDQoNCmBgYHtyfQ0KZmlsdGVyKGRpYW1vbmRzLCB4ID09IDAgfCB5ID09IDAgfCB6ID09IDApDQpgYGANCg0KVGhlcmUgYXJlIGFsc28gc29tZSBkaWFtb25kcyB3aXRoIHZhbHVlcyBvZiBgeWAgYW5kIGB6YCB0aGF0IGFyZSBhYm5vcm1hbGx5IGxhcmdlLiBUaGVyZSBhcmUgZGlhbW9uZHMgd2l0aCBgeSA9PSA1OC45YCBhbmQgYHkgPT0gMzEuOGAsIGFuZCBvbmUgd2l0aCBgeiA9PSAzMS44YC4gVGhlc2UgYXJlIHByb2JhYmx5IGRhdGEgZXJyb3JzIHNpbmNlIHRoZSB2YWx1ZXMgZG8gbm90IHNlZW0gaW4gbGluZSB3aXRoIHRoZSB2YWx1ZXMgb2YgdGhlIG90aGVyIHZhcmlhYmxlcy4NCg0KYGBge3J9DQpkaWFtb25kcyAlPiUNCiAgYXJyYW5nZShkZXNjKHkpKSAlPiUNCiAgaGVhZCgpDQoNCmRpYW1vbmRzICU+JQ0KICBhcnJhbmdlKGRlc2MoeikpICU+JQ0KICBoZWFkKCkNCmBgYA0KDQpJbml0aWFsbHksIEkgb25seSBjb25zaWRlcmVkIHVuaXZhcmlhdGUgb3V0bGllcnMuIEhvd2V2ZXIsIHRvIGNoZWNrIHRoZSBwbGF1c2liaWxpdHkgb2YgdGhvc2Ugb3V0bGllcnMgSSB3b3VsZCBpbmZvcm1hbGx5IGNvbnNpZGVyIGhvdyBjb25zaXN0ZW50IHRoZWlyIHZhbHVlcyBhcmUgd2l0aCB0aGUgdmFsdWVzIG9mIHRoZSBvdGhlciB2YXJpYWJsZXMuIEluIHRoaXMgY2FzZSwgc2NhdHRlciBwbG90cyBvZiBlYWNoIGNvbWJpbmF0aW9uIG9mIGB4YCwgYHlgLCBhbmQgYHpgIHNob3dzIHRoZXNlIG91dGxpZXJzIG11Y2ggbW9yZSBjbGVhcmx5Lg0KDQpgYGB7cn0NCmdncGxvdChkaWFtb25kcywgYWVzKHggPSB4LCB5ID0geSkpICsNCiAgZ2VvbV9wb2ludCgpDQoNCmdncGxvdChkaWFtb25kcywgYWVzKHggPSB4LCB5ID0geikpICsNCiAgZ2VvbV9wb2ludCgpDQoNCmdncGxvdChkaWFtb25kcywgYWVzKHggPSB5LCB5ID0geikpICsNCiAgZ2VvbV9wb2ludCgpDQpgYGANCg0KUmVtb3ZpbmcgdGhlIG91dGxpZXJzIGZyb20gYHhgLCBgeWAsIGFuZCBgemAgbWFrZXMgdGhlIGRpc3RyaWJ1dGlvbiBlYXNpZXIgdG8gc2VlLiBUaGUgcmlnaHQgc2tld25lc3Mgb2YgdGhlc2UgZGlzdHJpYnV0aW9ucyBpcyB1bnN1cnByaXNpbmc7IHRoZXJlIHNob3VsZCBiZSBtb3JlIHNtYWxsZXIgZGlhbW9uZHMgdGhhbiBsYXJnZXIgb25lcyBhbmQgdGhlc2UgdmFsdWVzIGNhbiBuZXZlciBiZSBuZWdhdGl2ZS4gTW9yZSBpbnRlcmVzdGluZ2x5LCB0aGVyZSBhcmUgc3Bpa2VzIGluIHRoZSBkaXN0cmlidXRpb24gYXQgY2VydGFpbiB2YWx1ZXMuIFRoZXNlIHNwaWtlcyBvZnRlbiwgYnV0IG5vdCBleGNsdXNpdmVseSwgb2NjdXIgbmVhciBpbnRlZ2VyIHZhbHVlcy4gV2l0aG91dCBrbm93aW5nIG1vcmUgYWJvdXQgZGlhbW9uZCBjdXR0aW5nLCBJIGNhbuKAmXQgc2F5IG1vcmUgYWJvdXQgd2hhdCB0aGVzZSBzcGlrZXMgcmVwcmVzZW50LiBJZiB5b3Uga25vdywgYWRkIGEgY29tbWVudC4gSSB3b3VsZCBndWVzcyB0aGF0IHNvbWUgZGlhbW9uZCBzaXplcyBhcmUgdXNlZCBtb3JlIG9mdGVuIHRoYW4gb3RoZXJzLCBhbmQgdGhlc2Ugc3Bpa2VzIGNvcnJlc3BvbmQgdG8gdGhvc2Ugc2l6ZXMuIEFsc28sIEkgd291bGQgZ3Vlc3MgdGhhdCBhIGRpYW1vbmQgY3V0IGFuZCBjYXJhdCB2YWx1ZSBvZiBhIGRpYW1vbmQgaW1wbHkgdmFsdWVzIG9mIGB4YCwgYHlgLCBhbmQgYHpgLiBTaW5jZSB0aGVyZSBhcmUgc3Bpa2VzIGluIHRoZSBkaXN0cmlidXRpb24gb2YgY2FyYXQgc2l6ZXMsIGFuZCBvbmx5IGEgZmV3IGRpZmZlcmVudCBjdXRzLCB0aGF0IGNvdWxkIHJlc3VsdCBpbiB0aGVzZSBzcGlrZXMuIEnigJlsbCBsZWF2ZSBpdCB0byB5b3UgdG8gZmlndXJlIG91dCBpZiB0aGF04oCZcyB0aGUgY2FzZS4NCg0KYGBge3J9DQpmaWx0ZXIoZGlhbW9uZHMsIHggPiAwLCB4IDwgMTApICU+JQ0KICBnZ3Bsb3QoKSArDQogIGdlb21faGlzdG9ncmFtKG1hcHBpbmcgPSBhZXMoeCA9IHgpLCBiaW53aWR0aCA9IDAuMDEpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDE6MTApDQoNCmZpbHRlcihkaWFtb25kcywgeSA+IDAsIHkgPCAxMCkgJT4lDQogIGdncGxvdCgpICsNCiAgZ2VvbV9oaXN0b2dyYW0obWFwcGluZyA9IGFlcyh4ID0geSksIGJpbndpZHRoID0gMC4wMSkgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gMToxMCkNCg0KZmlsdGVyKGRpYW1vbmRzLCB6ID4gMCwgeiA8IDEwKSAlPiUNCiAgZ2dwbG90KCkgKw0KICBnZW9tX2hpc3RvZ3JhbShtYXBwaW5nID0gYWVzKHggPSB6KSwgYmlud2lkdGggPSAwLjAxKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAxOjEwKQ0KYGBgDQoNCkFjY29yZGluZyB0byB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgW2RpYW1vbmRzXShodHRwczovL2dncGxvdDIudGlkeXZlcnNlLm9yZy9yZWZlcmVuY2UvZGlhbW9uZHMuaHRtbCksIGB4YCBpcyBsZW5ndGgsIGB5YCBpcyB3aWR0aCwgYW5kIGB6YCBpcyBkZXB0aC4gSWYgZG9jdW1lbnRhdGlvbiB3ZXJlIHVuYXZhaWxhYmxlLCBJIHdvdWxkIGNvbXBhcmUgdGhlIHZhbHVlcyBvZiB0aGUgdmFyaWFibGVzIHRvIG1hdGNoIHRoZW0gdG8gdGhlIGxlbmd0aCwgd2lkdGgsIGFuZCBkZXB0aC4gSSB3b3VsZCBleHBlY3QgbGVuZ3RoIHRvIGFsd2F5cyBiZSBsZXNzIHRoYW4gd2lkdGgsIG90aGVyd2lzZSB0aGUgbGVuZ3RoIHdvdWxkIGJlIGNhbGxlZCB0aGUgd2lkdGguIEkgd291bGQgYWxzbyBzZWFyY2ggZm9yIHRoZSBkZWZpbml0aW9ucyBvZiBsZW5ndGgsIHdpZHRoLCBhbmQgZGVwdGggd2l0aCByZXNwZWN0IHRvIGRpYW1vbmQgY3V0cy4gW0RlcHRoXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EaWFtb25kX2N1dCkgY2FuIGJlIGV4cHJlc3NlZCBhcyBhIHBlcmNlbnRhZ2Ugb2YgdGhlIGxlbmd0aC93aWR0aCBvZiB0aGUgZGlhbW9uZCwgd2hpY2ggbWVhbnMgaXQgc2hvdWxkIGJlIGxlc3MgdGhhbiBib3RoIHRoZSBsZW5ndGggYW5kIHRoZSB3aWR0aC4NCg0KYGBge3J9DQpzdW1tYXJpc2UoZGlhbW9uZHMsIG1lYW4oeCA+IHkpLCBtZWFuKHggPiB6KSwgbWVhbih5ID4geikpDQpgYGANCg0KSXQgYXBwZWFycyB0aGF0IGRlcHRoIChgemApIGlzIGFsd2F5cyBzbWFsbGVyIHRoYW4gbGVuZ3RoIChgeGApIG9yIHdpZHRoIChgeWApLCBwZXJoYXBzIGJlY2F1c2UgYSBzaGFsbG93ZXIgZGVwdGggaGVscHMgd2hlbiBzZXR0aW5nIGRpYW1vbmRzIGluIGpld2VscnkgYW5kIGR1ZSB0byBob3cgaXQgYWZmZWN0IHRoZSByZWZsZWN0aW9uIG9mIGxpZ2h0LiBMZW5ndGggaXMgbW9yZSB0aGFuIHdpZHRoIGluIGxlc3MgdGhhbiBoYWxmIHRoZSBvYnNlcnZhdGlvbnMsIHRoZSBvcHBvc2l0ZSBvZiBteSBleHBlY3RhdGlvbnMuDQoNCiMjIyAyLiBFeHBsb3JlIHRoZSBkaXN0cmlidXRpb24gb2YgcHJpY2UuIERvIHlvdSBkaXNjb3ZlciBhbnl0aGluZyB1bnVzdWFsIG9yIHN1cnByaXNpbmc/IChIaW50OiBDYXJlZnVsbHkgdGhpbmsgYWJvdXQgdGhlIGBiaW53aWR0aGAgYW5kIG1ha2Ugc3VyZSB5b3UgdHJ5IGEgd2lkZSByYW5nZSBvZiB2YWx1ZXMuKQ0KDQogLSBUaGUgcHJpY2UgZGF0YSBoYXMgbWFueSBzcGlrZXMsIGJ1dCBJIGNhbuKAmXQgdGVsbCB3aGF0IGVhY2ggc3Bpa2UgY29ycmVzcG9uZHMgdG8uIFRoZSBmb2xsb3dpbmcgcGxvdHMgZG9u4oCZdCBzaG93IG11Y2ggZGlmZmVyZW5jZSBpbiB0aGUgZGlzdHJpYnV0aW9ucyBpbiB0aGUgbGFzdCBvbmUgb3IgdHdvIGRpZ2l0cy4NCiAtIFRoZXJlIGFyZSBubyBkaWFtb25kcyB3aXRoIGEgcHJpY2Ugb2YgJDEsNTAwIChiZXR3ZWVuICQxLDQ1MCBhbmQgJDEsNTUwKS4NCiAtIFRoZXJl4oCZcyBhIGJ1bGdlIGluIHRoZSBkaXN0cmlidXRpb24gYXJvdW5kICQ3NTAuDQoNCmBgYHtyfQ0KZ2dwbG90KGZpbHRlcihkaWFtb25kcywgcHJpY2UgPCAyNTAwKSwgYWVzKHggPSBwcmljZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxMCwgY2VudGVyID0gMCkNCg0KZ2dwbG90KGZpbHRlcihkaWFtb25kcyksIGFlcyh4ID0gcHJpY2UpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMTAwLCBjZW50ZXIgPSAwKQ0KYGBgDQoNCkRpc3RyaWJ1dGlvbiBvZiBsYXN0IGRpZ2l0DQoNCmBgYHtyfQ0KZGlhbW9uZHMgJT4lDQogIG11dGF0ZShlbmRpbmcgPSBwcmljZSAlJSAxMCkgJT4lDQogIGdncGxvdChhZXMoeCA9IGVuZGluZykpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxLCBjZW50ZXIgPSAwKQ0KDQpkaWFtb25kcyAlPiUNCiAgbXV0YXRlKGVuZGluZyA9IHByaWNlICUlIDEwMCkgJT4lDQogIGdncGxvdChhZXMoeCA9IGVuZGluZykpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxKQ0KDQpkaWFtb25kcyAlPiUNCiAgbXV0YXRlKGVuZGluZyA9IHByaWNlICUlIDEwMDApICU+JQ0KICBmaWx0ZXIoZW5kaW5nID49IDUwMCwgZW5kaW5nIDw9IDgwMCkgJT4lDQogIGdncGxvdChhZXMoeCA9IGVuZGluZykpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxKQ0KYGBgDQoNCiMjIyAzLiBIb3cgbWFueSBkaWFtb25kcyBhcmUgMC45OSBjYXJhdD8gSG93IG1hbnkgYXJlIDEgY2FyYXQ/IFdoYXQgZG8geW91IHRoaW5rIGlzIHRoZSBjYXVzZSBvZiB0aGUgZGlmZmVyZW5jZT8NCg0KVGhlcmUgYXJlIG1vcmUgdGhhbiA3MCB0aW1lcyBhcyBtYW55IDEgY2FyYXQgZGlhbW9uZHMgYXMgMC45OSBjYXJhdCBkaWFtb25kLg0KDQpgYGB7cn0NCmRpYW1vbmRzICU+JQ0KICBmaWx0ZXIoY2FyYXQgPj0gMC45OSwgY2FyYXQgPD0gMSkgJT4lDQogIGNvdW50KGNhcmF0KQ0KYGBgDQoNCkkgZG9u4oCZdCBrbm93IGV4YWN0bHkgdGhlIHByb2Nlc3MgYmVoaW5kIGhvdyBjYXJhdHMgYXJlIG1lYXN1cmVkLCBidXQgc29tZSB3YXkgb3IgYW5vdGhlciBzb21lIGRpYW1vbmRzIGNhcmF0IHZhbHVlcyBhcmUgYmVpbmcg4oCccm91bmRlZCB1cOKAnSBQcmVzdW1hYmx5IHRoZXJlIGlzIGEgcHJlbWl1bSBmb3IgYSAxIGNhcmF0IGRpYW1vbmQgdnMuIGEgMC45OSBjYXJhdCBkaWFtb25kIGJleW9uZCB0aGUgZXhwZWN0ZWQgaW5jcmVhc2UgaW4gcHJpY2UgZHVlIHRvIGEgMC4wMSBjYXJhdCBpbmNyZWFzZS4NCg0KVG8gY2hlY2sgdGhpcyBpbnR1aXRpb24sIHdlIHdvdWxkIHdhbnQgdG8gbG9vayBhdCB0aGUgbnVtYmVyIG9mIGRpYW1vbmRzIGluIGVhY2ggY2FyYXQgcmFuZ2UgdG8gc2VlIGlmIHRoZXJlIGlzIGFuIHVudXN1YWxseSBsb3cgbnVtYmVyIG9mIDAuOTkgY2FyYXQgZGlhbW9uZHMsIGFuZCBhbiBhYm5vcm1hbGx5IGxhcmdlIG51bWJlciBvZiAxIGNhcmF0IGRpYW1vbmRzLg0KDQpgYGB7cn0NCmRpYW1vbmRzICU+JQ0KICBmaWx0ZXIoY2FyYXQgPj0gMC45LCBjYXJhdCA8PSAxLjEpICU+JQ0KICBjb3VudChjYXJhdCkgJT4lDQogIHByaW50KG4gPSBJbmYpDQpgYGANCg0KDQojIyMgNC4gQ29tcGFyZSBhbmQgY29udHJhc3QgYGNvb3JkX2NhcnRlc2lhbigpYCB2cyBgeGxpbSgpYCBvciBgeWxpbSgpYCB3aGVuIHpvb21pbmcgaW4gb24gYSBoaXN0b2dyYW0uIFdoYXQgaGFwcGVucyBpZiB5b3UgbGVhdmUgYGJpbndpZHRoYCB1bnNldD8gV2hhdCBoYXBwZW5zIGlmIHlvdSB0cnkgYW5kIHpvb20gc28gb25seSBoYWxmIGEgYmFyIHNob3dzPw0KDQpUaGUgYGNvb3JkX2NhcnRlc2lhbigpYCBmdW5jdGlvbiB6b29tcyBpbiBvbiB0aGUgYXJlYSBzcGVjaWZpZWQgYnkgdGhlIGxpbWl0cywgYWZ0ZXIgaGF2aW5nIGNhbGN1bGF0ZWQgYW5kIGRyYXduIHRoZSBnZW9tcy4gU2luY2UgdGhlIGhpc3RvZ3JhbSBiaW5zIGhhdmUgYWxyZWFkeSBiZWVuIGNhbGN1bGF0ZWQsIGl0IGlzIHVuYWZmZWN0ZWQuDQoNCmBgYHtyfQ0KZ2dwbG90KGRpYW1vbmRzKSArDQogIGdlb21faGlzdG9ncmFtKG1hcHBpbmcgPSBhZXMoeCA9IHByaWNlKSkgKw0KICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMTAwLCA1MDAwKSwgeWxpbSA9IGMoMCwgMzAwMCkpDQpgYGANCg0KSG93ZXZlciwgdGhlIGB4bGltKClgIGFuZCBgeWxpbSgpYCBmdW5jdGlvbnMgaW5mbHVlbmNlIGFjdGlvbnMgYmVmb3JlIHRoZSBjYWxjdWxhdGlvbiBvZiB0aGUgc3RhdHMgcmVsYXRlZCB0byB0aGUgaGlzdG9ncmFtLiBUaHVzLCBhbnkgdmFsdWVzIG91dHNpZGUgdGhlIHgtIGFuZCB5LWxpbWl0cyBhcmUgZHJvcHBlZCBiZWZvcmUgY2FsY3VsYXRpbmcgYmluIHdpZHRocyBhbmQgY291bnRzLiBUaGlzIGNhbiBpbmZsdWVuY2UgaG93IHRoZSBoaXN0b2dyYW0gbG9va3MuDQoNCmBgYHtyfQ0KZ2dwbG90KGRpYW1vbmRzKSArDQogIGdlb21faGlzdG9ncmFtKG1hcHBpbmcgPSBhZXMoeCA9IHByaWNlKSkgKw0KICB4bGltKDEwMCwgNTAwMCkgKw0KICB5bGltKDAsIDMwMDApDQpgYGANCg0K