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
- 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
- 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
- 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=