Last updated: 2017-12-18

Code version: 626c9ea

See more puzzles

Advent of Code

Session information

sessionInfo()
R version 3.4.2 (2017-09-28)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Sierra 10.12.6

Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libRlapack.dylib

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] aocodeR_0.1.1      testthat_1.0.2     forcats_0.2.0      stringr_1.2.0      dplyr_0.7.4       
 [6] purrr_0.2.4        readr_1.1.1        tidyr_0.7.2        tibble_1.3.4       ggplot2_2.2.1.9000
[11] tidyverse_1.2.1   

loaded via a namespace (and not attached):
 [1] reshape2_1.4.2    haven_1.1.0       lattice_0.20-35   colorspace_1.3-2  htmltools_0.3.6  
 [6] yaml_2.1.15       base64enc_0.1-3   rlang_0.1.4       foreign_0.8-69    glue_1.2.0       
[11] modelr_0.1.1      readxl_1.0.0      bindrcpp_0.2      bindr_0.1         plyr_1.8.4       
[16] munsell_0.4.3     gtable_0.2.0      cellranger_1.1.0  rvest_0.3.2       psych_1.7.8      
[21] evaluate_0.10.1   knitr_1.17        parallel_3.4.2    curl_3.0          broom_0.4.2      
[26] Rcpp_0.12.14      backports_1.1.1   scales_0.5.0.9000 jsonlite_1.5      mnormt_1.5-5     
[31] hms_0.4.0         digest_0.6.12     stringi_1.1.6     grid_3.4.2        rprojroot_1.2    
[36] cli_1.0.0         tools_3.4.2       magrittr_1.5      lazyeval_0.2.1    crayon_1.3.4     
[41] pkgconfig_2.0.1   rsconnect_0.8.5   xml2_1.1.1        lubridate_1.7.1   assertthat_0.2.0 
[46] rmarkdown_1.8     httr_1.3.1        rstudioapi_0.7    R6_2.2.2          nlme_3.1-131     
[51] git2r_0.19.0      compiler_3.4.2   

Brief

— Day 15: Dueling Generators —

Here, you encounter a pair of dueling generators. The generators, called generator A and generator B, are trying to agree on a sequence of numbers. However, one of them is malfunctioning, and so the sequences don’t always match.

As they do this, a judge waits for each of them to generate its next value, compares the lowest 16 bits of both values, and keeps track of the number of times those parts of the values match.

The generators both work on the same principle. To create its next value, a generator will take the previous value it produced, multiply it by a factor (generator A uses 16807; generator B uses 48271), and then keep the remainder of dividing that resulting product by 2147483647. That final remainder is the value it produces next.

To calculate each generator’s first value, it instead uses a specific starting value as its “previous value” (as listed in your puzzle input).

For example, suppose that for starting values, generator A uses 65, while generator B uses 8921. Then, the first five pairs of generated values are:

--Gen. A--  --Gen. B--
   1092455   430625591
1181022009  1233683848
 245556042  1431495498
1744312007   137874439
1352636452   285222916

In binary, these pairs are (with generator A’s value first in each pair):

100001010101101100111

00000000000100001010101101100111
00011001101010101101001100110111

01000110011001001111011100111001
01001001100010001000010110001000

00001110101000101110001101001010
01010101010100101110001101001010

01100111111110000001011011000111
00001000001101111100110000000111

01010000100111111001100000100100
00010001000000000010100000000100

Here, you can see that the lowest (here, rightmost) 16 bits of the third value match: 1110001101001010. Because of this one match, after processing these five pairs, the judge would have added only 1 to its total.

To get a significant sample, the judge would like to consider 40 million pairs. (In the example above, the judge would eventually find a total of 588 pairs that match in their lowest 16 bits.)

After 40 million pairs, what is the judge’s final count?

Let’s go

Packages & functions

library(tidyverse)
library(testthat)
library(aocodeR)

Input

input <- aoc_get_input(day = 15, cookie_path = paste0(rprojroot::find_rstudio_root_file(),
                                                 "/secrets/session_cookie.txt")) 
input
[1] "Generator A starts with 516\nGenerator B starts with 190"

Functions

int2bin16 <- function(int) {
    int %>% intToBits %>%
        as.numeric %>% rev %>% tail(16)
}
next_int <- function(c, f) {
    (c * f) %% 2147483647
}
matches <- function(n, A = 65, B = 8921){
    match <- 0
    current <- c(A, B)
    for(i in 1:n){
        current <- c(next_int(current[1], f = 16807), next_int(current[2], f = 48271))
        match <- match + (bitwAnd(current[1],0xffff) == bitwAnd(current[2],0xffff))
    }
    match}

Test

expect_equal(matches(n = 5),1)

deploy

matches(n = 40000000, A = 516, B = 190)
[1] 597

Success!



—- Part 2 —-

— Part Two —

In the interest of trying to align a little better, the generators get more picky about the numbers they actually give to the judge.

They still generate values in the same way, but now they only hand a value to the judge when it meets their criteria:

Generator A looks for values that are multiples of 4. Generator B looks for values that are multiples of 8. Each generator functions completely independently: they both go through values entirely on their own, only occasionally handing an acceptable value to the judge, and otherwise working through the same sequence of values as before until they find one.

The judge still waits for each generator to provide it with a value before comparing them (using the same comparison method as before). It keeps track of the order it receives values; the first values from each generator are compared, then the second values from each generator, then the third values, and so on.

Using the example starting values given above, the generators now produce the following first five values each:

–Gen. A– –Gen. B– 1352636452 1233683848 1992081072 862516352 530830436 1159784568 1980017072 1616057672 740335192 412269392 These values have the following corresponding binary values:

01010000100111111001100000100100
01001001100010001000010110001000

01110110101111001011111010110000
00110011011010001111010010000000

00011111101000111101010001100100
01000101001000001110100001111000

01110110000001001010100110110000
01100000010100110001010101001000

00101100001000001001111001011000
00011000100100101011101101010000

Unfortunately, even though this change makes more bits similar on average, none of these values’ lowest 16 bits match. Now, it’s not until the 1056th pair that the judge finds the first match:

--Gen. A--  --Gen. B--
1023762912   896885216

00111101000001010110000111100000
00110101011101010110000111100000

This change makes the generators much slower, and the judge is getting impatient; it is now only willing to consider 5 million pairs. (Using the values from the example above, after five million pairs, the judge would eventually find a total of 309 pairs that match in their lowest 16 bits.)

After 5 million pairs, but using this new generator logic, what is the judge’s final count?

Brief

Let’s go

next_int2 <- function(c, f, d) {
    c <- (c * f) %% 2147483647 
    while(c %% d != 0){
        c <- (c * f) %% 2147483647
    }
    c
}
        
 matches2 <- function(n, A = 65, B = 8921){
    match <- 0
    current <- c(A, B)
    for(i in 1:n){
        current <- c(next_int2(current[1], f = 16807, d = 4), next_int2(current[2], f = 48271, d= 8))
        match <- match + (bitwAnd(current[1],0xffff) == bitwAnd(current[2],0xffff))
    }
    match}      

Test

expect_equal(matches2(n = 5000000, A = 65, B = 8921), 309)

deploy

matches2(n = 5000000, A = 516, B = 190)
[1] 303

Success!



template based on the workflowr standalone template

LS0tCnRpdGxlOiAiLS0tIERheSAxNTogRHVlbGluZyBHZW5lcmF0b3JzIC0tLSIKYXV0aG9yOiAiYW5uYWtyeXN0YWxsaSIKZGF0ZTogMjAxNy0xMi0xNQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgpgYGB7ciBrbml0ci1vcHRzLWNodW5rLCBpbmNsdWRlPUZBTFNFfQojIFVwZGF0ZSBrbml0ciBjaHVuayBvcHRpb25zCiMgaHR0cHM6Ly95aWh1aS5uYW1lL2tuaXRyL29wdGlvbnMvI2NodW5rLW9wdGlvbnMKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGNvbW1lbnQgPSBOQSwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICB0aWR5ID0gRkFMU0UsCiAgZmlnLnBhdGggPSBwYXN0ZTAoImZpZ3VyZS8iLCBrbml0cjo6Y3VycmVudF9pbnB1dCgpLCAiLyIpCikKYGBgCgpgYGB7ciBsYXN0LXVwZGF0ZWQsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnfQojIEluc2VydCB0aGUgZGF0ZSB0aGUgZmlsZSB3YXMgbGFzdCB1cGRhdGVkCmNhdChzcHJpbnRmKCIqKkxhc3QgdXBkYXRlZDoqKiAlcyIsIFN5cy5EYXRlKCkpKQpgYGAKCmBgYHtyIGNvZGUtdmVyc2lvbiwgZWNobz1GQUxTRSwgcmVzdWx0cz0nYXNpcyd9CiMgSW5zZXJ0IHRoZSBjb2RlIHZlcnNpb24gKEdpdCBjb21taXQgU0hBMSkgaWYgR2l0IHJlcG9zaXRvcnkgZXhpc3RzIGFuZCBSCiMgcGFja2FnZSBnaXQyciBpcyBpbnN0YWxsZWQKaWYocmVxdWlyZU5hbWVzcGFjZSgiZ2l0MnIiLCBxdWlldGx5ID0gVFJVRSkpIHsKICBpZihnaXQycjo6aW5fcmVwb3NpdG9yeSgpKSB7CiAgICBjb2RlX3ZlcnNpb24gPC0gc3Vic3RyKGdpdDJyOjpjb21taXRzKClbWzFdXUBzaGEsIDEsIDcpCiAgfSBlbHNlIHsKICAgIGNvZGVfdmVyc2lvbiA8LSAiVW5hdmFpbGFibGUuIEluaXRpYWxpemUgR2l0IHJlcG9zaXRvcnkgdG8gZW5hYmxlLiIKICB9Cn0gZWxzZSB7CiAgY29kZV92ZXJzaW9uIDwtICJVbmF2YWlsYWJsZS4gSW5zdGFsbCBnaXQyciBwYWNrYWdlIHRvIGVuYWJsZS4iCn0KY2F0KHNwcmludGYoIioqQ29kZSB2ZXJzaW9uOioqICVzIiwgY29kZV92ZXJzaW9uKSkKcm0oY29kZV92ZXJzaW9uKQpgYGAKCgo+IFsqKipTZWUgbW9yZSBwdXp6bGVzKioqXShodHRwOi8vYW5uYWtyeXN0YWxsaS5tZS9hZHZlbnRfb2ZfY29kZS8pCgpbKipBZHZlbnQgb2YgQ29kZSoqXShodHRwczovL2FkdmVudG9mY29kZS5jb20vMjAxNy8pCgoKIyMgU2Vzc2lvbiBpbmZvcm1hdGlvbgoKPCEtLSBJbnNlcnQgdGhlIHNlc3Npb24gaW5mb3JtYXRpb24gaW50byB0aGUgZG9jdW1lbnQgLS0+CmBgYHtyIHNlc3Npb24taW5mb30Kc2Vzc2lvbkluZm8oKQpgYGAKCgojIyBCcmllZgoKPCEtLSBJbnNlcnQgUGFydCAxIG9mIHRoZSBwdXp6bGUgYnJpZWYgaGVyZSAtLT4KCi0tLSBEYXkgMTU6IER1ZWxpbmcgR2VuZXJhdG9ycyAtLS0KCkhlcmUsIHlvdSBlbmNvdW50ZXIgYSBwYWlyIG9mIGR1ZWxpbmcgZ2VuZXJhdG9ycy4gVGhlIGdlbmVyYXRvcnMsIGNhbGxlZCBnZW5lcmF0b3IgQSBhbmQgZ2VuZXJhdG9yIEIsIGFyZSB0cnlpbmcgdG8gYWdyZWUgb24gYSBzZXF1ZW5jZSBvZiBudW1iZXJzLiBIb3dldmVyLCBvbmUgb2YgdGhlbSBpcyBtYWxmdW5jdGlvbmluZywgYW5kIHNvIHRoZSBzZXF1ZW5jZXMgZG9uJ3QgYWx3YXlzIG1hdGNoLgoKQXMgdGhleSBkbyB0aGlzLCBhIGp1ZGdlIHdhaXRzIGZvciBlYWNoIG9mIHRoZW0gdG8gZ2VuZXJhdGUgaXRzIG5leHQgdmFsdWUsIGNvbXBhcmVzIHRoZSBsb3dlc3QgMTYgYml0cyBvZiBib3RoIHZhbHVlcywgYW5kIGtlZXBzIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgdGltZXMgdGhvc2UgcGFydHMgb2YgdGhlIHZhbHVlcyBtYXRjaC4KClRoZSBnZW5lcmF0b3JzIGJvdGggd29yayBvbiB0aGUgc2FtZSBwcmluY2lwbGUuIFRvIGNyZWF0ZSBpdHMgbmV4dCB2YWx1ZSwgYSBnZW5lcmF0b3Igd2lsbCB0YWtlIHRoZSBwcmV2aW91cyB2YWx1ZSBpdCBwcm9kdWNlZCwgbXVsdGlwbHkgaXQgYnkgYSBmYWN0b3IgKGdlbmVyYXRvciBBIHVzZXMgMTY4MDc7IGdlbmVyYXRvciBCIHVzZXMgNDgyNzEpLCBhbmQgdGhlbiBrZWVwIHRoZSByZW1haW5kZXIgb2YgZGl2aWRpbmcgdGhhdCByZXN1bHRpbmcgcHJvZHVjdCBieSAyMTQ3NDgzNjQ3LiBUaGF0IGZpbmFsIHJlbWFpbmRlciBpcyB0aGUgdmFsdWUgaXQgcHJvZHVjZXMgbmV4dC4KClRvIGNhbGN1bGF0ZSBlYWNoIGdlbmVyYXRvcidzIGZpcnN0IHZhbHVlLCBpdCBpbnN0ZWFkIHVzZXMgYSBzcGVjaWZpYyBzdGFydGluZyB2YWx1ZSBhcyBpdHMgInByZXZpb3VzIHZhbHVlIiAoYXMgbGlzdGVkIGluIHlvdXIgcHV6emxlIGlucHV0KS4KCkZvciBleGFtcGxlLCBzdXBwb3NlIHRoYXQgZm9yIHN0YXJ0aW5nIHZhbHVlcywgZ2VuZXJhdG9yIEEgdXNlcyA2NSwgd2hpbGUgZ2VuZXJhdG9yIEIgdXNlcyA4OTIxLiBUaGVuLCB0aGUgZmlyc3QgZml2ZSBwYWlycyBvZiBnZW5lcmF0ZWQgdmFsdWVzIGFyZToKYGBgCi0tR2VuLiBBLS0gIC0tR2VuLiBCLS0KICAgMTA5MjQ1NSAgIDQzMDYyNTU5MQoxMTgxMDIyMDA5ICAxMjMzNjgzODQ4CiAyNDU1NTYwNDIgIDE0MzE0OTU0OTgKMTc0NDMxMjAwNyAgIDEzNzg3NDQzOQoxMzUyNjM2NDUyICAgMjg1MjIyOTE2CmBgYApJbiBiaW5hcnksIHRoZXNlIHBhaXJzIGFyZSAod2l0aCBnZW5lcmF0b3IgQSdzIHZhbHVlIGZpcnN0IGluIGVhY2ggcGFpcik6CgoxMDAwMDEwMTAxMDExMDExMDAxMTEKCmBgYAowMDAwMDAwMDAwMDEwMDAwMTAxMDEwMTEwMTEwMDExMQowMDAxMTAwMTEwMTAxMDEwMTEwMTAwMTEwMDExMDExMQoKMDEwMDAxMTAwMTEwMDEwMDExMTEwMTExMDAxMTEwMDEKMDEwMDEwMDExMDAwMTAwMDEwMDAwMTAxMTAwMDEwMDAKCjAwMDAxMTEwMTAxMDAwMTAxMTEwMDAxMTAxMDAxMDEwCjAxMDEwMTAxMDEwMTAwMTAxMTEwMDAxMTAxMDAxMDEwCgowMTEwMDExMTExMTExMDAwMDAwMTAxMTAxMTAwMDExMQowMDAwMTAwMDAwMTEwMTExMTEwMDExMDAwMDAwMDExMQoKMDEwMTAwMDAxMDAxMTExMTEwMDExMDAwMDAxMDAxMDAKMDAwMTAwMDEwMDAwMDAwMDAwMTAxMDAwMDAwMDAxMDAKYGBgCkhlcmUsIHlvdSBjYW4gc2VlIHRoYXQgdGhlIGxvd2VzdCAoaGVyZSwgcmlnaHRtb3N0KSAxNiBiaXRzIG9mIHRoZSB0aGlyZCB2YWx1ZSBtYXRjaDogMTExMDAwMTEwMTAwMTAxMC4gQmVjYXVzZSBvZiB0aGlzIG9uZSBtYXRjaCwgYWZ0ZXIgcHJvY2Vzc2luZyB0aGVzZSBmaXZlIHBhaXJzLCB0aGUganVkZ2Ugd291bGQgaGF2ZSBhZGRlZCBvbmx5IDEgdG8gaXRzIHRvdGFsLgoKVG8gZ2V0IGEgc2lnbmlmaWNhbnQgc2FtcGxlLCB0aGUganVkZ2Ugd291bGQgbGlrZSB0byBjb25zaWRlciA0MCBtaWxsaW9uIHBhaXJzLiAoSW4gdGhlIGV4YW1wbGUgYWJvdmUsIHRoZSBqdWRnZSB3b3VsZCBldmVudHVhbGx5IGZpbmQgYSB0b3RhbCBvZiA1ODggcGFpcnMgdGhhdCBtYXRjaCBpbiB0aGVpciBsb3dlc3QgMTYgYml0cy4pCgpBZnRlciA0MCBtaWxsaW9uIHBhaXJzLCB3aGF0IGlzIHRoZSBqdWRnZSdzIGZpbmFsIGNvdW50PwoKIyBMZXQncyBnbwoKIyMjIFBhY2thZ2VzICYgZnVuY3Rpb25zCmBgYHtyLCBtZXNzYWdlID0gRn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkodGVzdHRoYXQpCmxpYnJhcnkoYW9jb2RlUikKCmBgYAoKCiMjIElucHV0Cgo8IS0tIFN1cHBseSBkYXkuIGNvb2tpZV9wYXRoIGRlZmF1bHRzIHRvIHBhdGggaW4gbXkgcHJvamVjdCAtLT4KYGBge3J9CmlucHV0IDwtIGFvY19nZXRfaW5wdXQoZGF5ID0gMTUsIGNvb2tpZV9wYXRoID0gcGFzdGUwKHJwcm9qcm9vdDo6ZmluZF9yc3R1ZGlvX3Jvb3RfZmlsZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi9zZWNyZXRzL3Nlc3Npb25fY29va2llLnR4dCIpKSAKaW5wdXQKYGBgCgojIyBGdW5jdGlvbnMKYGBge3J9CmludDJiaW4xNiA8LSBmdW5jdGlvbihpbnQpIHsKICAgIGludCAlPiUgaW50VG9CaXRzICU+JQogICAgICAgIGFzLm51bWVyaWMgJT4lIHJldiAlPiUgdGFpbCgxNikKfQoKbmV4dF9pbnQgPC0gZnVuY3Rpb24oYywgZikgewogICAgKGMgKiBmKSAlJSAyMTQ3NDgzNjQ3Cn0KCm1hdGNoZXMgPC0gZnVuY3Rpb24obiwgQSA9IDY1LCBCID0gODkyMSl7CiAgICBtYXRjaCA8LSAwCiAgICBjdXJyZW50IDwtIGMoQSwgQikKICAgIGZvcihpIGluIDE6bil7CiAgICAgICAgY3VycmVudCA8LSBjKG5leHRfaW50KGN1cnJlbnRbMV0sIGYgPSAxNjgwNyksIG5leHRfaW50KGN1cnJlbnRbMl0sIGYgPSA0ODI3MSkpCiAgICAgICAgbWF0Y2ggPC0gbWF0Y2ggKyAoYml0d0FuZChjdXJyZW50WzFdLDB4ZmZmZikgPT0gYml0d0FuZChjdXJyZW50WzJdLDB4ZmZmZikpCiAgICB9CiAgICBtYXRjaH0KCmBgYAoKIyMgVGVzdApgYGB7cn0KZXhwZWN0X2VxdWFsKG1hdGNoZXMobiA9IDUpLDEpCmBgYAoKIyMgZGVwbG95CgpgYGB7cn0KbWF0Y2hlcyhuID0gNDAwMDAwMDAsIEEgPSA1MTYsIEIgPSAxOTApCmBgYAoKCiMjIFN1Y2Nlc3MhCgohW10oLi4vc2NyZWVuc2hvdHMvRGF5MV8xLnBuZykKCjxicj4KCioqKgoKIyAtLS0tIFBhcnQgMiAtLS0tCgotLS0gUGFydCBUd28gLS0tCgpJbiB0aGUgaW50ZXJlc3Qgb2YgdHJ5aW5nIHRvIGFsaWduIGEgbGl0dGxlIGJldHRlciwgdGhlIGdlbmVyYXRvcnMgZ2V0IG1vcmUgcGlja3kgYWJvdXQgdGhlIG51bWJlcnMgdGhleSBhY3R1YWxseSBnaXZlIHRvIHRoZSBqdWRnZS4KClRoZXkgc3RpbGwgZ2VuZXJhdGUgdmFsdWVzIGluIHRoZSBzYW1lIHdheSwgYnV0IG5vdyB0aGV5IG9ubHkgaGFuZCBhIHZhbHVlIHRvIHRoZSBqdWRnZSB3aGVuIGl0IG1lZXRzIHRoZWlyIGNyaXRlcmlhOgoKR2VuZXJhdG9yIEEgbG9va3MgZm9yIHZhbHVlcyB0aGF0IGFyZSBtdWx0aXBsZXMgb2YgNC4KR2VuZXJhdG9yIEIgbG9va3MgZm9yIHZhbHVlcyB0aGF0IGFyZSBtdWx0aXBsZXMgb2YgOC4KRWFjaCBnZW5lcmF0b3IgZnVuY3Rpb25zIGNvbXBsZXRlbHkgaW5kZXBlbmRlbnRseTogdGhleSBib3RoIGdvIHRocm91Z2ggdmFsdWVzIGVudGlyZWx5IG9uIHRoZWlyIG93biwgb25seSBvY2Nhc2lvbmFsbHkgaGFuZGluZyBhbiBhY2NlcHRhYmxlIHZhbHVlIHRvIHRoZSBqdWRnZSwgYW5kIG90aGVyd2lzZSB3b3JraW5nIHRocm91Z2ggdGhlIHNhbWUgc2VxdWVuY2Ugb2YgdmFsdWVzIGFzIGJlZm9yZSB1bnRpbCB0aGV5IGZpbmQgb25lLgoKVGhlIGp1ZGdlIHN0aWxsIHdhaXRzIGZvciBlYWNoIGdlbmVyYXRvciB0byBwcm92aWRlIGl0IHdpdGggYSB2YWx1ZSBiZWZvcmUgY29tcGFyaW5nIHRoZW0gKHVzaW5nIHRoZSBzYW1lIGNvbXBhcmlzb24gbWV0aG9kIGFzIGJlZm9yZSkuIEl0IGtlZXBzIHRyYWNrIG9mIHRoZSBvcmRlciBpdCByZWNlaXZlcyB2YWx1ZXM7IHRoZSBmaXJzdCB2YWx1ZXMgZnJvbSBlYWNoIGdlbmVyYXRvciBhcmUgY29tcGFyZWQsIHRoZW4gdGhlIHNlY29uZCB2YWx1ZXMgZnJvbSBlYWNoIGdlbmVyYXRvciwgdGhlbiB0aGUgdGhpcmQgdmFsdWVzLCBhbmQgc28gb24uCgpVc2luZyB0aGUgZXhhbXBsZSBzdGFydGluZyB2YWx1ZXMgZ2l2ZW4gYWJvdmUsIHRoZSBnZW5lcmF0b3JzIG5vdyBwcm9kdWNlIHRoZSBmb2xsb3dpbmcgZmlyc3QgZml2ZSB2YWx1ZXMgZWFjaDoKCi0tR2VuLiBBLS0gIC0tR2VuLiBCLS0KMTM1MjYzNjQ1MiAgMTIzMzY4Mzg0OAoxOTkyMDgxMDcyICAgODYyNTE2MzUyCiA1MzA4MzA0MzYgIDExNTk3ODQ1NjgKMTk4MDAxNzA3MiAgMTYxNjA1NzY3MgogNzQwMzM1MTkyICAgNDEyMjY5MzkyClRoZXNlIHZhbHVlcyBoYXZlIHRoZSBmb2xsb3dpbmcgY29ycmVzcG9uZGluZyBiaW5hcnkgdmFsdWVzOgoKYGBgCjAxMDEwMDAwMTAwMTExMTExMDAxMTAwMDAwMTAwMTAwCjAxMDAxMDAxMTAwMDEwMDAxMDAwMDEwMTEwMDAxMDAwCgowMTExMDExMDEwMTExMTAwMTAxMTExMTAxMDExMDAwMAowMDExMDAxMTAxMTAxMDAwMTExMTAxMDAxMDAwMDAwMAoKMDAwMTExMTExMDEwMDAxMTExMDEwMTAwMDExMDAxMDAKMDEwMDAxMDEwMDEwMDAwMDExMTAxMDAwMDExMTEwMDAKCjAxMTEwMTEwMDAwMDAxMDAxMDEwMTAwMTEwMTEwMDAwCjAxMTAwMDAwMDEwMTAwMTEwMDAxMDEwMTAxMDAxMDAwCgowMDEwMTEwMDAwMTAwMDAwMTAwMTExMTAwMTAxMTAwMAowMDAxMTAwMDEwMDEwMDEwMTAxMTEwMTEwMTAxMDAwMApgYGAKVW5mb3J0dW5hdGVseSwgZXZlbiB0aG91Z2ggdGhpcyBjaGFuZ2UgbWFrZXMgbW9yZSBiaXRzIHNpbWlsYXIgb24gYXZlcmFnZSwgbm9uZSBvZiB0aGVzZSB2YWx1ZXMnIGxvd2VzdCAxNiBiaXRzIG1hdGNoLiBOb3csIGl0J3Mgbm90IHVudGlsIHRoZSAxMDU2dGggcGFpciB0aGF0IHRoZSBqdWRnZSBmaW5kcyB0aGUgZmlyc3QgbWF0Y2g6CgpgYGAKLS1HZW4uIEEtLSAgLS1HZW4uIEItLQoxMDIzNzYyOTEyICAgODk2ODg1MjE2CgowMDExMTEwMTAwMDAwMTAxMDExMDAwMDExMTEwMDAwMAowMDExMDEwMTAxMTEwMTAxMDExMDAwMDExMTEwMDAwMApgYGAKVGhpcyBjaGFuZ2UgbWFrZXMgdGhlIGdlbmVyYXRvcnMgbXVjaCBzbG93ZXIsIGFuZCB0aGUganVkZ2UgaXMgZ2V0dGluZyBpbXBhdGllbnQ7IGl0IGlzIG5vdyBvbmx5IHdpbGxpbmcgdG8gY29uc2lkZXIgNSBtaWxsaW9uIHBhaXJzLiAoVXNpbmcgdGhlIHZhbHVlcyBmcm9tIHRoZSBleGFtcGxlIGFib3ZlLCBhZnRlciBmaXZlIG1pbGxpb24gcGFpcnMsIHRoZSBqdWRnZSB3b3VsZCBldmVudHVhbGx5IGZpbmQgYSB0b3RhbCBvZiAzMDkgcGFpcnMgdGhhdCBtYXRjaCBpbiB0aGVpciBsb3dlc3QgMTYgYml0cy4pCgpBZnRlciA1IG1pbGxpb24gcGFpcnMsIGJ1dCB1c2luZyB0aGlzIG5ldyBnZW5lcmF0b3IgbG9naWMsIHdoYXQgaXMgdGhlIGp1ZGdlJ3MgZmluYWwgY291bnQ/CgoKCiMjIEJyaWVmCjwhLS0gSW5zZXJ0IFBhcnQgMiBvZiB0aGUgcHV6emxlIGJyaWVmIGhlcmUgLS0+CgoKIyBMZXQncyBnbwoKYGBge3J9Cm5leHRfaW50MiA8LSBmdW5jdGlvbihjLCBmLCBkKSB7CiAgICBjIDwtIChjICogZikgJSUgMjE0NzQ4MzY0NyAKICAgIHdoaWxlKGMgJSUgZCAhPSAwKXsKICAgICAgICBjIDwtIChjICogZikgJSUgMjE0NzQ4MzY0NwogICAgfQogICAgYwp9CiAgICAgICAgCiBtYXRjaGVzMiA8LSBmdW5jdGlvbihuLCBBID0gNjUsIEIgPSA4OTIxKXsKICAgIG1hdGNoIDwtIDAKICAgIGN1cnJlbnQgPC0gYyhBLCBCKQogICAgZm9yKGkgaW4gMTpuKXsKICAgICAgICBjdXJyZW50IDwtIGMobmV4dF9pbnQyKGN1cnJlbnRbMV0sIGYgPSAxNjgwNywgZCA9IDQpLCBuZXh0X2ludDIoY3VycmVudFsyXSwgZiA9IDQ4MjcxLCBkPSA4KSkKICAgICAgICBtYXRjaCA8LSBtYXRjaCArIChiaXR3QW5kKGN1cnJlbnRbMV0sMHhmZmZmKSA9PSBiaXR3QW5kKGN1cnJlbnRbMl0sMHhmZmZmKSkKICAgIH0KICAgIG1hdGNofSAgICAgIAoKYGBgCgoKCiMjIFRlc3QKYGBge3J9CmV4cGVjdF9lcXVhbChtYXRjaGVzMihuID0gNTAwMDAwMCwgQSA9IDY1LCBCID0gODkyMSksIDMwOSkKYGBgCgojIyBkZXBsb3kKCmBgYHtyfQptYXRjaGVzMihuID0gNTAwMDAwMCwgQSA9IDUxNiwgQiA9IDE5MCkKYGBgCgojIyBTdWNjZXNzIQoKCgo8YnI+CgoqKioKCnRlbXBsYXRlIGJhc2VkIG9uIHRoZSBbd29ya2Zsb3dyXShodHRwczovL2dpdGh1Yi5jb20vamRibGlzY2hhay93b3JrZmxvd3IpIHN0YW5kYWxvbmUgdGVtcGxhdGUK