Prequisites

This lesson presumes that you are familiar with the contents of:

Introduction

This lesson provides an explanation of loops in R. Loops are often necessary in R to process data, but where they are required in other programming languages, R programmers can often avoid them by using vector operations or the apply() family of functions. Nevertheless, there are times when they are essential, so R programmers must know how to work with loops.

In computer programming, loops are program control structures that allow the repetition of a sequence of instructions a certain number of times or until a specific condition is met.

There are different types of loops, and R supports the most common ones:

for loop: executes a block of code a specific number of times based on a range of values or a list

while loop: executes a block of code repeatedly as long as a certain condition is true

do-while/repeat loop: executes a block of code at least once and then repeatedly as long as a certain condition is true

Loops can also be nested, which means that one loop can be contained within another loop. This allows for more complex iterations and more efficient programming.

We generally distinguish between “counting loops” that iterate some number of times versus “iterating loops” that iterate over the elements of a vector or list.

Counting Loop: for

The counting loop is actually more like an iterator in R, although it can be set up to mimic the behavior of a typical loop in C/C++, Java, etc., that loops from a low value to a high value. See the examples below.

n = 5
for (i in 1:n) {
  print(i)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5

In the example above, i is the loop variable and it takes on the values in the vector 1:5, i.e., 1, 2, 3, 4, 5

To count down, it would be 5:1 or n:1 in the above code example.

Like other languages, R uses curly braces to enclose the body of the loop, i.e., the statements that are executed repeatedly, once for each value of i. Of course, the loop counter can be any properly named variable.

The example below accesses a vector using positional access, e.g., v[1] accesses the first element. Note that vector, data frames, lists, and arrays are indexed starting at 1 and not 0 as in C-based languages.

v = rnorm(5)      # vector of five random numbers
for (i in 1:length(v)) 
{
  v[i] = v[i] ^ 2
}

print(v)
## [1] 0.00342597 0.21315501 0.77381792 1.22558029 0.13509337

While you can use loops you actually do not need them. If you apply a mathematical operation to a vector, R automatically applies them to each element, but loops might be more natural in the beginning.

# note that you actually do not need loops in R
# this also squares each element in the vector v
v = v ^ 2

As already stated, looping in R is actually iteration over a set: a set of numbers as above or a set of any kind of primitive object, e.g., strings. Note that in the code below, k takes on each value in the vector over which the loop iterates.

s = c("one","two","three","four")

for (k in s) {
  print(k)
}
## [1] "one"
## [1] "two"
## [1] "three"
## [1] "four"

We could have written this using a non-iterator approach as well, which is more like what you’d do in C. Note that length returns the number of elements in a vector, i.e., its “length”.

s = c("one","two","three","four")

for (j in 1:length(s)) {
  print(s[j])
}
## [1] "one"
## [1] "two"
## [1] "three"
## [1] "four"

Iteration Continuation

Continuation of the loop to the next iteration and forgoing processing the remainder of the current iteration is done with next in R, similar to continue in C-based languages such as Java.

In the example below we are already reaching ahead to the if statement. The code fragment echoes only odd number. Of course, you could have done this differently by just iterating over the even numbers from one to twenty, but that would not have allowed us to share this example for using next.

for (i in 1:10) {
  if (!i %% 2) {
    next
  }
  print(i)
}
## [1] 1
## [1] 3
## [1] 5
## [1] 7
## [1] 9

But, just to show you how to iterate over just odd number, we can use the seq() function which generates a sequence of numbers in steps. No if and no break needed – much simpler.

for (i in seq(1, 10, 2)) {
  print(i)
}
## [1] 1
## [1] 3
## [1] 5
## [1] 7
## [1] 9

Or, more explicitly by specifying the parameters by name.

for (i in seq(from = 1, to = 10, by = 2)) {
  print(i)
}
## [1] 1
## [1] 3
## [1] 5
## [1] 7
## [1] 9

To stop the execution of the rest of a loop and to move immediately to the next statement after the loop is done with break in R which is identical to C, C++, Java, etc. In the code below we will find the position of the first occurrence of some number; x is the number we are looking for in v and p is the found position.

v = c(1, 3, 5, 7, 1, 9, 4)
x = 9
p = 0

for (i in 1:length(v)) {
  if (v[i] == x) {
    p = i
    break
  }
}

print(p)
## [1] 6

To be clear, there is a quicker and more efficient way to do this using the which function. This function does not exist is other languages and it shows the power of R. Also, using which is much faster. Incidentally, the code below finds all occurrences of x in v. Note, once again, the use of a vector variable to refer to all elements.

v = c(1, 3, 5, 7, 1, 9, 4)
x = 9

p = which(v == x)

print(p)
## [1] 6

Conditional Loops: while and repeat

Like many other languages, R supports top and bottom tested loops. In the example below we repeatedly ask for a number from the user and only exit the loop if the number is 42. Of course, the example really should be done with a bottom tested loop.

response <- as.integer(readline(prompt="Enter a number: "))

while (response != 42) {   
  print("Sorry, not correct");
  response <- as.integer(readline(prompt="Enter a number: "));
}

In the above example, we are using two new functions. readline is used to read input from the console, while as.integer coerces (or casts in C/C++ terminology) the input to an integer.

The code is above is not very efficient or elegant as it has the code for the user prompt twice. It is really better to ask first and then check the condition: we need a bottom-tested loop.

Let’s look at the same example, but with a repeat loop that runs until a condition is reached and the loop is explicitly exited with break. So, if you want to run the code at least once, use repeat; if the code is run zero or more times, use while. The repeat loop is identical to the do or do while loop found in many other programming languages.

repeat {   
  response <- as.integer(readline(prompt="Enter a number: "));
  if (response == 42) {
    break
  }
  print("Sorry, not correct");
}

There is no equivalent in R for the use of an infinite for loop as in C and C++, e.g., for(;;){ // do something indefinitely } that runs until a condition is reached and then uses break to exit the loop. The repeat loop construct is used instead. There is no testing of a condition in the repeat loop, so there’s no equivalent to the C-like construct do … while.

Conclusion

As you saw, R is not a difficult language to learn as it is similar to other languages and for most language constructs that you are familiar with, there is an equivalent. But it is important that you go beyond this tutorial and learn the “R way” of programming using vectorized operations.


Files & Resources

All Files for Lesson 6.108

References

No references.

Errata

None collected yet. Let us know.

LS0tCnRpdGxlOiAiTG9vcHMgYW5kIEl0ZXJhdGlvbiBpbiBSIgpwYXJhbXM6CiAgdHlwZSA6IGxlc3NvbgogIGNhdGVnb3J5OiA2CiAgbnVtYmVyOiAxMDgKICB0aW1lOiA0NQogIGxldmVsOiBiZWdpbm5lcgogIHRhZ3M6ICJyLHByaW1lcixsb29wcyxpdGVyYXRpb24sYXBwbHkiCiAgZGVzY3JpcHRpb246ICJTaG93cyBob3cgdG8gcGVyZm9ybSBpdGVyYXRpb24gb3ZlcgogICAgICAgICAgICAgICAgdmVjdG9ycyBhbmQgbGlzdHMgdXNpbmcgbG9vcHMgaW4gUi4KICAgICAgICAgICAgICAgIENvbnRyYXRzIGxvb3BzIHdpdGggdmVjdG9yIG9wZXJhdGlvbnMuCiAgICAgICAgICAgICAgICBQcm92aWRlcyB0aW1lIGNvbXBhcmlzb25zLiIKZGF0ZTogIjxzbWFsbD5gciBTeXMuRGF0ZSgpYDwvc21hbGw+IgphdXRob3I6ICI8c21hbGw+TWFydGluIFNjaGVkbGJhdWVyPC9zbWFsbD4iCmVtYWlsOiAibS5zY2hlZGxiYXVlckBuZXUuZWR1IgphZmZpbGl0YXRpb246ICJOb3J0aGVhc3Rlcm4gVW5pdmVyc2l0eSIKb3V0cHV0OiAKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29sbGFwc2VkOiBmYWxzZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IHNwYWNlbGFiCiAgICBoaWdobGlnaHQ6IHRhbmdvCi0tLQoKLS0tCnRpdGxlOiAiPHNtYWxsPmByIHBhcmFtcyRjYXRlZ29yeWAuYHIgcGFyYW1zJG51bWJlcmA8L3NtYWxsPjxici8+PHNwYW4gc3R5bGU9J2NvbG9yOiAjMkU0MDUzOyBmb250LXNpemU6IDAuOWVtJz5gciBybWFya2Rvd246Om1ldGFkYXRhJHRpdGxlYDwvc3Bhbj4iCi0tLQoKYGBge3IgY29kZT14ZnVuOjpyZWFkX3V0ZjgocGFzdGUwKGhlcmU6OmhlcmUoKSwnL1IvX2luc2VydDJEQi5SJykpLCBpbmNsdWRlID0gRkFMU0V9CmBgYAoKIyMgUHJlcXVpc2l0ZXMKClRoaXMgbGVzc29uIHByZXN1bWVzIHRoYXQgeW91IGFyZSBmYW1pbGlhciB3aXRoIHRoZSBjb250ZW50cyBvZjoKCi0gWzYuMTA0IC0tIFF1aWNrIEd1aWRlIHRvIFIgRm9yIFByb2dyYW1tZXJzXShodHRwOi8vYXJ0aWZpY2l1bS51cy9sZXNzb25zLzA2LnIvbC02LTEwNC1yNHByb2dzL2wtNi0xMDQuaHRtbCkKCiMjIEludHJvZHVjdGlvbgoKVGhpcyBsZXNzb24gcHJvdmlkZXMgYW4gZXhwbGFuYXRpb24gb2YgbG9vcHMgaW4gUi4gTG9vcHMgYXJlIG9mdGVuIG5lY2Vzc2FyeSBpbiBSIHRvIHByb2Nlc3MgZGF0YSwgYnV0IHdoZXJlIHRoZXkgYXJlIHJlcXVpcmVkIGluIG90aGVyIHByb2dyYW1taW5nIGxhbmd1YWdlcywgUiBwcm9ncmFtbWVycyBjYW4gb2Z0ZW4gYXZvaWQgdGhlbSBieSB1c2luZyB2ZWN0b3Igb3BlcmF0aW9ucyBvciB0aGUgYGFwcGx5KClgIGZhbWlseSBvZiBmdW5jdGlvbnMuIE5ldmVydGhlbGVzcywgdGhlcmUgYXJlIHRpbWVzIHdoZW4gdGhleSBhcmUgZXNzZW50aWFsLCBzbyBSIHByb2dyYW1tZXJzIG11c3Qga25vdyBob3cgdG8gd29yayB3aXRoIGxvb3BzLgoKSW4gY29tcHV0ZXIgcHJvZ3JhbW1pbmcsIGxvb3BzIGFyZSBwcm9ncmFtIGNvbnRyb2wgc3RydWN0dXJlcyB0aGF0IGFsbG93IHRoZSByZXBldGl0aW9uIG9mIGEgc2VxdWVuY2Ugb2YgaW5zdHJ1Y3Rpb25zIGEgY2VydGFpbiBudW1iZXIgb2YgdGltZXMgb3IgdW50aWwgYSBzcGVjaWZpYyBjb25kaXRpb24gaXMgbWV0LiAKClRoZXJlIGFyZSBkaWZmZXJlbnQgdHlwZXMgb2YgbG9vcHMsIGFuZCBSIHN1cHBvcnRzIHRoZSBtb3N0IGNvbW1vbiBvbmVzOgoKKipmb3IgbG9vcCoqOiBleGVjdXRlcyBhIGJsb2NrIG9mIGNvZGUgYSBzcGVjaWZpYyBudW1iZXIgb2YgdGltZXMgYmFzZWQgb24gYSByYW5nZSBvZiB2YWx1ZXMgb3IgYSBsaXN0CgoqKndoaWxlIGxvb3AqKjogZXhlY3V0ZXMgYSBibG9jayBvZiBjb2RlIHJlcGVhdGVkbHkgYXMgbG9uZyBhcyBhIGNlcnRhaW4gY29uZGl0aW9uIGlzIHRydWUKCioqZG8td2hpbGUvcmVwZWF0IGxvb3AqKjogZXhlY3V0ZXMgYSBibG9jayBvZiBjb2RlIGF0IGxlYXN0IG9uY2UgYW5kIHRoZW4gcmVwZWF0ZWRseSBhcyBsb25nIGFzIGEgY2VydGFpbiBjb25kaXRpb24gaXMgdHJ1ZQoKTG9vcHMgY2FuIGFsc28gYmUgbmVzdGVkLCB3aGljaCBtZWFucyB0aGF0IG9uZSBsb29wIGNhbiBiZSBjb250YWluZWQgd2l0aGluIGFub3RoZXIgbG9vcC4gVGhpcyBhbGxvd3MgZm9yIG1vcmUgY29tcGxleCBpdGVyYXRpb25zIGFuZCBtb3JlIGVmZmljaWVudCBwcm9ncmFtbWluZy4KCldlIGdlbmVyYWxseSBkaXN0aW5ndWlzaCBiZXR3ZWVuICJjb3VudGluZyBsb29wcyIgdGhhdCBpdGVyYXRlIHNvbWUgbnVtYmVyIG9mIHRpbWVzIHZlcnN1cyAiaXRlcmF0aW5nIGxvb3BzIiB0aGF0IGl0ZXJhdGUgb3ZlciB0aGUgZWxlbWVudHMgb2YgYSB2ZWN0b3Igb3IgbGlzdC4gCgojIyBDb3VudGluZyBMb29wOiAqZm9yKgoKVGhlIGNvdW50aW5nIGxvb3AgaXMgYWN0dWFsbHkgbW9yZSBsaWtlIGFuIGl0ZXJhdG9yIGluIFIsIGFsdGhvdWdoIGl0IGNhbiBiZSBzZXQgdXAgdG8gbWltaWMgdGhlIGJlaGF2aW9yIG9mIGEgdHlwaWNhbCBsb29wIGluIEMvQysrLCBKYXZhLCAqZXRjLiosIHRoYXQgbG9vcHMgZnJvbSBhIGxvdyB2YWx1ZSB0byBhIGhpZ2ggdmFsdWUuIFNlZSB0aGUgZXhhbXBsZXMgYmVsb3cuCgpgYGB7ciBzaW1wbGVGb3JMb29wfQpuID0gNQpmb3IgKGkgaW4gMTpuKSB7CiAgcHJpbnQoaSkKfQpgYGAKCkluIHRoZSBleGFtcGxlIGFib3ZlLCAqaSogaXMgdGhlIGxvb3AgdmFyaWFibGUgYW5kIGl0IHRha2VzIG9uIHRoZSB2YWx1ZXMgaW4gdGhlIHZlY3RvciAqMTo1KiwgKmkuZS4sKiAxLCAyLCAzLCA0LCA1IFxlbSBvbmUgYXQgYSB0aW1lLiAKClRvIGNvdW50IGRvd24sIGl0IHdvdWxkIGJlICo1OjEqIG9yICpuOjEqIGluIHRoZSBhYm92ZSBjb2RlIGV4YW1wbGUuCgpMaWtlIG90aGVyIGxhbmd1YWdlcywgUiB1c2VzIGN1cmx5IGJyYWNlcyB0byBlbmNsb3NlIHRoZSBib2R5IG9mIHRoZSBsb29wLCAqaS5lLiosIHRoZSBzdGF0ZW1lbnRzIHRoYXQgYXJlIGV4ZWN1dGVkIHJlcGVhdGVkbHksIG9uY2UgZm9yIGVhY2ggdmFsdWUgb2YgKmkqLiBPZiBjb3Vyc2UsIHRoZSBsb29wIGNvdW50ZXIgY2FuIGJlIGFueSBwcm9wZXJseSBuYW1lZCB2YXJpYWJsZS4KClRoZSBleGFtcGxlIGJlbG93IGFjY2Vzc2VzIGEgdmVjdG9yIHVzaW5nIHBvc2l0aW9uYWwgYWNjZXNzLCAqZS5nLiosICp2WzFdKiBhY2Nlc3NlcyB0aGUgZmlyc3QgZWxlbWVudC4gTm90ZSB0aGF0IHZlY3RvciwgZGF0YSBmcmFtZXMsIGxpc3RzLCBhbmQgYXJyYXlzIGFyZSBpbmRleGVkIHN0YXJ0aW5nIGF0IDEgYW5kIG5vdCAwIGFzIGluIEMtYmFzZWQgbGFuZ3VhZ2VzLgoKYGBge3IgbG9vcHNDYWxjc30KdiA9IHJub3JtKDUpICAgICAgIyB2ZWN0b3Igb2YgZml2ZSByYW5kb20gbnVtYmVycwpmb3IgKGkgaW4gMTpsZW5ndGgodikpIAp7CiAgdltpXSA9IHZbaV0gXiAyCn0KCnByaW50KHYpCmBgYAoKV2hpbGUgeW91IGNhbiB1c2UgbG9vcHMgeW91IGFjdHVhbGx5IGRvIG5vdCBuZWVkIHRoZW0uIElmIHlvdSBhcHBseSBhIG1hdGhlbWF0aWNhbCBvcGVyYXRpb24gdG8gYSB2ZWN0b3IsIFIgYXV0b21hdGljYWxseSBhcHBsaWVzIHRoZW0gdG8gZWFjaCBlbGVtZW50LCBidXQgbG9vcHMgbWlnaHQgYmUgbW9yZSBuYXR1cmFsIGluIHRoZSBiZWdpbm5pbmcuCgpgYGB7ciB2ZWN0b3JQcm9jfQojIG5vdGUgdGhhdCB5b3UgYWN0dWFsbHkgZG8gbm90IG5lZWQgbG9vcHMgaW4gUgojIHRoaXMgYWxzbyBzcXVhcmVzIGVhY2ggZWxlbWVudCBpbiB0aGUgdmVjdG9yIHYKdiA9IHYgXiAyCmBgYAoKQXMgYWxyZWFkeSBzdGF0ZWQsIGxvb3BpbmcgaW4gUiBpcyBhY3R1YWxseSBpdGVyYXRpb24gb3ZlciBhIHNldDogYSBzZXQgb2YgbnVtYmVycyBhcyBhYm92ZSBvciBhIHNldCBvZiBhbnkga2luZCBvZiBwcmltaXRpdmUgb2JqZWN0LCAqZS5nLiwqIHN0cmluZ3MuIE5vdGUgdGhhdCBpbiB0aGUgY29kZSBiZWxvdywgKmsqIHRha2VzIG9uIGVhY2ggdmFsdWUgaW4gdGhlIHZlY3RvciBvdmVyIHdoaWNoIHRoZSBsb29wIGl0ZXJhdGVzLgoKYGBge3IgaXRlcmF0ZU92ZXJTdHJpbmdzfQpzID0gYygib25lIiwidHdvIiwidGhyZWUiLCJmb3VyIikKCmZvciAoayBpbiBzKSB7CiAgcHJpbnQoaykKfQpgYGAKCldlIGNvdWxkIGhhdmUgd3JpdHRlbiB0aGlzIHVzaW5nIGEgbm9uLWl0ZXJhdG9yIGFwcHJvYWNoIGFzIHdlbGwsIHdoaWNoIGlzIG1vcmUgbGlrZSB3aGF0IHlvdSdkIGRvIGluIEMuIE5vdGUgdGhhdCA8Y29kZT5sZW5ndGg8L2NvZGU+IHJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiBhIHZlY3RvciwgKmkuZS4qLCBpdHMgImxlbmd0aCIuCgpgYGB7ciBsb29wT3ZlclN0cmluZ3N9CnMgPSBjKCJvbmUiLCJ0d28iLCJ0aHJlZSIsImZvdXIiKQoKZm9yIChqIGluIDE6bGVuZ3RoKHMpKSB7CiAgcHJpbnQoc1tqXSkKfQpgYGAKCiMjIyBJdGVyYXRpb24gQ29udGludWF0aW9uCgpDb250aW51YXRpb24gb2YgdGhlIGxvb3AgdG8gdGhlIG5leHQgaXRlcmF0aW9uIGFuZCBmb3Jnb2luZyBwcm9jZXNzaW5nIHRoZSByZW1haW5kZXIgb2YgdGhlIGN1cnJlbnQgaXRlcmF0aW9uIGlzIGRvbmUgd2l0aCAqbmV4dCogaW4gUiwgc2ltaWxhciB0byAqY29udGludWUqIGluIEMtYmFzZWQgbGFuZ3VhZ2VzIHN1Y2ggYXMgSmF2YS4KCkluIHRoZSBleGFtcGxlIGJlbG93IHdlIGFyZSBhbHJlYWR5IHJlYWNoaW5nIGFoZWFkIHRvIHRoZSAqaWYqIHN0YXRlbWVudC4gVGhlIGNvZGUgZnJhZ21lbnQgZWNob2VzIG9ubHkgb2RkIG51bWJlci4gT2YgY291cnNlLCB5b3UgY291bGQgaGF2ZSBkb25lIHRoaXMgZGlmZmVyZW50bHkgYnkganVzdCBpdGVyYXRpbmcgb3ZlciB0aGUgZXZlbiBudW1iZXJzIGZyb20gb25lIHRvIHR3ZW50eSwgYnV0IHRoYXQgd291bGQgbm90IGhhdmUgYWxsb3dlZCB1cyB0byBzaGFyZSB0aGlzIGV4YW1wbGUgZm9yIHVzaW5nICpuZXh0Ki4KCmBgYHtyIG5leHRJbkZvcn0KZm9yIChpIGluIDE6MTApIHsKICBpZiAoIWkgJSUgMikgewogICAgbmV4dAogIH0KICBwcmludChpKQp9CmBgYAoKQnV0LCBqdXN0IHRvIHNob3cgeW91IGhvdyB0byBpdGVyYXRlIG92ZXIganVzdCBvZGQgbnVtYmVyLCB3ZSBjYW4gdXNlIHRoZSA8Y29kZT5zZXEoKTwvY29kZT4gZnVuY3Rpb24gd2hpY2ggZ2VuZXJhdGVzIGEgc2VxdWVuY2Ugb2YgbnVtYmVycyBpbiBzdGVwcy4gTm8gKmlmKiBhbmQgbm8gKmJyZWFrKiBuZWVkZWQgLS0gbXVjaCBzaW1wbGVyLgoKYGBge3IgbG9vcE92ZXJPZGRTZXF9CmZvciAoaSBpbiBzZXEoMSwgMTAsIDIpKSB7CiAgcHJpbnQoaSkKfQpgYGAKCk9yLCBtb3JlIGV4cGxpY2l0bHkgYnkgc3BlY2lmeWluZyB0aGUgcGFyYW1ldGVycyBieSBuYW1lLgoKYGBge3IgbG9vcE92ZXJPZGRTZXFXaXRoUGFybXN9CmZvciAoaSBpbiBzZXEoZnJvbSA9IDEsIHRvID0gMTAsIGJ5ID0gMikpIHsKICBwcmludChpKQp9CmBgYAoKVG8gc3RvcCB0aGUgZXhlY3V0aW9uIG9mIHRoZSByZXN0IG9mIGEgbG9vcCBhbmQgdG8gbW92ZSBpbW1lZGlhdGVseSB0byB0aGUgbmV4dCBzdGF0ZW1lbnQgYWZ0ZXIgdGhlIGxvb3AgaXMgZG9uZSB3aXRoICpicmVhayogaW4gUiB3aGljaCBpcyBpZGVudGljYWwgdG8gQywgQysrLCBKYXZhLCBldGMuIEluIHRoZSBjb2RlIGJlbG93IHdlIHdpbGwgZmluZCB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2Ygc29tZSBudW1iZXI7ICp4KiBpcyB0aGUgbnVtYmVyIHdlIGFyZSBsb29raW5nIGZvciBpbiAqdiogYW5kICpwKiBpcyB0aGUgZm91bmQgcG9zaXRpb24uCgpgYGB7ciBicmVha0Zvcn0KdiA9IGMoMSwgMywgNSwgNywgMSwgOSwgNCkKeCA9IDkKcCA9IDAKCmZvciAoaSBpbiAxOmxlbmd0aCh2KSkgewogIGlmICh2W2ldID09IHgpIHsKICAgIHAgPSBpCiAgICBicmVhawogIH0KfQoKcHJpbnQocCkKYGBgCgpUbyBiZSBjbGVhciwgdGhlcmUgaXMgYSBxdWlja2VyIGFuZCBtb3JlIGVmZmljaWVudCB3YXkgdG8gZG8gdGhpcyB1c2luZyB0aGUgPGNvZGU+d2hpY2g8L2NvZGU+IGZ1bmN0aW9uLiBUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IGV4aXN0IGlzIG90aGVyIGxhbmd1YWdlcyBhbmQgaXQgc2hvd3MgdGhlIHBvd2VyIG9mIFIuIEFsc28sIHVzaW5nIDxjb2RlPndoaWNoPC9jb2RlPiBpcyBtdWNoIGZhc3Rlci4gSW5jaWRlbnRhbGx5LCB0aGUgY29kZSBiZWxvdyBmaW5kcyBhbGwgb2NjdXJyZW5jZXMgb2YgKngqIGluICp2Ki4gTm90ZSwgb25jZSBhZ2FpbiwgdGhlIHVzZSBvZiBhIHZlY3RvciB2YXJpYWJsZSB0byByZWZlciB0byBhbGwgZWxlbWVudHMuCgpgYGB7ciBmaW5kVmFsV2l0aFdoaWNofQp2ID0gYygxLCAzLCA1LCA3LCAxLCA5LCA0KQp4ID0gOQoKcCA9IHdoaWNoKHYgPT0geCkKCnByaW50KHApCmBgYAoKIyMgQ29uZGl0aW9uYWwgTG9vcHM6ICp3aGlsZSogYW5kICpyZXBlYXQqCgpMaWtlIG1hbnkgb3RoZXIgbGFuZ3VhZ2VzLCBSIHN1cHBvcnRzIHRvcCBhbmQgYm90dG9tIHRlc3RlZCBsb29wcy4gSW4gdGhlIGV4YW1wbGUgYmVsb3cgd2UgcmVwZWF0ZWRseSBhc2sgZm9yIGEgbnVtYmVyIGZyb20gdGhlIHVzZXIgYW5kIG9ubHkgZXhpdCB0aGUgbG9vcCBpZiB0aGUgbnVtYmVyIGlzIDQyLiBPZiBjb3Vyc2UsIHRoZSBleGFtcGxlIHJlYWxseSBzaG91bGQgYmUgZG9uZSB3aXRoIGEgYm90dG9tIHRlc3RlZCBsb29wLgoKYGBge3Igd2hpbGVMb29wLCBldmFsPUZ9CnJlc3BvbnNlIDwtIGFzLmludGVnZXIocmVhZGxpbmUocHJvbXB0PSJFbnRlciBhIG51bWJlcjogIikpCgp3aGlsZSAocmVzcG9uc2UgIT0gNDIpIHsgICAKICBwcmludCgiU29ycnksIG5vdCBjb3JyZWN0Iik7CiAgcmVzcG9uc2UgPC0gYXMuaW50ZWdlcihyZWFkbGluZShwcm9tcHQ9IkVudGVyIGEgbnVtYmVyOiAiKSk7Cn0KYGBgCgpJbiB0aGUgYWJvdmUgZXhhbXBsZSwgd2UgYXJlIHVzaW5nIHR3byBuZXcgZnVuY3Rpb25zLiA8Y29kZT5yZWFkbGluZTwvY29kZT4gaXMgdXNlZCB0byByZWFkIGlucHV0IGZyb20gdGhlIGNvbnNvbGUsIHdoaWxlIDxjb2RlPmFzLmludGVnZXI8L2NvZGU+IGNvZXJjZXMgKG9yIGNhc3RzIGluIEMvQysrIHRlcm1pbm9sb2d5KSB0aGUgaW5wdXQgdG8gYW4gaW50ZWdlci4KClRoZSBjb2RlIGlzIGFib3ZlIGlzIG5vdCB2ZXJ5IGVmZmljaWVudCBvciBlbGVnYW50IGFzIGl0IGhhcyB0aGUgY29kZSBmb3IgdGhlIHVzZXIgcHJvbXB0IHR3aWNlLiBJdCBpcyByZWFsbHkgYmV0dGVyIHRvIGFzayBmaXJzdCBhbmQgdGhlbiBjaGVjayB0aGUgY29uZGl0aW9uOiB3ZSBuZWVkIGEgYm90dG9tLXRlc3RlZCBsb29wLgoKTGV0J3MgbG9vayBhdCB0aGUgc2FtZSBleGFtcGxlLCBidXQgd2l0aCBhICpyZXBlYXQqIGxvb3AgdGhhdCBydW5zIHVudGlsIGEgY29uZGl0aW9uIGlzIHJlYWNoZWQgYW5kIHRoZSBsb29wIGlzIGV4cGxpY2l0bHkgZXhpdGVkIHdpdGggKmJyZWFrKi4gU28sIGlmIHlvdSB3YW50IHRvIHJ1biB0aGUgY29kZSBhdCBsZWFzdCBvbmNlLCB1c2UgKnJlcGVhdCo7IGlmIHRoZSBjb2RlIGlzIHJ1biB6ZXJvIG9yIG1vcmUgdGltZXMsIHVzZSAqd2hpbGUqLiBUaGUgKnJlcGVhdCogbG9vcCBpcyBpZGVudGljYWwgdG8gdGhlICpkbyogb3IgKmRvIHdoaWxlKiBsb29wIGZvdW5kIGluIG1hbnkgb3RoZXIgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzLgoKYGBge3IgcmVwZWF0TG9vcCwgZXZhbD1GfQpyZXBlYXQgeyAgIAogIHJlc3BvbnNlIDwtIGFzLmludGVnZXIocmVhZGxpbmUocHJvbXB0PSJFbnRlciBhIG51bWJlcjogIikpOwogIGlmIChyZXNwb25zZSA9PSA0MikgewogICAgYnJlYWsKICB9CiAgcHJpbnQoIlNvcnJ5LCBub3QgY29ycmVjdCIpOwp9CmBgYAoKVGhlcmUgaXMgbm8gZXF1aXZhbGVudCBpbiBSIGZvciB0aGUgdXNlIG9mIGFuIGluZmluaXRlICpmb3IqIGxvb3AgYXMgaW4gQyBhbmQgQysrLCAqZS5nLiosIDxjb2RlPmZvcig7Oyl7IC8vIGRvIHNvbWV0aGluZyBpbmRlZmluaXRlbHkgfTwvY29kZT4gdGhhdCBydW5zIHVudGlsIGEgY29uZGl0aW9uIGlzIHJlYWNoZWQgYW5kIHRoZW4gdXNlcyAqYnJlYWsqIHRvIGV4aXQgdGhlIGxvb3AuIFRoZSAqcmVwZWF0KiBsb29wIGNvbnN0cnVjdCBpcyB1c2VkIGluc3RlYWQuIFRoZXJlIGlzIG5vIHRlc3Rpbmcgb2YgYSBjb25kaXRpb24gaW4gdGhlICpyZXBlYXQqIGxvb3AsIHNvIHRoZXJlJ3Mgbm8gZXF1aXZhbGVudCB0byB0aGUgQy1saWtlIGNvbnN0cnVjdCAqZG8gLi4uIHdoaWxlKi4KCiMjIENvbmNsdXNpb24KCkFzIHlvdSBzYXcsIFIgaXMgbm90IGEgZGlmZmljdWx0IGxhbmd1YWdlIHRvIGxlYXJuIGFzIGl0IGlzIHNpbWlsYXIgdG8gb3RoZXIgbGFuZ3VhZ2VzIGFuZCBmb3IgbW9zdCBsYW5ndWFnZSBjb25zdHJ1Y3RzIHRoYXQgeW91IGFyZSBmYW1pbGlhciB3aXRoLCB0aGVyZSBpcyBhbiBlcXVpdmFsZW50LiBCdXQgaXQgaXMgaW1wb3J0YW50IHRoYXQgeW91IGdvIGJleW9uZCB0aGlzIHR1dG9yaWFsIGFuZCBsZWFybiB0aGUgIlIgd2F5IiBvZiBwcm9ncmFtbWluZyB1c2luZyB2ZWN0b3JpemVkIG9wZXJhdGlvbnMuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIEZpbGVzICYgUmVzb3VyY2VzCgpgYGB7ciB6aXBGaWxlcywgZWNobz1GQUxTRX0KemlwTmFtZSA9IHNwcmludGYoIkxlc3NvbkZpbGVzLSVzLSVzLnppcCIsIAogICAgICAgICAgICAgICAgIHBhcmFtcyRjYXRlZ29yeSwKICAgICAgICAgICAgICAgICBwYXJhbXMkbnVtYmVyKQoKdGV4dEFMaW5rID0gcGFzdGUwKCJBbGwgRmlsZXMgZm9yIExlc3NvbiAiLCAKICAgICAgICAgICAgICAgcGFyYW1zJGNhdGVnb3J5LCIuIixwYXJhbXMkbnVtYmVyKQoKIyBkb3dubG9hZEZpbGVzTGluaygpIGlzIGluY2x1ZGVkIGZyb20gX2luc2VydDJEQi5SCmtuaXRyOjpyYXdfaHRtbChkb3dubG9hZEZpbGVzTGluaygiLiIsIHppcE5hbWUsIHRleHRBTGluaykpCmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBSZWZlcmVuY2VzCgpObyByZWZlcmVuY2VzLgoKIyMgRXJyYXRhCgpOb25lIGNvbGxlY3RlZCB5ZXQuIExldCB1cyBrbm93LgoKYGBgez1odG1sfQo8c2NyaXB0IHNyYz0iaHR0cHM6Ly9mb3JtLmpvdGZvcm0uY29tL3N0YXRpYy9mZWVkYmFjazIuanMiIHR5cGU9InRleHQvamF2YXNjcmlwdCI+CiAgbmV3IEpvdGZvcm1GZWVkYmFjayh7CiAgICBmb3JtSWQ6ICIyMTIxODcwNzI3ODQxNTciLAogICAgYnV0dG9uVGV4dDogIkZlZWRiYWNrIiwKICAgIGJhc2U6ICJodHRwczovL2Zvcm0uam90Zm9ybS5jb20vIiwKICAgIGJhY2tncm91bmQ6ICIjRjU5MjAyIiwKICAgIGZvbnRDb2xvcjogIiNGRkZGRkYiLAogICAgYnV0dG9uU2lkZTogImxlZnQiLAogICAgYnV0dG9uQWxpZ246ICJjZW50ZXIiLAogICAgdHlwZTogZmFsc2UsCiAgICB3aWR0aDogNzAwLAogICAgaGVpZ2h0OiA1MDAsCiAgICBpc0NhcmRGb3JtOiBmYWxzZQogIH0pOwo8L3NjcmlwdD4KYGBgCmBgYHtyIGNvZGU9eGZ1bjo6cmVhZF91dGY4KHBhc3RlMChoZXJlOjpoZXJlKCksJy9SL19kZXBsb3lLbml0LlInKSksIGluY2x1ZGUgPSBGQUxTRX0KYGBgCg==