1.Range Review

One of the most common statistics to describe a dataset is the range. The range of a dataset is the difference between the maximum and minimum values. While this descriptive statistic is a good start, it is important to consider the impact outliers have on the results:

knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Interquartile1.png")

In this image, most of the data is between 0 and 15. However, there is one large negative outlier (-20) and one large positive outlier (40). This makes the range of the dataset 60 (The difference between 40 and -20). That’s not very representative of the spread of the majority of the data!

The interquartile range (IQR) is a descriptive statistic that tries to solve this problem. The IQR ignores the tails of the dataset, so you know the range around-which your data is centered.

In this lesson, we’ll teach you how to calculate the interquartile range and interpret it.

Instructions

1.We’ve imported a dataset of song lengths (measured in seconds) and plotted a histogram.

It looks like there are some outliers — this might be a good opportunity to use the IQR.

Before we do that, let’s calculate the range. We’ve found the maximum and minimum values of the dataset and stored them in variables named maximum and minimum.

Create a variable named song_range and set it equal to the difference between the maximum and the minimum.

# load libraries
library(ggplot2)
# load song data
load("songs.Rda")
# find maximum and minimum song lengths
maximum <- max(songs)
minimum <- min(songs)
# create variable song_range here:
song_range <- maximum - minimum
song_range

[1] 983.5102

knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Interquartile2.png")

# ignore the code below here:

tryCatch(print(paste("The range of the dataset is",song_range)), error=function(e) {print("You haven't defined the variable song_range yet")})

[1] “The range of the dataset is 983.51021”

2.Quartiles

The interquartile range is the difference between the third quartile (Q3) and the first quartile (Q1). If you need a refresher on quartiles, you can take a look at our lesson.

For now, all you need to know is that the first quartile is the value that separates the first 25% of the data from the remaining 75%.

The third quartile is the opposite — it separates the first 75% of the data from the remaining 25%.

knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Interquartile3.png")

The interquartile range is the difference between these two values.

Instructions

1.We’ve calculated the first quartile of songs and stored it in the variable q1.

Calculate the third quartile and store it in a variable named q3.

To calculate the third quartile, call the same function, but change the second argument to 0.75.

# load song data
load("songs.Rda")
# find the first quartile
q1 <- quantile(songs,0.25)
q1
 25% 

175.9342

# calculate the third quartile here:
q3 <- quantile(songs,0.75)
q3
 75% 

275.4738

2.Now that we have both the first quartile and the third quartile, let’s calculate the IQR.

Create a variable named interquartile_range and set it equal to the difference between q3 and q1.

# calculate the interquartile range here:
interquartile_range <- q3 - q1
interquartile_range
 75% 

99.53959

# ignore the code below here:

tryCatch(print(paste("The first quartile of the dataset is",q1)), error=function(e) {print("You haven't defined q1 yet")})

tryCatch(print(paste("The third quartile of the dataset is",q3)), error=function(e) {print("You haven't defined q3 yet")})

tryCatch(print(paste("The IQR of the dataset is",interquartile_range)), error=function(e) {print("You haven't defined interquartile_range yet")})

[1] “The first quartile of the dataset is 175.93424”

[1] “The third quartile of the dataset is 275.47383”

[1] “The IQR of the dataset is 99.53959”

3.IQR in R

In the last exercise, we calculated the IQR by finding the quartiles using R and finding the difference ourselves. The stats library has a function that can calculate the IQR all in one step.

The IQR() function takes a dataset as a parameter and returns the Interquartile Range.

dataset = c(4, 10, 38, 85, 193)
interquartile_range = IQR(dataset)
interquartile_range
[1] 75

Instructions

1.Let’s calculate the IQR again, but this time, use the stats function.

Create a variable named interquartile_range and set it equal to the result of calling IQR() using songs as an argument.

# create the variable interquartile_range here
interquartile_range <- IQR(songs)
interquartile_range

[1] 99.53959

# ignore the code below here:

tryCatch(print(paste("The IQR of the dataset is",interquartile_range)), error=function(e) {print("You haven't defined interquartile_range yet")})

[1] “The IQR of the dataset is 99.53959”

4.Review

Nice work! You can now calculate the Interquartile Range of a dataset using R. The main takeaway of the IQR is that it is a statistic, like the range, that helps describe the spread of the center of the data.

However, unlike the range, the IQR is robust. A statistic is robust when outliers have little impact on it. For example, the IQRs of the two datasets below are identical, even though one has a massive outlier.

dataset_one = c(6, 9, 10, 45, 190, 200) # IQR is 144.5

dataset_two = c(6, 9, 10, 45, 190, 20000000) # IQR is 144.5

By looking at the IQR instead of the range, you can get a better sense of the spread of the middle of the data.

The interquartile range is displayed in a commonly-used graph — the box plot.

knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Interquartile4.png")

In a box plot, the ends of the box are Q1 and Q3. So the length of the box is the IQR.

Instrctions

We’ve set up a small dataset and are printing its range and IQR.

Try changing the maximum number in the dataset to different values.

What happens to the range when you make the maximum value 100000? What happens to the IQR?

Try changing the minimum value to be more of an outlier as well.

# small dataset
dataset = c(-500000, -50, -24, -13, -2, 0, 12, 15, 18, 73, 90, 100, 100000)

# calculate range and IQR
dataset_range = max(dataset) - min(dataset)
dataset_iqr = IQR(dataset)

# print range and IQR
print(paste("The range of the dataset is ",dataset_range))
[1] "The range of the dataset is  6e+05"
print(paste("The IQR of the dataset is ",dataset_iqr))
[1] "The IQR of the dataset is  86"
LS0tDQp0aXRsZTogIkludGVycXVhcnRpbGUgUmFuZ2UiDQphdXRob3I6ICJBbm5hYmVsIEt1byINCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVZLSVtLSVkICVIOiVNJylgIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyAxLlJhbmdlIFJldmlldw0KDQpPbmUgb2YgdGhlIG1vc3QgY29tbW9uIHN0YXRpc3RpY3MgdG8gZGVzY3JpYmUgYSBkYXRhc2V0IGlzIHRoZSByYW5nZS4gVGhlIHJhbmdlIG9mIGEgZGF0YXNldCBpcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBtYXhpbXVtIGFuZCBtaW5pbXVtIHZhbHVlcy4gV2hpbGUgdGhpcyBkZXNjcmlwdGl2ZSBzdGF0aXN0aWMgaXMgYSBnb29kIHN0YXJ0LCBpdCBpcyBpbXBvcnRhbnQgdG8gY29uc2lkZXIgdGhlIGltcGFjdCBvdXRsaWVycyBoYXZlIG9uIHRoZSByZXN1bHRzOg0KDQpgYGB7ciBJbnRlcnF1YXJ0aWxlMSwgb3V0LndpZHRoPSI2MCUifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkM6L1VzZXJzL2t1b2FuL0Rlc2t0b3AvUiBDb2RlL0ludGVycXVhcnRpbGUxLnBuZyIpDQpgYGANCg0KSW4gdGhpcyBpbWFnZSwgbW9zdCBvZiB0aGUgZGF0YSBpcyBiZXR3ZWVuIDAgYW5kIDE1LiBIb3dldmVyLCB0aGVyZSBpcyBvbmUgbGFyZ2UgbmVnYXRpdmUgb3V0bGllciAoLTIwKSBhbmQgb25lIGxhcmdlIHBvc2l0aXZlIG91dGxpZXIgKDQwKS4gVGhpcyBtYWtlcyB0aGUgcmFuZ2Ugb2YgdGhlIGRhdGFzZXQgNjAgKFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gNDAgYW5kIC0yMCkuIFRoYXTigJlzIG5vdCB2ZXJ5IHJlcHJlc2VudGF0aXZlIG9mIHRoZSBzcHJlYWQgb2YgdGhlIG1ham9yaXR5IG9mIHRoZSBkYXRhIQ0KDQpUaGUgaW50ZXJxdWFydGlsZSByYW5nZSAoSVFSKSBpcyBhIGRlc2NyaXB0aXZlIHN0YXRpc3RpYyB0aGF0IHRyaWVzIHRvIHNvbHZlIHRoaXMgcHJvYmxlbS4gVGhlIElRUiBpZ25vcmVzIHRoZSB0YWlscyBvZiB0aGUgZGF0YXNldCwgc28geW91IGtub3cgdGhlIHJhbmdlIGFyb3VuZC13aGljaCB5b3VyIGRhdGEgaXMgY2VudGVyZWQuDQoNCkluIHRoaXMgbGVzc29uLCB3ZeKAmWxsIHRlYWNoIHlvdSBob3cgdG8gY2FsY3VsYXRlIHRoZSBpbnRlcnF1YXJ0aWxlIHJhbmdlIGFuZCBpbnRlcnByZXQgaXQuDQoNCiMjIEluc3RydWN0aW9ucw0KDQoxLldl4oCZdmUgaW1wb3J0ZWQgYSBkYXRhc2V0IG9mIHNvbmcgbGVuZ3RocyAobWVhc3VyZWQgaW4gc2Vjb25kcykgYW5kIHBsb3R0ZWQgYSBoaXN0b2dyYW0uDQoNCkl0IGxvb2tzIGxpa2UgdGhlcmUgYXJlIHNvbWUgb3V0bGllcnMg4oCUIHRoaXMgbWlnaHQgYmUgYSBnb29kIG9wcG9ydHVuaXR5IHRvIHVzZSB0aGUgSVFSLg0KDQpCZWZvcmUgd2UgZG8gdGhhdCwgbGV04oCZcyBjYWxjdWxhdGUgdGhlIHJhbmdlLiBXZeKAmXZlIGZvdW5kIHRoZSBtYXhpbXVtIGFuZCBtaW5pbXVtIHZhbHVlcyBvZiB0aGUgZGF0YXNldCBhbmQgc3RvcmVkIHRoZW0gaW4gdmFyaWFibGVzIG5hbWVkIG1heGltdW0gYW5kIG1pbmltdW0uDQoNCkNyZWF0ZSBhIHZhcmlhYmxlIG5hbWVkIHNvbmdfcmFuZ2UgYW5kIHNldCBpdCBlcXVhbCB0byB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBtYXhpbXVtIGFuZCB0aGUgbWluaW11bS4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgbG9hZCBsaWJyYXJpZXMNCmxpYnJhcnkoZ2dwbG90MikNCmBgYA0KDQpgYGB7cn0NCiMgbG9hZCBzb25nIGRhdGENCmxvYWQoInNvbmdzLlJkYSIpDQpgYGANCg0KYGBge3J9DQojIGZpbmQgbWF4aW11bSBhbmQgbWluaW11bSBzb25nIGxlbmd0aHMNCm1heGltdW0gPC0gbWF4KHNvbmdzKQ0KbWluaW11bSA8LSBtaW4oc29uZ3MpDQpgYGANCg0KYGBge3J9DQojIGNyZWF0ZSB2YXJpYWJsZSBzb25nX3JhbmdlIGhlcmU6DQpzb25nX3JhbmdlIDwtIG1heGltdW0gLSBtaW5pbXVtDQpzb25nX3JhbmdlDQpgYGANCg0KWzFdIDk4My41MTAyDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0V9DQojIHBsb3QgaGlzdG9ncmFtDQpoaXN0IDwtIHFwbG90KHNvbmdzLA0KICAgICAgICAgICAgICBnZW9tPSJoaXN0b2dyYW0iLA0KICAgICAgICAgICAgICBtYWluID0gJ0hpc3RvZ3JhbSBvZiBTb25nIExlbmd0aHMnLA0KICAgICAgICAgICAgICB4bGFiID0gJ1NvbmcgTGVuZ3RoIChTZWNvbmRzKScsDQogICAgICAgICAgICAgIHlsYWIgPSAnQ291bnQnLA0KICAgICAgICAgICAgICBmaWxsPUkoImJsdWUiKSwNCiAgICAgICAgICAgICAgY29sPUkoInJlZCIpLA0KICAgICAgICAgICAgICBhbHBoYT1JKC4yKSkNCmhpc3QNCmBgYA0KDQpgYGB7ciBJbnRlcnF1YXJ0aWxlMiwgb3V0LndpZHRoPSI2MCUifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkM6L1VzZXJzL2t1b2FuL0Rlc2t0b3AvUiBDb2RlL0ludGVycXVhcnRpbGUyLnBuZyIpDQpgYGANCg0KYGBge3J9DQojIGlnbm9yZSB0aGUgY29kZSBiZWxvdyBoZXJlOg0KDQp0cnlDYXRjaChwcmludChwYXN0ZSgiVGhlIHJhbmdlIG9mIHRoZSBkYXRhc2V0IGlzIixzb25nX3JhbmdlKSksIGVycm9yPWZ1bmN0aW9uKGUpIHtwcmludCgiWW91IGhhdmVuJ3QgZGVmaW5lZCB0aGUgdmFyaWFibGUgc29uZ19yYW5nZSB5ZXQiKX0pDQpgYGANCg0KWzFdICJUaGUgcmFuZ2Ugb2YgdGhlIGRhdGFzZXQgaXMgOTgzLjUxMDIxIg0KDQojIDIuUXVhcnRpbGVzDQoNClRoZSBpbnRlcnF1YXJ0aWxlIHJhbmdlIGlzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHRoaXJkIHF1YXJ0aWxlIChRMykgYW5kIHRoZSBmaXJzdCBxdWFydGlsZSAoUTEpLiBJZiB5b3UgbmVlZCBhIHJlZnJlc2hlciBvbiBxdWFydGlsZXMsIHlvdSBjYW4gdGFrZSBhIGxvb2sgYXQgb3VyIGxlc3Nvbi4NCg0KRm9yIG5vdywgYWxsIHlvdSBuZWVkIHRvIGtub3cgaXMgdGhhdCB0aGUgZmlyc3QgcXVhcnRpbGUgaXMgdGhlIHZhbHVlIHRoYXQgc2VwYXJhdGVzIHRoZSBmaXJzdCAyNSUgb2YgdGhlIGRhdGEgZnJvbSB0aGUgcmVtYWluaW5nIDc1JS4NCg0KVGhlIHRoaXJkIHF1YXJ0aWxlIGlzIHRoZSBvcHBvc2l0ZSDigJQgaXQgc2VwYXJhdGVzIHRoZSBmaXJzdCA3NSUgb2YgdGhlIGRhdGEgZnJvbSB0aGUgcmVtYWluaW5nIDI1JS4NCg0KYGBge3IgSW50ZXJxdWFydGlsZTMsIG91dC53aWR0aD0iNjAlIn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJDOi9Vc2Vycy9rdW9hbi9EZXNrdG9wL1IgQ29kZS9JbnRlcnF1YXJ0aWxlMy5wbmciKQ0KYGBgDQoNClRoZSBpbnRlcnF1YXJ0aWxlIHJhbmdlIGlzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlc2UgdHdvIHZhbHVlcy4NCg0KIyMgSW5zdHJ1Y3Rpb25zDQoNCjEuV2XigJl2ZSBjYWxjdWxhdGVkIHRoZSBmaXJzdCBxdWFydGlsZSBvZiBzb25ncyBhbmQgc3RvcmVkIGl0IGluIHRoZSB2YXJpYWJsZSBxMS4NCg0KQ2FsY3VsYXRlIHRoZSB0aGlyZCBxdWFydGlsZSBhbmQgc3RvcmUgaXQgaW4gYSB2YXJpYWJsZSBuYW1lZCBxMy4NCg0KVG8gY2FsY3VsYXRlIHRoZSB0aGlyZCBxdWFydGlsZSwgY2FsbCB0aGUgc2FtZSBmdW5jdGlvbiwgYnV0IGNoYW5nZSB0aGUgc2Vjb25kIGFyZ3VtZW50IHRvIDAuNzUuDQoNCmBgYHtyfQ0KIyBsb2FkIHNvbmcgZGF0YQ0KbG9hZCgic29uZ3MuUmRhIikNCmBgYA0KDQpgYGB7cn0NCiMgZmluZCB0aGUgZmlyc3QgcXVhcnRpbGUNCnExIDwtIHF1YW50aWxlKHNvbmdzLDAuMjUpDQpxMQ0KYGBgDQoNCiAgICAgMjUlIA0KMTc1LjkzNDIgDQoNCmBgYHtyfQ0KIyBjYWxjdWxhdGUgdGhlIHRoaXJkIHF1YXJ0aWxlIGhlcmU6DQpxMyA8LSBxdWFudGlsZShzb25ncywwLjc1KQ0KcTMNCmBgYA0KDQogICAgIDc1JSANCjI3NS40NzM4IA0KDQoyLk5vdyB0aGF0IHdlIGhhdmUgYm90aCB0aGUgZmlyc3QgcXVhcnRpbGUgYW5kIHRoZSB0aGlyZCBxdWFydGlsZSwgbGV04oCZcyBjYWxjdWxhdGUgdGhlIElRUi4NCg0KQ3JlYXRlIGEgdmFyaWFibGUgbmFtZWQgaW50ZXJxdWFydGlsZV9yYW5nZSBhbmQgc2V0IGl0IGVxdWFsIHRvIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gcTMgYW5kIHExLg0KDQpgYGB7cn0NCiMgY2FsY3VsYXRlIHRoZSBpbnRlcnF1YXJ0aWxlIHJhbmdlIGhlcmU6DQppbnRlcnF1YXJ0aWxlX3JhbmdlIDwtIHEzIC0gcTENCmludGVycXVhcnRpbGVfcmFuZ2UNCmBgYA0KDQogICAgIDc1JSANCjk5LjUzOTU5IA0KDQpgYGB7cn0NCiMgaWdub3JlIHRoZSBjb2RlIGJlbG93IGhlcmU6DQoNCnRyeUNhdGNoKHByaW50KHBhc3RlKCJUaGUgZmlyc3QgcXVhcnRpbGUgb2YgdGhlIGRhdGFzZXQgaXMiLHExKSksIGVycm9yPWZ1bmN0aW9uKGUpIHtwcmludCgiWW91IGhhdmVuJ3QgZGVmaW5lZCBxMSB5ZXQiKX0pDQoNCnRyeUNhdGNoKHByaW50KHBhc3RlKCJUaGUgdGhpcmQgcXVhcnRpbGUgb2YgdGhlIGRhdGFzZXQgaXMiLHEzKSksIGVycm9yPWZ1bmN0aW9uKGUpIHtwcmludCgiWW91IGhhdmVuJ3QgZGVmaW5lZCBxMyB5ZXQiKX0pDQoNCnRyeUNhdGNoKHByaW50KHBhc3RlKCJUaGUgSVFSIG9mIHRoZSBkYXRhc2V0IGlzIixpbnRlcnF1YXJ0aWxlX3JhbmdlKSksIGVycm9yPWZ1bmN0aW9uKGUpIHtwcmludCgiWW91IGhhdmVuJ3QgZGVmaW5lZCBpbnRlcnF1YXJ0aWxlX3JhbmdlIHlldCIpfSkNCmBgYA0KDQpbMV0gIlRoZSBmaXJzdCBxdWFydGlsZSBvZiB0aGUgZGF0YXNldCBpcyAxNzUuOTM0MjQiDQoNClsxXSAiVGhlIHRoaXJkIHF1YXJ0aWxlIG9mIHRoZSBkYXRhc2V0IGlzIDI3NS40NzM4MyINCg0KWzFdICJUaGUgSVFSIG9mIHRoZSBkYXRhc2V0IGlzIDk5LjUzOTU5Ig0KDQojIDMuSVFSIGluIFINCg0KSW4gdGhlIGxhc3QgZXhlcmNpc2UsIHdlIGNhbGN1bGF0ZWQgdGhlIElRUiBieSBmaW5kaW5nIHRoZSBxdWFydGlsZXMgdXNpbmcgUiBhbmQgZmluZGluZyB0aGUgZGlmZmVyZW5jZSBvdXJzZWx2ZXMuIFRoZSBzdGF0cyBsaWJyYXJ5IGhhcyBhIGZ1bmN0aW9uIHRoYXQgY2FuIGNhbGN1bGF0ZSB0aGUgSVFSIGFsbCBpbiBvbmUgc3RlcC4NCg0KVGhlIElRUigpIGZ1bmN0aW9uIHRha2VzIGEgZGF0YXNldCBhcyBhIHBhcmFtZXRlciBhbmQgcmV0dXJucyB0aGUgSW50ZXJxdWFydGlsZSBSYW5nZS4NCg0KYGBge3J9DQpkYXRhc2V0ID0gYyg0LCAxMCwgMzgsIDg1LCAxOTMpDQppbnRlcnF1YXJ0aWxlX3JhbmdlID0gSVFSKGRhdGFzZXQpDQppbnRlcnF1YXJ0aWxlX3JhbmdlDQpgYGANCg0KIyMgSW5zdHJ1Y3Rpb25zDQoNCjEuTGV04oCZcyBjYWxjdWxhdGUgdGhlIElRUiBhZ2FpbiwgYnV0IHRoaXMgdGltZSwgdXNlIHRoZSBzdGF0cyBmdW5jdGlvbi4NCg0KQ3JlYXRlIGEgdmFyaWFibGUgbmFtZWQgaW50ZXJxdWFydGlsZV9yYW5nZSBhbmQgc2V0IGl0IGVxdWFsIHRvIHRoZSByZXN1bHQgb2YgY2FsbGluZyBJUVIoKSB1c2luZyBzb25ncyBhcyBhbiBhcmd1bWVudC4NCg0KYGBge3J9DQojIGNyZWF0ZSB0aGUgdmFyaWFibGUgaW50ZXJxdWFydGlsZV9yYW5nZSBoZXJlDQppbnRlcnF1YXJ0aWxlX3JhbmdlIDwtIElRUihzb25ncykNCmludGVycXVhcnRpbGVfcmFuZ2UNCmBgYA0KDQpbMV0gOTkuNTM5NTkNCg0KYGBge3J9DQojIGlnbm9yZSB0aGUgY29kZSBiZWxvdyBoZXJlOg0KDQp0cnlDYXRjaChwcmludChwYXN0ZSgiVGhlIElRUiBvZiB0aGUgZGF0YXNldCBpcyIsaW50ZXJxdWFydGlsZV9yYW5nZSkpLCBlcnJvcj1mdW5jdGlvbihlKSB7cHJpbnQoIllvdSBoYXZlbid0IGRlZmluZWQgaW50ZXJxdWFydGlsZV9yYW5nZSB5ZXQiKX0pDQpgYGANCg0KWzFdICJUaGUgSVFSIG9mIHRoZSBkYXRhc2V0IGlzIDk5LjUzOTU5Ig0KDQojIDQuUmV2aWV3DQoNCk5pY2Ugd29yayEgWW91IGNhbiBub3cgY2FsY3VsYXRlIHRoZSBJbnRlcnF1YXJ0aWxlIFJhbmdlIG9mIGEgZGF0YXNldCB1c2luZyBSLiBUaGUgbWFpbiB0YWtlYXdheSBvZiB0aGUgSVFSIGlzIHRoYXQgaXQgaXMgYSBzdGF0aXN0aWMsIGxpa2UgdGhlIHJhbmdlLCB0aGF0IGhlbHBzIGRlc2NyaWJlIHRoZSBzcHJlYWQgb2YgdGhlIGNlbnRlciBvZiB0aGUgZGF0YS4NCg0KSG93ZXZlciwgdW5saWtlIHRoZSByYW5nZSwgdGhlIElRUiBpcyByb2J1c3QuIEEgc3RhdGlzdGljIGlzIHJvYnVzdCB3aGVuIG91dGxpZXJzIGhhdmUgbGl0dGxlIGltcGFjdCBvbiBpdC4gRm9yIGV4YW1wbGUsIHRoZSBJUVJzIG9mIHRoZSB0d28gZGF0YXNldHMgYmVsb3cgYXJlIGlkZW50aWNhbCwgZXZlbiB0aG91Z2ggb25lIGhhcyBhIG1hc3NpdmUgb3V0bGllci4NCg0KZGF0YXNldF9vbmUgPSBjKDYsIDksIDEwLCA0NSwgMTkwLCAyMDApICMgSVFSIGlzIDE0NC41DQoNCmRhdGFzZXRfdHdvID0gYyg2LCA5LCAxMCwgNDUsIDE5MCwgMjAwMDAwMDApICMgSVFSIGlzIDE0NC41DQoNCkJ5IGxvb2tpbmcgYXQgdGhlIElRUiBpbnN0ZWFkIG9mIHRoZSByYW5nZSwgeW91IGNhbiBnZXQgYSBiZXR0ZXIgc2Vuc2Ugb2YgdGhlIHNwcmVhZCBvZiB0aGUgbWlkZGxlIG9mIHRoZSBkYXRhLg0KDQpUaGUgaW50ZXJxdWFydGlsZSByYW5nZSBpcyBkaXNwbGF5ZWQgaW4gYSBjb21tb25seS11c2VkIGdyYXBoIOKAlCB0aGUgYm94IHBsb3QuDQoNCmBgYHtyIEludGVycXVhcnRpbGU0LCBvdXQud2lkdGg9IjYwJSJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQzovVXNlcnMva3VvYW4vRGVza3RvcC9SIENvZGUvSW50ZXJxdWFydGlsZTQucG5nIikNCmBgYA0KDQpJbiBhIGJveCBwbG90LCB0aGUgZW5kcyBvZiB0aGUgYm94IGFyZSBRMSBhbmQgUTMuIFNvIHRoZSBsZW5ndGggb2YgdGhlIGJveCBpcyB0aGUgSVFSLg0KDQojIyBJbnN0cmN0aW9ucw0KDQpXZeKAmXZlIHNldCB1cCBhIHNtYWxsIGRhdGFzZXQgYW5kIGFyZSBwcmludGluZyBpdHMgcmFuZ2UgYW5kIElRUi4NCg0KVHJ5IGNoYW5naW5nIHRoZSBtYXhpbXVtIG51bWJlciBpbiB0aGUgZGF0YXNldCB0byBkaWZmZXJlbnQgdmFsdWVzLg0KDQpXaGF0IGhhcHBlbnMgdG8gdGhlIHJhbmdlIHdoZW4geW91IG1ha2UgdGhlIG1heGltdW0gdmFsdWUgMTAwMDAwPyBXaGF0IGhhcHBlbnMgdG8gdGhlIElRUj8NCg0KVHJ5IGNoYW5naW5nIHRoZSBtaW5pbXVtIHZhbHVlIHRvIGJlIG1vcmUgb2YgYW4gb3V0bGllciBhcyB3ZWxsLg0KYGBge3J9DQojIHNtYWxsIGRhdGFzZXQNCmRhdGFzZXQgPSBjKC01MDAwMDAsIC01MCwgLTI0LCAtMTMsIC0yLCAwLCAxMiwgMTUsIDE4LCA3MywgOTAsIDEwMCwgMTAwMDAwKQ0KDQojIGNhbGN1bGF0ZSByYW5nZSBhbmQgSVFSDQpkYXRhc2V0X3JhbmdlID0gbWF4KGRhdGFzZXQpIC0gbWluKGRhdGFzZXQpDQpkYXRhc2V0X2lxciA9IElRUihkYXRhc2V0KQ0KDQojIHByaW50IHJhbmdlIGFuZCBJUVINCnByaW50KHBhc3RlKCJUaGUgcmFuZ2Ugb2YgdGhlIGRhdGFzZXQgaXMgIixkYXRhc2V0X3JhbmdlKSkNCnByaW50KHBhc3RlKCJUaGUgSVFSIG9mIHRoZSBkYXRhc2V0IGlzICIsZGF0YXNldF9pcXIpKQ0KYGBgDQoNCg==