Introduction

The purpose of this assignment is to work with data manipulation involving strings and by using regex and testing the regular expressions by programming in R.

Import Libraries

library(tidyverse)
library(openintro)

Part 1

  1. Using the 173 majors listed in fivethirtyeight.com’s College Majors dataset [https://fivethirtyeight.com/features/the-economic-guide-to-picking-a-college-major/], provide code that identifies the majors that contain either “DATA” or “STATISTICS”
url <- "https://raw.githubusercontent.com/pujaroy280/DATA607Week3/main/all-ages.csv"
college_majors_data <- read.csv(url) # Data has 173 observations (rows) of 11 variables (columns)
head(college_majors_data)
##   Major_code                                 Major
## 1       1100                   GENERAL AGRICULTURE
## 2       1101 AGRICULTURE PRODUCTION AND MANAGEMENT
## 3       1102                AGRICULTURAL ECONOMICS
## 4       1103                       ANIMAL SCIENCES
## 5       1104                          FOOD SCIENCE
## 6       1105            PLANT SCIENCE AND AGRONOMY
##                    Major_category  Total Employed Employed_full_time_year_round
## 1 Agriculture & Natural Resources 128148    90245                         74078
## 2 Agriculture & Natural Resources  95326    76865                         64240
## 3 Agriculture & Natural Resources  33955    26321                         22810
## 4 Agriculture & Natural Resources 103549    81177                         64937
## 5 Agriculture & Natural Resources  24280    17281                         12722
## 6 Agriculture & Natural Resources  79409    63043                         51077
##   Unemployed Unemployment_rate Median P25th P75th
## 1       2423        0.02614711  50000 34000 80000
## 2       2266        0.02863606  54000 36000 80000
## 3        821        0.03024832  63000 40000 98000
## 4       3619        0.04267890  46000 30000 72000
## 5        894        0.04918845  62000 38500 90000
## 6       2070        0.03179089  50000 35000 75000
# The dataset loaded or read into a variable is called 'college_majors_data'

# Filter the dataset to include majors containing either "DATA" or "STATISTICS"
majors_with_data_or_stats <- college_majors_data[grep(pattern = "DATA|STATISTICS", college_majors_data$Major, ignore.case = TRUE), ]

# grep() function is used to search for patterns "DATA" or "STATISTICS" in the Major column of the college_majors dataset. The ignore.case = TRUE argument ensures that the search is case-insensitive.

# Display the filtered majors
print(majors_with_data_or_stats)
##     Major_code                                         Major
## 20        2101      COMPUTER PROGRAMMING AND DATA PROCESSING
## 93        3702               STATISTICS AND DECISION SCIENCE
## 170       6212 MANAGEMENT INFORMATION SYSTEMS AND STATISTICS
##              Major_category  Total Employed Employed_full_time_year_round
## 20  Computers & Mathematics  29317    22828                         18747
## 93  Computers & Mathematics  24806    18808                         14468
## 170                Business 156673   134478                        118249
##     Unemployed Unemployment_rate Median P25th  P75th
## 20        2265        0.09026422  60000 40000  85000
## 93        1138        0.05705405  70000 43000 102000
## 170       6186        0.04397714  72000 50000 100000
majors_with_data_or_stats$Major
## [1] "COMPUTER PROGRAMMING AND DATA PROCESSING"     
## [2] "STATISTICS AND DECISION SCIENCE"              
## [3] "MANAGEMENT INFORMATION SYSTEMS AND STATISTICS"

Only 3 majors appeared and their major category included “Computers & Mathematics” and “Business”.

Part 2

  1. Write code that transforms the data below: [1] “bell pepper” “bilberry” “blackberry” “blood orange” [5] “blueberry” “cantaloupe” “chili pepper” “cloudberry”
    [9] “elderberry” “lime” “lychee” “mulberry”
    [13] “olive” “salal berry” Into a format like this: c(“bell pepper”, “bilberry”, “blackberry”, “blood orange”, “blueberry”, “cantaloupe”, “chili pepper”, “cloudberry”, “elderberry”, “lime”, “lychee”, “mulberry”, “olive”, “salal berry”)
fruits <- c("bell pepper", "bilberry", "blackberry", "blood orange",
                   "blueberry", "cantaloupe", "chili pepper", "cloudberry",
                   "elderberry", "lime", "lychee", "mulberry", "olive",
                   "salal berry")
fruits
##  [1] "bell pepper"  "bilberry"     "blackberry"   "blood orange" "blueberry"   
##  [6] "cantaloupe"   "chili pepper" "cloudberry"   "elderberry"   "lime"        
## [11] "lychee"       "mulberry"     "olive"        "salal berry"
# Transform the data
# str_c is a function from the stringr package of R that concatenates strings.
fruits_transform <- str_c("c(", str_c('"', fruits, '"', collapse = ", "), ")")
str_view(fruits_transform)
## [1] │ c("bell pepper", "bilberry", "blackberry", "blood orange", "blueberry", "cantaloupe", "chili pepper", "cloudberry", "elderberry", "lime", "lychee", "mulberry", "olive", "salal berry")

Part 3

The two exercises below are taken from R for Data Science, 14.3.5.1 in the on-line version: 3) Describe, in words, what these expressions will match: (.)\1\1 “(.)(.)\2\1” (..)\1 “(.).\1.\1” “(.)(.)(.).*\3\2\1”

expression1 <- "(.)\\1\\1"
str_view(expression1)
## [1] │ (.)\1\1
str_view(c(words,"888", "$$$", "ppp"), expression1)
## [981] │ <888>
## [982] │ <$$$>
## [983] │ <ppp>

(.)\1\1 matches any sequence of three characters where the first character is the same as the second and third characters.

expression2 <- "(.)(.)\\2\\1"
str_view(expression2)
## [1] │ (.)(.)\2\1
str_view(c(words), expression2)
##  [19] │ after<noon>
##  [43] │ <appa>rent
##  [53] │ <arra>nge
## [107] │ b<otto>m
## [112] │ br<illi>ant
## [174] │ c<ommo>n
## [230] │ d<iffi>cult
## [259] │ <effe>ct
## [329] │ f<ollo>w
## [422] │ in<deed>
## [470] │ l<ette>r
## [521] │ m<illi>on
## [581] │ <oppo>rtunity
## [582] │ <oppo>se
## [877] │ tom<orro>w

The regular expression: “(.)(.)\2\1” matches a string length of four in which the first+fourth and second+third characters are the same.

expression3 <- "(..)\\1" # naming expression
str_view(expression3) # string view of expression
## [1] │ (..)\1
str_view(c(words, fruit), expression3) # testing matches
##  [696] │ r<emem>ber
##  [984] │ b<anan>a
## [1000] │ <coco>nut
## [1002] │ <cucu>mber
## [1021] │ <juju>be
## [1036] │ <papa>ya
## [1053] │ s<alal> berry

“(..)\1” is a regular expression that matches any string that has 2 identical characters.

expression4 <- "(.).\\1.\\1"
str_view(expression4) 
## [1] │ (.).\1.\1
str_view(c(words, fruit), expression4)
##  [265] │ <eleve>n
##  [984] │ b<anana>
## [1036] │ p<apaya>

The regular expression: “(.).\1.\1” matches a string length of five in which the 3 characters including the first, third and fifth are the same.

expression5 <- "(.)(.)(.).*\\3\\2\\1"
str_view(expression5) 
## [1] │ (.)(.)(.).*\3\2\1
str_view(c(words, fruit, "lalamimilala", "12345fedcba54321"), expression5)
##  [598] │ <paragrap>h
## [1061] │ <lalamimilal>a
## [1062] │ <12345fedcba54321>

The regular expression: “(.)(.)(.).*\3\2\1” matches any string length that starts with three characters that consist of any characters. This expression matches the last three characters of the string in reverse order of the original string.

Part 4

  1. Construct regular expressions to match words that: Start and end with the same character. Contain a repeated pair of letters (e.g. “church” contains “ch” repeated twice.) Contain one letter repeated in at least three places (e.g. “eleven” contains three “e”s.)
expression6 <- "^(.).*\\1$" 
str_view(expression6)
## [1] │ ^(.).*\1$
str_view(c(words), expression6)
##  [36] │ <america>
##  [49] │ <area>
## [209] │ <dad>
## [213] │ <dead>
## [223] │ <depend>
## [258] │ <educate>
## [266] │ <else>
## [268] │ <encourage>
## [270] │ <engine>
## [278] │ <europe>
## [283] │ <evidence>
## [285] │ <example>
## [287] │ <excuse>
## [288] │ <exercise>
## [291] │ <expense>
## [292] │ <experience>
## [296] │ <eye>
## [386] │ <health>
## [394] │ <high>
## [450] │ <knock>
## ... and 16 more
expression7 <- "(..).*\\1"
str_view(expression7)
## [1] │ (..).*\1
str_view(c(words), expression7) 
##  [48] │ ap<propr>iate
## [152] │ <church>
## [181] │ c<ondition>
## [217] │ <decide>
## [275] │ <environmen>t
## [487] │ l<ondon>
## [598] │ pa<ragra>ph
## [603] │ p<articular>
## [617] │ <photograph>
## [638] │ p<repare>
## [641] │ p<ressure>
## [696] │ r<emem>ber
## [698] │ <repre>sent
## [699] │ <require>
## [739] │ <sense>
## [858] │ the<refore>
## [903] │ u<nderstand>
## [946] │ w<hethe>r
expression8 <- "(.).*\\1.*\\1" 
str_view(expression8) 
## [1] │ (.).*\1.*\1
str_view(c(words), expression8)
##  [48] │ a<pprop>riate
##  [62] │ <availa>ble
##  [86] │ b<elieve>
##  [90] │ b<etwee>n
## [119] │ bu<siness>
## [221] │ d<egree>
## [229] │ diff<erence>
## [233] │ di<scuss>
## [265] │ <eleve>n
## [275] │ e<nvironmen>t
## [283] │ <evidence>
## [288] │ <exercise>
## [291] │ <expense>
## [292] │ <experience>
## [423] │ <indivi>dual
## [598] │ p<aragra>ph
## [684] │ r<eceive>
## [696] │ r<emembe>r
## [698] │ r<eprese>nt
## [845] │ t<elephone>
## ... and 2 more

Conclusion

To sum it all up, I learned how to filter and work with regular expressions using Regex and R. It can often be confusing at the beginning due to the syntax, yet working on this assignment was rewarding since it provided me the knowledge of identifying patterns in strings.

LS0tDQp0aXRsZTogIldlZWsgMyBSIENoYXJhY3RlciBNYW5pcHVsYXRpb24gYW5kIERhdGUgUHJvY2Vzc2luZyINCmF1dGhvcjogIlB1amEgUm95Ig0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0OiBvcGVuaW50cm86OmxhYl9yZXBvcnQNCi0tLQ0KDQojIyMgSW50cm9kdWN0aW9uDQpUaGUgcHVycG9zZSBvZiB0aGlzIGFzc2lnbm1lbnQgaXMgdG8gd29yayB3aXRoIGRhdGEgbWFuaXB1bGF0aW9uIGludm9sdmluZyBzdHJpbmdzIGFuZCBieSB1c2luZyByZWdleCBhbmQgdGVzdGluZyB0aGUgcmVndWxhciBleHByZXNzaW9ucyBieSBwcm9ncmFtbWluZyBpbiBSLiANCg0KIyMjIEltcG9ydCBMaWJyYXJpZXMNCmBgYHtyIGxvYWQtcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkob3BlbmludHJvKQ0KYGBgDQoNCiMjIyBQYXJ0IDENCg0KMSkgVXNpbmcgdGhlIDE3MyBtYWpvcnMgbGlzdGVkIGluIGZpdmV0aGlydHllaWdodC5jb23igJlzIENvbGxlZ2UgTWFqb3JzIGRhdGFzZXQgW2h0dHBzOi8vZml2ZXRoaXJ0eWVpZ2h0LmNvbS9mZWF0dXJlcy90aGUtZWNvbm9taWMtZ3VpZGUtdG8tcGlja2luZy1hLWNvbGxlZ2UtbWFqb3IvXSwgcHJvdmlkZSBjb2RlIHRoYXQgaWRlbnRpZmllcyB0aGUgbWFqb3JzIHRoYXQgY29udGFpbiBlaXRoZXIgIkRBVEEiIG9yICJTVEFUSVNUSUNTIg0KDQpgYGB7cn0NCnVybCA8LSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3B1amFyb3kyODAvREFUQTYwN1dlZWszL21haW4vYWxsLWFnZXMuY3N2Ig0KY29sbGVnZV9tYWpvcnNfZGF0YSA8LSByZWFkLmNzdih1cmwpICMgRGF0YSBoYXMgMTczIG9ic2VydmF0aW9ucyAocm93cykgb2YgMTEgdmFyaWFibGVzIChjb2x1bW5zKQ0KYGBgDQoNCmBgYHtyfQ0KaGVhZChjb2xsZWdlX21ham9yc19kYXRhKQ0KYGBgDQoNCmBgYHtyfQ0KIyBUaGUgZGF0YXNldCBsb2FkZWQgb3IgcmVhZCBpbnRvIGEgdmFyaWFibGUgaXMgY2FsbGVkICdjb2xsZWdlX21ham9yc19kYXRhJw0KDQojIEZpbHRlciB0aGUgZGF0YXNldCB0byBpbmNsdWRlIG1ham9ycyBjb250YWluaW5nIGVpdGhlciAiREFUQSIgb3IgIlNUQVRJU1RJQ1MiDQptYWpvcnNfd2l0aF9kYXRhX29yX3N0YXRzIDwtIGNvbGxlZ2VfbWFqb3JzX2RhdGFbZ3JlcChwYXR0ZXJuID0gIkRBVEF8U1RBVElTVElDUyIsIGNvbGxlZ2VfbWFqb3JzX2RhdGEkTWFqb3IsIGlnbm9yZS5jYXNlID0gVFJVRSksIF0NCg0KIyBncmVwKCkgZnVuY3Rpb24gaXMgdXNlZCB0byBzZWFyY2ggZm9yIHBhdHRlcm5zICJEQVRBIiBvciAiU1RBVElTVElDUyIgaW4gdGhlIE1ham9yIGNvbHVtbiBvZiB0aGUgY29sbGVnZV9tYWpvcnMgZGF0YXNldC4gVGhlIGlnbm9yZS5jYXNlID0gVFJVRSBhcmd1bWVudCBlbnN1cmVzIHRoYXQgdGhlIHNlYXJjaCBpcyBjYXNlLWluc2Vuc2l0aXZlLg0KDQojIERpc3BsYXkgdGhlIGZpbHRlcmVkIG1ham9ycw0KcHJpbnQobWFqb3JzX3dpdGhfZGF0YV9vcl9zdGF0cykNCg0KYGBgDQpgYGB7cn0NCm1ham9yc193aXRoX2RhdGFfb3Jfc3RhdHMkTWFqb3INCmBgYA0KT25seSAzIG1ham9ycyBhcHBlYXJlZCBhbmQgdGhlaXIgbWFqb3IgY2F0ZWdvcnkgaW5jbHVkZWQgIkNvbXB1dGVycyAmIE1hdGhlbWF0aWNzIiBhbmQgIkJ1c2luZXNzIi4NCg0KIyMjIFBhcnQgMg0KMikgV3JpdGUgY29kZSB0aGF0IHRyYW5zZm9ybXMgdGhlIGRhdGEgYmVsb3c6DQpbMV0gImJlbGwgcGVwcGVyIiAgImJpbGJlcnJ5IiAgICAgImJsYWNrYmVycnkiICAgImJsb29kIG9yYW5nZSINCls1XSAiYmx1ZWJlcnJ5IiAgICAiY2FudGFsb3VwZSIgICAiY2hpbGkgcGVwcGVyIiAiY2xvdWRiZXJyeSIgIA0KWzldICJlbGRlcmJlcnJ5IiAgICJsaW1lIiAgICAgICAgICJseWNoZWUiICAgICAgICJtdWxiZXJyeSIgICAgDQpbMTNdICJvbGl2ZSIgICAgICAgICJzYWxhbCBiZXJyeSINCkludG8gYSBmb3JtYXQgbGlrZSB0aGlzOg0KYygiYmVsbCBwZXBwZXIiLCAiYmlsYmVycnkiLCAiYmxhY2tiZXJyeSIsICJibG9vZCBvcmFuZ2UiLCAiYmx1ZWJlcnJ5IiwgImNhbnRhbG91cGUiLCAiY2hpbGkgcGVwcGVyIiwgImNsb3VkYmVycnkiLCAiZWxkZXJiZXJyeSIsICJsaW1lIiwgImx5Y2hlZSIsICJtdWxiZXJyeSIsICJvbGl2ZSIsICJzYWxhbCBiZXJyeSIpDQoNCmBgYHtyfQ0KZnJ1aXRzIDwtIGMoImJlbGwgcGVwcGVyIiwgImJpbGJlcnJ5IiwgImJsYWNrYmVycnkiLCAiYmxvb2Qgb3JhbmdlIiwNCiAgICAgICAgICAgICAgICAgICAiYmx1ZWJlcnJ5IiwgImNhbnRhbG91cGUiLCAiY2hpbGkgcGVwcGVyIiwgImNsb3VkYmVycnkiLA0KICAgICAgICAgICAgICAgICAgICJlbGRlcmJlcnJ5IiwgImxpbWUiLCAibHljaGVlIiwgIm11bGJlcnJ5IiwgIm9saXZlIiwNCiAgICAgICAgICAgICAgICAgICAic2FsYWwgYmVycnkiKQ0KZnJ1aXRzDQpgYGANCmBgYHtyfQ0KIyBUcmFuc2Zvcm0gdGhlIGRhdGENCiMgc3RyX2MgaXMgYSBmdW5jdGlvbiBmcm9tIHRoZSBzdHJpbmdyIHBhY2thZ2Ugb2YgUiB0aGF0IGNvbmNhdGVuYXRlcyBzdHJpbmdzLg0KZnJ1aXRzX3RyYW5zZm9ybSA8LSBzdHJfYygiYygiLCBzdHJfYygnIicsIGZydWl0cywgJyInLCBjb2xsYXBzZSA9ICIsICIpLCAiKSIpDQpzdHJfdmlldyhmcnVpdHNfdHJhbnNmb3JtKQ0KYGBgDQoNCiMjIyBQYXJ0IDMNClRoZSB0d28gZXhlcmNpc2VzIGJlbG93IGFyZSB0YWtlbiBmcm9tIFIgZm9yIERhdGEgU2NpZW5jZSwgMTQuMy41LjEgaW4gdGhlIG9uLWxpbmUgdmVyc2lvbjoNCjMpIERlc2NyaWJlLCBpbiB3b3Jkcywgd2hhdCB0aGVzZSBleHByZXNzaW9ucyB3aWxsIG1hdGNoOg0KKC4pXDFcMQ0KIiguKSguKVxcMlxcMSINCiguLilcMQ0KIiguKS5cXDEuXFwxIg0KIiguKSguKSguKS4qXFwzXFwyXFwxIg0KYGBge3J9DQpleHByZXNzaW9uMSA8LSAiKC4pXFwxXFwxIg0Kc3RyX3ZpZXcoZXhwcmVzc2lvbjEpDQoNCnN0cl92aWV3KGMod29yZHMsIjg4OCIsICIkJCQiLCAicHBwIiksIGV4cHJlc3Npb24xKQ0KYGBgDQooLilcMVwxIG1hdGNoZXMgYW55IHNlcXVlbmNlIG9mIHRocmVlIGNoYXJhY3RlcnMgd2hlcmUgdGhlIGZpcnN0IGNoYXJhY3RlciBpcyB0aGUgc2FtZSBhcyB0aGUgc2Vjb25kIGFuZCB0aGlyZCBjaGFyYWN0ZXJzLg0KDQpgYGB7cn0NCmV4cHJlc3Npb24yIDwtICIoLikoLilcXDJcXDEiDQpzdHJfdmlldyhleHByZXNzaW9uMikNCg0Kc3RyX3ZpZXcoYyh3b3JkcyksIGV4cHJlc3Npb24yKQ0KYGBgDQpUaGUgcmVndWxhciBleHByZXNzaW9uOiAiKC4pKC4pXFwyXFwxIiBtYXRjaGVzIGEgc3RyaW5nIGxlbmd0aCBvZiBmb3VyIGluIHdoaWNoIHRoZSBmaXJzdCtmb3VydGggYW5kIHNlY29uZCt0aGlyZCBjaGFyYWN0ZXJzIGFyZSB0aGUgc2FtZS4gDQpgYGB7cn0NCmV4cHJlc3Npb24zIDwtICIoLi4pXFwxIiAjIG5hbWluZyBleHByZXNzaW9uDQpzdHJfdmlldyhleHByZXNzaW9uMykgIyBzdHJpbmcgdmlldyBvZiBleHByZXNzaW9uDQpzdHJfdmlldyhjKHdvcmRzLCBmcnVpdCksIGV4cHJlc3Npb24zKSAjIHRlc3RpbmcgbWF0Y2hlcw0KYGBgDQoiKC4uKVwxIiBpcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0aGF0IG1hdGNoZXMgYW55IHN0cmluZyB0aGF0IGhhcyAyIGlkZW50aWNhbCBjaGFyYWN0ZXJzLg0KYGBge3J9DQpleHByZXNzaW9uNCA8LSAiKC4pLlxcMS5cXDEiDQpzdHJfdmlldyhleHByZXNzaW9uNCkgDQpzdHJfdmlldyhjKHdvcmRzLCBmcnVpdCksIGV4cHJlc3Npb240KQ0KYGBgDQpUaGUgcmVndWxhciBleHByZXNzaW9uOiAiKC4pLlxcMS5cXDEiIG1hdGNoZXMgYSBzdHJpbmcgbGVuZ3RoIG9mIGZpdmUgaW4gd2hpY2ggdGhlIDMgY2hhcmFjdGVycyBpbmNsdWRpbmcgdGhlIGZpcnN0LCB0aGlyZCBhbmQgZmlmdGggYXJlIHRoZSBzYW1lLiANCmBgYHtyfQ0KZXhwcmVzc2lvbjUgPC0gIiguKSguKSguKS4qXFwzXFwyXFwxIg0Kc3RyX3ZpZXcoZXhwcmVzc2lvbjUpIA0Kc3RyX3ZpZXcoYyh3b3JkcywgZnJ1aXQsICJsYWxhbWltaWxhbGEiLCAiMTIzNDVmZWRjYmE1NDMyMSIpLCBleHByZXNzaW9uNSkNCmBgYA0KVGhlIHJlZ3VsYXIgZXhwcmVzc2lvbjogIiguKSguKSguKS4qXFwzXFwyXFwxIiBtYXRjaGVzIGFueSBzdHJpbmcgbGVuZ3RoIHRoYXQgc3RhcnRzIHdpdGggdGhyZWUgY2hhcmFjdGVycyB0aGF0IGNvbnNpc3Qgb2YgYW55IGNoYXJhY3RlcnMuIFRoaXMgZXhwcmVzc2lvbiBtYXRjaGVzIHRoZSBsYXN0IHRocmVlIGNoYXJhY3RlcnMgb2YgdGhlIHN0cmluZyBpbiByZXZlcnNlIG9yZGVyIG9mIHRoZSBvcmlnaW5hbCBzdHJpbmcuDQoNCiMjIyBQYXJ0IDQNCjQpIENvbnN0cnVjdCByZWd1bGFyIGV4cHJlc3Npb25zIHRvIG1hdGNoIHdvcmRzIHRoYXQ6DQpTdGFydCBhbmQgZW5kIHdpdGggdGhlIHNhbWUgY2hhcmFjdGVyLg0KQ29udGFpbiBhIHJlcGVhdGVkIHBhaXIgb2YgbGV0dGVycyAoZS5nLiAiY2h1cmNoIiBjb250YWlucyAiY2giIHJlcGVhdGVkIHR3aWNlLikNCkNvbnRhaW4gb25lIGxldHRlciByZXBlYXRlZCBpbiBhdCBsZWFzdCB0aHJlZSBwbGFjZXMgKGUuZy4gImVsZXZlbiIgY29udGFpbnMgdGhyZWUgImUicy4pDQpgYGB7cn0NCmV4cHJlc3Npb242IDwtICJeKC4pLipcXDEkIiANCnN0cl92aWV3KGV4cHJlc3Npb242KQ0Kc3RyX3ZpZXcoYyh3b3JkcyksIGV4cHJlc3Npb242KQ0KYGBgDQoNCmBgYHtyfQ0KZXhwcmVzc2lvbjcgPC0gIiguLikuKlxcMSINCnN0cl92aWV3KGV4cHJlc3Npb243KQ0Kc3RyX3ZpZXcoYyh3b3JkcyksIGV4cHJlc3Npb243KSANCmBgYA0KDQpgYGB7cn0NCmV4cHJlc3Npb244IDwtICIoLikuKlxcMS4qXFwxIiANCnN0cl92aWV3KGV4cHJlc3Npb244KSANCnN0cl92aWV3KGMod29yZHMpLCBleHByZXNzaW9uOCkNCmBgYA0KDQojIyMgQ29uY2x1c2lvbg0KVG8gc3VtIGl0IGFsbCB1cCwgSSBsZWFybmVkIGhvdyB0byBmaWx0ZXIgYW5kIHdvcmsgd2l0aCByZWd1bGFyIGV4cHJlc3Npb25zIHVzaW5nIFJlZ2V4IGFuZCBSLiBJdCBjYW4gb2Z0ZW4gYmUgY29uZnVzaW5nIGF0IHRoZSBiZWdpbm5pbmcgZHVlIHRvIHRoZSBzeW50YXgsIHlldCB3b3JraW5nIG9uIHRoaXMgYXNzaWdubWVudCB3YXMgcmV3YXJkaW5nIHNpbmNlIGl0IHByb3ZpZGVkIG1lIHRoZSBrbm93bGVkZ2Ugb2YgaWRlbnRpZnlpbmcgcGF0dGVybnMgaW4gc3RyaW5ncy4=