Data Types
Numeric
The numeric data type are commonly used for scientific or
statistical computations where decimal values and high precision are
often required. You can perform arithmetic operations on
numeric variables in R, such as addition, subtraction,
multiplication, and division.
The numeric data type in R is used to represent both integer
and floating-point numbers. You can create a numeric variable
in R by simply assigning a value to it using the assignment operator,
‘<-’. For example:
x <- 100 # integer
y <- 3.1415926 # floating-point number
R will automatically choose the appropriate data type (integer or
floating-point) depending on the operands and the result of the
operation.
You can use the typeof() function to check the data type of
a variable in R, as shown below:
x <- 100
typeof(x) # returns "double"
## [1] "double"
y <- 3.1415926
typeof(y) # returns "double"
## [1] "double"
R uses the “double” precision data type to represent numeric
values, which provides high precision and can represent a wide range of
values. However, it is important to consider memory usage and
performance when working with large data sets or computationally
intensive operations. The numeric data types can use more
memory than the integer data type we will talk about next, so
it may be preferable to use the integer data type when possible
to optimize memory usage.
Integer
In R, the integer are a specific type of numeric data type
used to represent whole numbers without a fractional component. The
integer data type uses less memory than the numeric
data type, which can make it more efficient for certain operations.
You can create an integer variable in R by simply assigning a value
that is a whole number, without a decimal component. For example:
x <- 100
typeof(x) # returns "double" (implicitly converted to numeric data type)
## [1] "double"
However, it’s important to note that the above assignment implicitly
converts the value to a numeric data type, which uses more
memory. To explicitly create an integer variable, you have to
use the ‘as.integer()’ function. For example:
y <- as.integer(100)
typeof(y) # returns "integer"
## [1] "integer"
You can also explicitly declare an integer variable by using
the ‘L’ suffix when assigning a value. For example:
z <- 5L
typeof(z) # returns "integer"
## [1] "integer"
You can perform arithmetic operations on integer variables
in R, including addition, subtraction, multiplication, and division. R
will automatically choose the appropriate data type (integer or
floating-point) depending on the operands and the result of the
operation. So when working with integer variables in R, it’s
important to ensure that you’re not inadvertently converting them to
numeric data types, which can result in precision loss and increased
memory usage. To ensure that an integer variable remains an
integer, you can use the ‘as.integer()’ function or the ‘L’ suffix when
assigning a value.
Complex
The complex data type represents complex numbers in R, which
have both real and imaginary components. You can create a
complex variable in R using the ‘complex()’ function, which
takes two arguments: the real component and the imaginary component. For
example:
z <- complex(real = 2, imaginary = 3)
You can access the real and imaginary components of a
complex variable using the Re() and Im() functions,
respectively. For example:
z <- complex(real = 2, imaginary = 3)
z
## [1] 2+3i
Re(z) # returns 2
## [1] 2
Im(z) # returns 3
## [1] 3
You can perform arithmetic operations on complex variables
in R, including addition, subtraction, multiplication, and division. R
will automatically apply the appropriate rules for complex arithmetic,
which take into account both the real and imaginary components of the
numbers.
To calculate the magnitude (or absolute value) of a complex
number, you can use the ‘abs()’ function. To calculate the angle (or
argument) of a complex number, you can use the ‘Arg()’
function, which returns the result in radians. For example:
z <- complex(real = 2, imaginary = 3)
z
## [1] 2+3i
abs(z) # returns 3.605551
## [1] 3.605551
Arg(z) # returns 0.9827937 (in radians)
## [1] 0.9827937
Character
The character data type is used to represent text or strings
of characters in R. Text data can include letters, numbers, and special
characters, and can be of variable length. A character data
type is created by enclosing the text in single or double quotation
marks. For example:
name <- 'Alex Lee'
typeof(name) # returns "charater"
## [1] "character"
name <- "Alex Lee"
typeof(name) # returns "character"
## [1] "character"
You can concatenate two or more character variables using
the ‘paste()’ or ‘paste0()’ functions. The ‘paste()’ function separates
the concatenated variables with a space, while the ‘paste0()’ function
concatenates them without a separator. For example:
first_name <- "Alex"
last_name <- "Lee"
full_name <- paste(first_name, last_name, sep = " ")
full_name # returns "Alex Lee"
## [1] "Alex Lee"
full_name_no_sep <- paste0(first_name, last_name)
full_name_no_sep # returns "AlexLee"
## [1] "AlexLee"
Logical
The logical data type represents true/false values in R. It
is created using the TRUE and FALSE keywords. For example:
is_raining <- TRUE
typeof(is_raining) # returns "logical"
## [1] "logical"
You can perform logical operations on logical variables in
R, including negation (!), conjunction (& or &&), and
disjunction (| or ||). R applies the appropriate rules for logical
operations based on the truth values of the operands.
To perform conditional operations on logical variables, you
can use the ‘ifelse()’ function, which takes three arguments: a logical
expression, a value to return if the expression is true, and a value to
return if the expression is false. For example:
x <- 10
y <- ifelse(x > 5, "greater than 5", "less than or equal to 5")
y # returns "greater than 5"
## [1] "greater than 5"
When working with logical variables in R, it is important to
be aware of issues related to truth values and logical operators. For
example, the && and || operators only evaluate the first operand
if the result can be determined from that operand alone, which can lead
to unexpected results if the second operand has side effects.
Raw
The raw data type in R is used to represent binary data in
its original form, such as the contents of a file or a network packet.
Each element of a raw vector represents a single byte of data,
with values ranging from 0x00 to 0xFF (hexadecimal) or 0 to 255
(decimal).
To create a raw vector in R, you can use the ‘as.raw()’
function, which takes a numeric vector as input and returns a
raw vector. For example, the following code creates a
raw vector with the hexadecimal values for the ASCII characters
“Hello”:
x <- as.raw(c(0x48, 0x65, 0x6c, 0x6c, 0x6f))
cat(rawToChar(x)) # output: "Hello"
## Hello
You can also create a raw vector with the decimal values for
the same ASCII characters:
x <- as.raw(c(72, 101, 108, 108, 111))
cat(rawToChar(x)) # output: "Hello"
## Hello
Once you have a raw vector, you can manipulate its values
using various functions and operators in R. For example, you can extract
a single byte from a raw vector using the [ ] operator, like
this:
x <- as.raw(c(0x48, 0x65, 0x6c, 0x6c, 0x6f))
byte <- x[1] # extract the first byte (0x48)
byte
## [1] 48
You can also combine raw vectors using the ‘c()’ function,
like this:
x1 <- as.raw(c(0x48, 0x65, 0x6c))
x2 <- as.raw(c(0x6c, 0x6f))
x3 <- c(x1, x2) # combine the two raw vectors into one
x3
## [1] 48 65 6c 6c 6f
Finally, you can convert a raw vector to a character string
using the ‘rawToChar()’ function, like this:
x <- as.raw(c(0x48, 0x65, 0x6c, 0x6c, 0x6f))
str <- rawToChar(x) # convert the raw vector to a character string ("Hello")
str
## [1] "Hello"
LS0tCnRpdGxlOiAiT3ZlcnZpZXcgb2YgUiBEYXRhIFR5cGVzIgphdXRob3I6ICJFbG0gQ29tcHV0aW5nIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDIKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiB5ZXMKICAgIGNzczogc3R5bGVzLmNzcwogICAgY29kZV9kb3dubG9hZDogeWVzCiAgICB0aGVtZTogcmVhZGFibGUKICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAnMicKICB3b3JkX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzInCi0tLQoKIyBJbnRyb2R1Y3Rpb24KClIgY29tZXMgd2l0aCBzZXZlcmFsIGJ1aWx0LWluIGRhdGEgdHlwZXMsIHdoaWNoIGluY2x1ZGUgKm51bWVyaWMqLCAqaW50ZWdlciosICpjb21wbGV4KiwgKmNoYXJhY3RlciosICpsb2dpY2FsKiwgYW5kICpyYXcqLiBJbiB0aGlzIGFydGljbGUsIHdlJ2xsIGJyaWVmbHkgZGlzY3VzcyBlYWNoIGRhdGEgdHlwZSBhbmQgcHJvdmlkZSBzb21lIGNvZGUgZXhhbXBsZXMgdG8gaWxsdXN0cmF0ZSB0aGVpciB1c2FnZS4KCiMgRGF0YSBUeXBlcwojIyBOdW1lcmljCgpUaGUgKm51bWVyaWMqIGRhdGEgdHlwZSBhcmUgY29tbW9ubHkgdXNlZCBmb3Igc2NpZW50aWZpYyBvciBzdGF0aXN0aWNhbCBjb21wdXRhdGlvbnMgd2hlcmUgZGVjaW1hbCB2YWx1ZXMgYW5kIGhpZ2ggcHJlY2lzaW9uIGFyZSBvZnRlbiByZXF1aXJlZC4gWW91IGNhbiBwZXJmb3JtIGFyaXRobWV0aWMgb3BlcmF0aW9ucyBvbiAqbnVtZXJpYyogdmFyaWFibGVzIGluIFIsIHN1Y2ggYXMgYWRkaXRpb24sIHN1YnRyYWN0aW9uLCBtdWx0aXBsaWNhdGlvbiwgYW5kIGRpdmlzaW9uLiAKClRoZSAqbnVtZXJpYyogZGF0YSB0eXBlIGluIFIgaXMgdXNlZCB0byByZXByZXNlbnQgYm90aCBpbnRlZ2VyIGFuZCBmbG9hdGluZy1wb2ludCBudW1iZXJzLiBZb3UgY2FuIGNyZWF0ZSBhICpudW1lcmljKiB2YXJpYWJsZSBpbiBSIGJ5IHNpbXBseSBhc3NpZ25pbmcgYSB2YWx1ZSB0byBpdCB1c2luZyB0aGUgYXNzaWdubWVudCBvcGVyYXRvciwgJzwtJy4gRm9yIGV4YW1wbGU6CgoKYGBge3J9CnggPC0gMTAwICMgaW50ZWdlcgoKeSA8LSAzLjE0MTU5MjYgIyBmbG9hdGluZy1wb2ludCBudW1iZXIKYGBgCgpSIHdpbGwgYXV0b21hdGljYWxseSBjaG9vc2UgdGhlIGFwcHJvcHJpYXRlIGRhdGEgdHlwZSAoaW50ZWdlciBvciBmbG9hdGluZy1wb2ludCkgZGVwZW5kaW5nIG9uIHRoZSBvcGVyYW5kcyBhbmQgdGhlIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uLgoKWW91IGNhbiB1c2UgdGhlICp0eXBlb2YoKSogZnVuY3Rpb24gdG8gY2hlY2sgdGhlIGRhdGEgdHlwZSBvZiBhIHZhcmlhYmxlIGluIFIsIGFzIHNob3duIGJlbG93OgoKYGBge3J9CnggPC0gMTAwCnR5cGVvZih4KSAjIHJldHVybnMgImRvdWJsZSIKCnkgPC0gMy4xNDE1OTI2CnR5cGVvZih5KSAjIHJldHVybnMgImRvdWJsZSIKYGBgCgpSIHVzZXMgdGhlICJkb3VibGUiIHByZWNpc2lvbiBkYXRhIHR5cGUgdG8gcmVwcmVzZW50ICpudW1lcmljKiB2YWx1ZXMsIHdoaWNoIHByb3ZpZGVzIGhpZ2ggcHJlY2lzaW9uIGFuZCBjYW4gcmVwcmVzZW50IGEgd2lkZSByYW5nZSBvZiB2YWx1ZXMuIEhvd2V2ZXIsIGl0IGlzIGltcG9ydGFudCB0byBjb25zaWRlciBtZW1vcnkgdXNhZ2UgYW5kIHBlcmZvcm1hbmNlIHdoZW4gd29ya2luZyB3aXRoIGxhcmdlIGRhdGEgc2V0cyBvciBjb21wdXRhdGlvbmFsbHkgaW50ZW5zaXZlIG9wZXJhdGlvbnMuIFRoZSAqbnVtZXJpYyogZGF0YSB0eXBlcyBjYW4gdXNlIG1vcmUgbWVtb3J5IHRoYW4gdGhlICppbnRlZ2VyKiBkYXRhIHR5cGUgd2Ugd2lsbCB0YWxrIGFib3V0IG5leHQsIHNvIGl0IG1heSBiZSBwcmVmZXJhYmxlIHRvIHVzZSB0aGUgKmludGVnZXIqIGRhdGEgdHlwZSB3aGVuIHBvc3NpYmxlIHRvIG9wdGltaXplIG1lbW9yeSB1c2FnZS4KCiMjIEludGVnZXIKCkluIFIsIHRoZSAqaW50ZWdlciogYXJlIGEgc3BlY2lmaWMgdHlwZSBvZiBudW1lcmljIGRhdGEgdHlwZSB1c2VkIHRvIHJlcHJlc2VudCB3aG9sZSBudW1iZXJzIHdpdGhvdXQgYSBmcmFjdGlvbmFsIGNvbXBvbmVudC4gVGhlICppbnRlZ2VyKiBkYXRhIHR5cGUgdXNlcyBsZXNzIG1lbW9yeSB0aGFuIHRoZSAqbnVtZXJpYyogZGF0YSB0eXBlLCB3aGljaCBjYW4gbWFrZSBpdCBtb3JlIGVmZmljaWVudCBmb3IgY2VydGFpbiBvcGVyYXRpb25zLgoKWW91IGNhbiBjcmVhdGUgYW4gaW50ZWdlciB2YXJpYWJsZSBpbiBSIGJ5IHNpbXBseSBhc3NpZ25pbmcgYSB2YWx1ZSB0aGF0IGlzIGEgd2hvbGUgbnVtYmVyLCB3aXRob3V0IGEgZGVjaW1hbCBjb21wb25lbnQuIEZvciBleGFtcGxlOgoKYGBge3J9CnggPC0gMTAwCnR5cGVvZih4KSAjIHJldHVybnMgImRvdWJsZSIgKGltcGxpY2l0bHkgY29udmVydGVkIHRvIG51bWVyaWMgZGF0YSB0eXBlKQpgYGAKCkhvd2V2ZXIsIGl0J3MgaW1wb3J0YW50IHRvIG5vdGUgdGhhdCB0aGUgYWJvdmUgYXNzaWdubWVudCBpbXBsaWNpdGx5IGNvbnZlcnRzIHRoZSB2YWx1ZSB0byBhICpudW1lcmljKiBkYXRhIHR5cGUsIHdoaWNoIHVzZXMgbW9yZSBtZW1vcnkuIFRvIGV4cGxpY2l0bHkgY3JlYXRlIGFuICppbnRlZ2VyKiB2YXJpYWJsZSwgeW91IGhhdmUgdG8gdXNlIHRoZSAnYXMuaW50ZWdlcigpJyBmdW5jdGlvbi4gRm9yIGV4YW1wbGU6CgoKYGBge3J9CnkgPC0gYXMuaW50ZWdlcigxMDApCnR5cGVvZih5KSAjIHJldHVybnMgImludGVnZXIiCmBgYAoKWW91IGNhbiBhbHNvIGV4cGxpY2l0bHkgZGVjbGFyZSBhbiAqaW50ZWdlciogdmFyaWFibGUgYnkgdXNpbmcgdGhlICdMJyBzdWZmaXggd2hlbiBhc3NpZ25pbmcgYSB2YWx1ZS4gRm9yIGV4YW1wbGU6CgoKYGBge3J9CnogPC0gNUwKdHlwZW9mKHopICMgcmV0dXJucyAiaW50ZWdlciIKYGBgCgpZb3UgY2FuIHBlcmZvcm0gYXJpdGhtZXRpYyBvcGVyYXRpb25zIG9uICppbnRlZ2VyKiB2YXJpYWJsZXMgaW4gUiwgaW5jbHVkaW5nIGFkZGl0aW9uLCBzdWJ0cmFjdGlvbiwgbXVsdGlwbGljYXRpb24sIGFuZCBkaXZpc2lvbi4gUiB3aWxsIGF1dG9tYXRpY2FsbHkgY2hvb3NlIHRoZSBhcHByb3ByaWF0ZSBkYXRhIHR5cGUgKGludGVnZXIgb3IgZmxvYXRpbmctcG9pbnQpIGRlcGVuZGluZyBvbiB0aGUgb3BlcmFuZHMgYW5kIHRoZSByZXN1bHQgb2YgdGhlIG9wZXJhdGlvbi4gU28gd2hlbiB3b3JraW5nIHdpdGggKmludGVnZXIqIHZhcmlhYmxlcyBpbiBSLCBpdCdzIGltcG9ydGFudCB0byBlbnN1cmUgdGhhdCB5b3UncmUgbm90IGluYWR2ZXJ0ZW50bHkgY29udmVydGluZyB0aGVtIHRvIG51bWVyaWMgZGF0YSB0eXBlcywgd2hpY2ggY2FuIHJlc3VsdCBpbiBwcmVjaXNpb24gbG9zcyBhbmQgaW5jcmVhc2VkIG1lbW9yeSB1c2FnZS4gVG8gZW5zdXJlIHRoYXQgYW4gKmludGVnZXIqIHZhcmlhYmxlIHJlbWFpbnMgYW4gaW50ZWdlciwgeW91IGNhbiB1c2UgdGhlICdhcy5pbnRlZ2VyKCknIGZ1bmN0aW9uIG9yIHRoZSAnTCcgc3VmZml4IHdoZW4gYXNzaWduaW5nIGEgdmFsdWUuCgojIyBDb21wbGV4CgpUaGUgKmNvbXBsZXgqIGRhdGEgdHlwZSByZXByZXNlbnRzIGNvbXBsZXggbnVtYmVycyBpbiBSLCB3aGljaCBoYXZlIGJvdGggcmVhbCBhbmQgaW1hZ2luYXJ5IGNvbXBvbmVudHMuIFlvdSBjYW4gY3JlYXRlIGEgKmNvbXBsZXgqIHZhcmlhYmxlIGluIFIgdXNpbmcgdGhlICdjb21wbGV4KCknIGZ1bmN0aW9uLCB3aGljaCB0YWtlcyB0d28gYXJndW1lbnRzOiB0aGUgcmVhbCBjb21wb25lbnQgYW5kIHRoZSBpbWFnaW5hcnkgY29tcG9uZW50LiBGb3IgZXhhbXBsZToKCmBgYHtyfQp6IDwtIGNvbXBsZXgocmVhbCA9IDIsIGltYWdpbmFyeSA9IDMpCmBgYAoKWW91IGNhbiBhY2Nlc3MgdGhlIHJlYWwgYW5kIGltYWdpbmFyeSBjb21wb25lbnRzIG9mIGEgKmNvbXBsZXgqIHZhcmlhYmxlIHVzaW5nIHRoZSBSZSgpIGFuZCBJbSgpIGZ1bmN0aW9ucywgcmVzcGVjdGl2ZWx5LiBGb3IgZXhhbXBsZToKCmBgYHtyfQp6IDwtIGNvbXBsZXgocmVhbCA9IDIsIGltYWdpbmFyeSA9IDMpCnoKUmUoeikgIyByZXR1cm5zIDIKSW0oeikgIyByZXR1cm5zIDMKYGBgCgpZb3UgY2FuIHBlcmZvcm0gYXJpdGhtZXRpYyBvcGVyYXRpb25zIG9uICpjb21wbGV4KiB2YXJpYWJsZXMgaW4gUiwgaW5jbHVkaW5nIGFkZGl0aW9uLCBzdWJ0cmFjdGlvbiwgbXVsdGlwbGljYXRpb24sIGFuZCBkaXZpc2lvbi4gUiB3aWxsIGF1dG9tYXRpY2FsbHkgYXBwbHkgdGhlIGFwcHJvcHJpYXRlIHJ1bGVzIGZvciBjb21wbGV4IGFyaXRobWV0aWMsIHdoaWNoIHRha2UgaW50byBhY2NvdW50IGJvdGggdGhlIHJlYWwgYW5kIGltYWdpbmFyeSBjb21wb25lbnRzIG9mIHRoZSBudW1iZXJzLgoKVG8gY2FsY3VsYXRlIHRoZSBtYWduaXR1ZGUgKG9yIGFic29sdXRlIHZhbHVlKSBvZiBhICpjb21wbGV4KiBudW1iZXIsIHlvdSBjYW4gdXNlIHRoZSAnYWJzKCknIGZ1bmN0aW9uLiBUbyBjYWxjdWxhdGUgdGhlIGFuZ2xlIChvciBhcmd1bWVudCkgb2YgYSAqY29tcGxleCogbnVtYmVyLCB5b3UgY2FuIHVzZSB0aGUgJ0FyZygpJyBmdW5jdGlvbiwgd2hpY2ggcmV0dXJucyB0aGUgcmVzdWx0IGluIHJhZGlhbnMuIEZvciBleGFtcGxlOgoKYGBge3J9CnogPC0gY29tcGxleChyZWFsID0gMiwgaW1hZ2luYXJ5ID0gMykKegphYnMoeikgIyByZXR1cm5zIDMuNjA1NTUxCkFyZyh6KSAjIHJldHVybnMgMC45ODI3OTM3IChpbiByYWRpYW5zKQpgYGAKCiMjIENoYXJhY3RlcgoKVGhlICpjaGFyYWN0ZXIqIGRhdGEgdHlwZSBpcyB1c2VkIHRvIHJlcHJlc2VudCB0ZXh0IG9yIHN0cmluZ3Mgb2YgY2hhcmFjdGVycyBpbiBSLiBUZXh0IGRhdGEgY2FuIGluY2x1ZGUgbGV0dGVycywgbnVtYmVycywgYW5kIHNwZWNpYWwgY2hhcmFjdGVycywgYW5kIGNhbiBiZSBvZiB2YXJpYWJsZSBsZW5ndGguIEEgKmNoYXJhY3RlciogZGF0YSB0eXBlIGlzIGNyZWF0ZWQgYnkgZW5jbG9zaW5nIHRoZSB0ZXh0IGluIHNpbmdsZSBvciBkb3VibGUgcXVvdGF0aW9uIG1hcmtzLiBGb3IgZXhhbXBsZToKCgpgYGB7cn0KbmFtZSA8LSAnQWxleCBMZWUnCnR5cGVvZihuYW1lKSAjIHJldHVybnMgImNoYXJhdGVyIgoKbmFtZSA8LSAiQWxleCBMZWUiCnR5cGVvZihuYW1lKSAjIHJldHVybnMgImNoYXJhY3RlciIKYGBgCgpZb3UgY2FuIGNvbmNhdGVuYXRlIHR3byBvciBtb3JlICpjaGFyYWN0ZXIqIHZhcmlhYmxlcyB1c2luZyB0aGUgJ3Bhc3RlKCknIG9yICdwYXN0ZTAoKScgZnVuY3Rpb25zLiBUaGUgJ3Bhc3RlKCknIGZ1bmN0aW9uIHNlcGFyYXRlcyB0aGUgY29uY2F0ZW5hdGVkIHZhcmlhYmxlcyB3aXRoIGEgc3BhY2UsIHdoaWxlIHRoZSAncGFzdGUwKCknIGZ1bmN0aW9uIGNvbmNhdGVuYXRlcyB0aGVtIHdpdGhvdXQgYSBzZXBhcmF0b3IuIEZvciBleGFtcGxlOgoKYGBge3J9CmZpcnN0X25hbWUgPC0gIkFsZXgiCmxhc3RfbmFtZSA8LSAiTGVlIgpmdWxsX25hbWUgPC0gcGFzdGUoZmlyc3RfbmFtZSwgbGFzdF9uYW1lLCBzZXAgPSAiICIpCmZ1bGxfbmFtZSAjIHJldHVybnMgIkFsZXggTGVlIgoKZnVsbF9uYW1lX25vX3NlcCA8LSBwYXN0ZTAoZmlyc3RfbmFtZSwgbGFzdF9uYW1lKQpmdWxsX25hbWVfbm9fc2VwICMgcmV0dXJucyAiQWxleExlZSIKCmBgYAoKCiMjIExvZ2ljYWwKClRoZSAqbG9naWNhbCogZGF0YSB0eXBlIHJlcHJlc2VudHMgdHJ1ZS9mYWxzZSB2YWx1ZXMgaW4gUi4gSXQgaXMgY3JlYXRlZCB1c2luZyB0aGUgVFJVRSBhbmQgRkFMU0Uga2V5d29yZHMuIEZvciBleGFtcGxlOgoKCmBgYHtyfQppc19yYWluaW5nIDwtIFRSVUUKdHlwZW9mKGlzX3JhaW5pbmcpICMgcmV0dXJucyAibG9naWNhbCIKYGBgCgpZb3UgY2FuIHBlcmZvcm0gbG9naWNhbCBvcGVyYXRpb25zIG9uICpsb2dpY2FsKiB2YXJpYWJsZXMgaW4gUiwgaW5jbHVkaW5nIG5lZ2F0aW9uICghKSwgY29uanVuY3Rpb24gKCYgb3IgJiYpLCBhbmQgZGlzanVuY3Rpb24gKHwgb3IgfHwpLiBSIGFwcGxpZXMgdGhlIGFwcHJvcHJpYXRlIHJ1bGVzIGZvciBsb2dpY2FsIG9wZXJhdGlvbnMgYmFzZWQgb24gdGhlIHRydXRoIHZhbHVlcyBvZiB0aGUgb3BlcmFuZHMuCgpUbyBwZXJmb3JtIGNvbmRpdGlvbmFsIG9wZXJhdGlvbnMgb24gKmxvZ2ljYWwqIHZhcmlhYmxlcywgeW91IGNhbiB1c2UgdGhlICdpZmVsc2UoKScgZnVuY3Rpb24sIHdoaWNoIHRha2VzIHRocmVlIGFyZ3VtZW50czogYSBsb2dpY2FsIGV4cHJlc3Npb24sIGEgdmFsdWUgdG8gcmV0dXJuIGlmIHRoZSBleHByZXNzaW9uIGlzIHRydWUsIGFuZCBhIHZhbHVlIHRvIHJldHVybiBpZiB0aGUgZXhwcmVzc2lvbiBpcyBmYWxzZS4gRm9yIGV4YW1wbGU6CgpgYGB7cn0KeCA8LSAxMAp5IDwtIGlmZWxzZSh4ID4gNSwgImdyZWF0ZXIgdGhhbiA1IiwgImxlc3MgdGhhbiBvciBlcXVhbCB0byA1IikKeSAjIHJldHVybnMgImdyZWF0ZXIgdGhhbiA1IgpgYGAKCldoZW4gd29ya2luZyB3aXRoICpsb2dpY2FsKiB2YXJpYWJsZXMgaW4gUiwgaXQgaXMgaW1wb3J0YW50IHRvIGJlIGF3YXJlIG9mIGlzc3VlcyByZWxhdGVkIHRvIHRydXRoIHZhbHVlcyBhbmQgbG9naWNhbCBvcGVyYXRvcnMuIEZvciBleGFtcGxlLCB0aGUgJiYgYW5kIHx8IG9wZXJhdG9ycyBvbmx5IGV2YWx1YXRlIHRoZSBmaXJzdCBvcGVyYW5kIGlmIHRoZSByZXN1bHQgY2FuIGJlIGRldGVybWluZWQgZnJvbSB0aGF0IG9wZXJhbmQgYWxvbmUsIHdoaWNoIGNhbiBsZWFkIHRvIHVuZXhwZWN0ZWQgcmVzdWx0cyBpZiB0aGUgc2Vjb25kIG9wZXJhbmQgaGFzIHNpZGUgZWZmZWN0cy4KCiMjIFJhdwoKVGhlICpyYXcqIGRhdGEgdHlwZSBpbiBSIGlzIHVzZWQgdG8gcmVwcmVzZW50IGJpbmFyeSBkYXRhIGluIGl0cyBvcmlnaW5hbCBmb3JtLCBzdWNoIGFzIHRoZSBjb250ZW50cyBvZiBhIGZpbGUgb3IgYSBuZXR3b3JrIHBhY2tldC4gRWFjaCBlbGVtZW50IG9mIGEgKnJhdyogdmVjdG9yIHJlcHJlc2VudHMgYSBzaW5nbGUgYnl0ZSBvZiBkYXRhLCB3aXRoIHZhbHVlcyByYW5naW5nIGZyb20gMHgwMCB0byAweEZGIChoZXhhZGVjaW1hbCkgb3IgMCB0byAyNTUgKGRlY2ltYWwpLgoKVG8gY3JlYXRlIGEgKnJhdyogdmVjdG9yIGluIFIsIHlvdSBjYW4gdXNlIHRoZSAnYXMucmF3KCknIGZ1bmN0aW9uLCB3aGljaCB0YWtlcyBhICpudW1lcmljKiB2ZWN0b3IgYXMgaW5wdXQgYW5kIHJldHVybnMgYSAqcmF3KiB2ZWN0b3IuIEZvciBleGFtcGxlLCB0aGUgZm9sbG93aW5nIGNvZGUgY3JlYXRlcyBhICpyYXcqIHZlY3RvciB3aXRoIHRoZSBoZXhhZGVjaW1hbCB2YWx1ZXMgZm9yIHRoZSBBU0NJSSBjaGFyYWN0ZXJzICJIZWxsbyI6CmBgYHtyfQp4IDwtIGFzLnJhdyhjKDB4NDgsIDB4NjUsIDB4NmMsIDB4NmMsIDB4NmYpKQpjYXQocmF3VG9DaGFyKHgpKSAjIG91dHB1dDogIkhlbGxvIgpgYGAKCllvdSBjYW4gYWxzbyBjcmVhdGUgYSAqcmF3KiB2ZWN0b3Igd2l0aCB0aGUgZGVjaW1hbCB2YWx1ZXMgZm9yIHRoZSBzYW1lIEFTQ0lJIGNoYXJhY3RlcnM6CgpgYGB7cn0KeCA8LSBhcy5yYXcoYyg3MiwgMTAxLCAxMDgsIDEwOCwgMTExKSkKY2F0KHJhd1RvQ2hhcih4KSkgIyBvdXRwdXQ6ICJIZWxsbyIKYGBgCgpPbmNlIHlvdSBoYXZlIGEgKnJhdyogdmVjdG9yLCB5b3UgY2FuIG1hbmlwdWxhdGUgaXRzIHZhbHVlcyB1c2luZyB2YXJpb3VzIGZ1bmN0aW9ucyBhbmQgb3BlcmF0b3JzIGluIFIuIEZvciBleGFtcGxlLCB5b3UgY2FuIGV4dHJhY3QgYSBzaW5nbGUgYnl0ZSBmcm9tIGEgKnJhdyogdmVjdG9yIHVzaW5nIHRoZSBbIF0gb3BlcmF0b3IsIGxpa2UgdGhpczoKCmBgYHtyfQp4IDwtIGFzLnJhdyhjKDB4NDgsIDB4NjUsIDB4NmMsIDB4NmMsIDB4NmYpKQpieXRlIDwtIHhbMV0gIyBleHRyYWN0IHRoZSBmaXJzdCBieXRlICgweDQ4KQpieXRlCmBgYAoKWW91IGNhbiBhbHNvIGNvbWJpbmUgKnJhdyogdmVjdG9ycyB1c2luZyB0aGUgJ2MoKScgZnVuY3Rpb24sIGxpa2UgdGhpczoKCmBgYHtyfQp4MSA8LSBhcy5yYXcoYygweDQ4LCAweDY1LCAweDZjKSkKeDIgPC0gYXMucmF3KGMoMHg2YywgMHg2ZikpCngzIDwtIGMoeDEsIHgyKSAjIGNvbWJpbmUgdGhlIHR3byByYXcgdmVjdG9ycyBpbnRvIG9uZQp4MwpgYGAKCkZpbmFsbHksIHlvdSBjYW4gY29udmVydCBhICpyYXcgdmVjdG9yKiB0byBhIGNoYXJhY3RlciBzdHJpbmcgdXNpbmcgdGhlICdyYXdUb0NoYXIoKScgZnVuY3Rpb24sIGxpa2UgdGhpczoKCmBgYHtyfQp4IDwtIGFzLnJhdyhjKDB4NDgsIDB4NjUsIDB4NmMsIDB4NmMsIDB4NmYpKQpzdHIgPC0gcmF3VG9DaGFyKHgpICMgY29udmVydCB0aGUgcmF3IHZlY3RvciB0byBhIGNoYXJhY3RlciBzdHJpbmcgKCJIZWxsbyIpCnN0cgpgYGAKCiMgU3VtbWFyeQoKSW4gc3VtbWFyeSwgUiBoYXMgc2V2ZXJhbCBidWlsdC1pbiBkYXRhIHR5cGVzIHRoYXQgeW91IGNhbiB1c2UgdG8gc3RvcmUgYW5kIG1hbmlwdWxhdGUgZGF0YS4gVGhlc2UgZGF0YSB0eXBlcyBpbmNsdWRlIG51bWVyaWMsIGludGVnZXIsIGNvbXBsZXgsIGNoYXJhY3RlciwgbG9naWNhbCBhbmQgcmF3LiBVbmRlcnN0YW5kaW5nIHRoZSBkaWZmZXJlbnQgZGF0YSB0eXBlcyBpbiBSIGlzIGVzc2VudGlhbCBmb3Igd29ya2luZyB3aXRoIGRhdGEgZWZmZWN0aXZlbHku