input<-read_lines("Day6Sample.txt")
### obstructions go into a dictionary 
### and locate the guard & size of the lab
obst<-dict()
for (i in 1:length(input)){
  xs<-str_locate_all(input[i],"#")[[1]][,1]
  if(length(xs)>0){
    for(j in 1:length(xs)){
      obst$set(str_c(xs[j],"~",i),0)}}
  if(str_detect(input[i],"\\^")){
    guard<-c(str_locate(input[i],"\\^")[1],i)}}
labrows<-length(input)
labcolumns<-nchar(input[i])

Part 1

Follow the path - take in the dictonary of obstructions, guard position, number of rows, and number of columns

find_distinct_positions<-function(o,g,lr,lc){
  ### Vector of visited positions
  visited<-c(str_flatten(g,collapse="~"))
  ### starting direction
  dr<-"U"
  keepgoing<-TRUE
  ### while it hasn't hit the edge
  while(keepgoing){
    ### depending on the direction - if there's something in front, turn right.  if not, move forward
    switch(dr,
           "U"={if(o$has(str_flatten(g+c(0,-1),collapse="~"))){
             dr<-"R"}else{g<-g+c(0,-1)}},
           "R"={if(o$has(str_flatten(g+c(1,0),collapse="~"))){
             dr<-"D"}else{g<-g+c(1,0)}},
           "D"={if(o$has(str_flatten(g+c(0,1),collapse="~"))){
             dr<-"L"}else{g<-g+c(0,1)}},
           "L"={if(o$has(str_flatten(g+c(-1,0),collapse="~"))){
             dr<-"U"}else{g<-g+c(-1,0)}},
           cat("bad direction\n"))
    visited<-c(visited,str_flatten(g,collapse="~"))
    ### check to see if about to run off the edge
    if((dr=="U"&&g[2]==1)||(dr=="L"&&g[1]==1)||(dr=="D"&&g[2]==lr)||(dr=="R"&&g[1]==lc)){keepgoing<-FALSE}}
  
visited<-unique(visited)
length(visited)}
part1<-find_distinct_positions(obst,guard,labrows,labcolumns)
part1
[1] 41
Guard Path for my input
Guard Path for my input

Part 2

My original thought is to re-run this over and over again putting an obstacle in every step along the path; which means I can’t use a dictionary for the obstacles

obvec<-c()
for (i in 1:length(input)){
  xs<-str_locate_all(input[i],"#")[[1]][,1]
  if(length(xs)>0){
    for(j in 1:length(xs)){
      obvec<-c(obvec,str_c(xs[j],"~",i))}}}

And change the pathfinder to use a vector instead and return the steps along the path

fdpv<-function(o,g,lr,lc){
  ### Vector of visited positions
  visited<-c(str_flatten(g,collapse="~"))
  ### starting direction
  dr<-"U"
  keepgoing<-TRUE
  ### while it hasn't hit the edge
  while(keepgoing){
    ### depending on the direction - if there's something in front, turn right.  if not, move forward
    switch(dr,
           "U"={if((str_flatten(g+c(0,-1),collapse="~"))%in%o){
             dr<-"R"}else{g<-g+c(0,-1)}},
           "R"={if((str_flatten(g+c(1,0),collapse="~"))%in%o){
             dr<-"D"}else{g<-g+c(1,0)}},
           "D"={if((str_flatten(g+c(0,1),collapse="~"))%in%o){
             dr<-"L"}else{g<-g+c(0,1)}},
           "L"={if((str_flatten(g+c(-1,0),collapse="~"))%in%o){
             dr<-"U"}else{g<-g+c(-1,0)}},
           cat("bad direction\n"))
    visited<-c(visited,str_flatten(g,collapse="~"))
    ### check to see if about to run off the edge
    if((dr=="U"&&g[2]==1)||(dr=="L"&&g[1]==1)||(dr=="D"&&g[2]==lr)||(dr=="R"&&g[1]==lc)){keepgoing<-FALSE}}
  
  visited<-unique(visited)
  ### return visited to get the path
  visited}
guardpath<-fdpv(obvec,guard,labrows,labcolumns)
### take out the starting guard space
guardpath<-guardpath[which(guardpath!=str_flatten(guard,collapse="~"))]

This is much the same, but returns whether or not the guard is in a loop

guardloop<-function(o,g,lr,lc){
  ### starting direction
  dr<-"U"
  ### create a dictionary of places/direction combos
  beenthere<-dict()
  beenthere$set(str_flatten(c(g,dr),collapse="~"),0)
  keepgoing<-TRUE
  ### while it hasn't hit the edge
  while(keepgoing){
    ### depending on the direction - if there's something in front, turn right.  if not, move forward
    switch(dr,
           "U"={if((str_flatten(g+c(0,-1),collapse="~"))%in%o){
             dr<-"R"}else{g<-g+c(0,-1)}},
           "R"={if((str_flatten(g+c(1,0),collapse="~"))%in%o){
             dr<-"D"}else{g<-g+c(1,0)}},
           "D"={if((str_flatten(g+c(0,1),collapse="~"))%in%o){
             dr<-"L"}else{g<-g+c(0,1)}},
           "L"={if((str_flatten(g+c(-1,0),collapse="~"))%in%o){
             dr<-"U"}else{g<-g+c(-1,0)}},
           cat("bad direction\n"))
    ### check to see if have been in this position before with this direction
    if(beenthere$has(str_flatten(c(g,dr),collapse="~"))){
      loop<-TRUE
      keepgoing<-FALSE
    }else{
      beenthere$set(str_flatten(c(g,dr),collapse="~"),0)}
    ### check to see if about to run off the edge, if so, loop is FALSE
    if((dr=="U"&&g[2]==1)||(dr=="L"&&g[1]==1)||(dr=="D"&&g[2]==lr)||(dr=="R"&&g[1]==lc)){
      keepgoing<-FALSE
      loop<-FALSE}}
  loop}

Finally, check each step in the path to see if it is a loop or not

obplace<-function(o,g,lr,lc,gp){
  obcounter<-0
  for(i in 1:length(gp)){
    ### check to see if this is a loop if you add something into 
    isloop<-guardloop(c(o,gp[i]),g,lr,lc)
    if(isloop){obcounter<-obcounter+1}}
  obcounter}
part2<-obplace(obvec,guard,labrows,labcolumns,guardpath)
part2
[1] 6
LS0tDQp0aXRsZTogIkRheSA2IE5vdGVib29rIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KGdnYW5pbWF0ZSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KGtuaXRyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoY29sbGVjdGlvbnMpDQpvcHRpb25zKHNjaXBlbiA9IDk5OSkNCmBgYA0KDQpgYGB7cn0NCmlucHV0PC1yZWFkX2xpbmVzKCJEYXk2U2FtcGxlLnR4dCIpDQojIyMgb2JzdHJ1Y3Rpb25zIGdvIGludG8gYSBkaWN0aW9uYXJ5IA0KIyMjIGFuZCBsb2NhdGUgdGhlIGd1YXJkICYgc2l6ZSBvZiB0aGUgbGFiDQpvYnN0PC1kaWN0KCkNCmZvciAoaSBpbiAxOmxlbmd0aChpbnB1dCkpew0KICB4czwtc3RyX2xvY2F0ZV9hbGwoaW5wdXRbaV0sIiMiKVtbMV1dWywxXQ0KICBpZihsZW5ndGgoeHMpPjApew0KICAgIGZvcihqIGluIDE6bGVuZ3RoKHhzKSl7DQogICAgICBvYnN0JHNldChzdHJfYyh4c1tqXSwifiIsaSksMCl9fQ0KICBpZihzdHJfZGV0ZWN0KGlucHV0W2ldLCJcXF4iKSl7DQogICAgZ3VhcmQ8LWMoc3RyX2xvY2F0ZShpbnB1dFtpXSwiXFxeIilbMV0saSl9fQ0KbGFicm93czwtbGVuZ3RoKGlucHV0KQ0KbGFiY29sdW1uczwtbmNoYXIoaW5wdXRbaV0pDQpgYGANCg0KDQoNCg0KIyMgUGFydCAxDQoNCkZvbGxvdyB0aGUgcGF0aCAtDQp0YWtlIGluIHRoZSBkaWN0b25hcnkgb2Ygb2JzdHJ1Y3Rpb25zLCBndWFyZCBwb3NpdGlvbiwgbnVtYmVyIG9mIHJvd3MsIGFuZCBudW1iZXIgb2YgY29sdW1ucyANCg0KYGBge3J9DQpmaW5kX2Rpc3RpbmN0X3Bvc2l0aW9uczwtZnVuY3Rpb24obyxnLGxyLGxjKXsNCiAgIyMjIFZlY3RvciBvZiB2aXNpdGVkIHBvc2l0aW9ucw0KICB2aXNpdGVkPC1jKHN0cl9mbGF0dGVuKGcsY29sbGFwc2U9In4iKSkNCiAgIyMjIHN0YXJ0aW5nIGRpcmVjdGlvbg0KICBkcjwtIlUiDQogIGtlZXBnb2luZzwtVFJVRQ0KICAjIyMgd2hpbGUgaXQgaGFzbid0IGhpdCB0aGUgZWRnZQ0KICB3aGlsZShrZWVwZ29pbmcpew0KICAgICMjIyBkZXBlbmRpbmcgb24gdGhlIGRpcmVjdGlvbiAtIGlmIHRoZXJlJ3Mgc29tZXRoaW5nIGluIGZyb250LCB0dXJuIHJpZ2h0LiAgaWYgbm90LCBtb3ZlIGZvcndhcmQNCiAgICBzd2l0Y2goZHIsDQogICAgICAgICAgICJVIj17aWYobyRoYXMoc3RyX2ZsYXR0ZW4oZytjKDAsLTEpLGNvbGxhcHNlPSJ+IikpKXsNCiAgICAgICAgICAgICBkcjwtIlIifWVsc2V7ZzwtZytjKDAsLTEpfX0sDQogICAgICAgICAgICJSIj17aWYobyRoYXMoc3RyX2ZsYXR0ZW4oZytjKDEsMCksY29sbGFwc2U9In4iKSkpew0KICAgICAgICAgICAgIGRyPC0iRCJ9ZWxzZXtnPC1nK2MoMSwwKX19LA0KICAgICAgICAgICAiRCI9e2lmKG8kaGFzKHN0cl9mbGF0dGVuKGcrYygwLDEpLGNvbGxhcHNlPSJ+IikpKXsNCiAgICAgICAgICAgICBkcjwtIkwifWVsc2V7ZzwtZytjKDAsMSl9fSwNCiAgICAgICAgICAgIkwiPXtpZihvJGhhcyhzdHJfZmxhdHRlbihnK2MoLTEsMCksY29sbGFwc2U9In4iKSkpew0KICAgICAgICAgICAgIGRyPC0iVSJ9ZWxzZXtnPC1nK2MoLTEsMCl9fSwNCiAgICAgICAgICAgY2F0KCJiYWQgZGlyZWN0aW9uXG4iKSkNCiAgICB2aXNpdGVkPC1jKHZpc2l0ZWQsc3RyX2ZsYXR0ZW4oZyxjb2xsYXBzZT0ifiIpKQ0KICAgICMjIyBjaGVjayB0byBzZWUgaWYgYWJvdXQgdG8gcnVuIG9mZiB0aGUgZWRnZQ0KICAgIGlmKChkcj09IlUiJiZnWzJdPT0xKXx8KGRyPT0iTCImJmdbMV09PTEpfHwoZHI9PSJEIiYmZ1syXT09bHIpfHwoZHI9PSJSIiYmZ1sxXT09bGMpKXtrZWVwZ29pbmc8LUZBTFNFfX0NCiAgDQp2aXNpdGVkPC11bmlxdWUodmlzaXRlZCkNCmxlbmd0aCh2aXNpdGVkKX0NCmBgYA0KDQoNCmBgYHtyfQ0KcGFydDE8LWZpbmRfZGlzdGluY3RfcG9zaXRpb25zKG9ic3QsZ3VhcmQsbGFicm93cyxsYWJjb2x1bW5zKQ0KcGFydDENCmBgYA0KIVtHdWFyZCBQYXRoIGZvciBteSBpbnB1dF0oZ3VhcmRzdGVwcy5naWYpDQoNCg0KIyMgUGFydCAyDQoNCk15IG9yaWdpbmFsIHRob3VnaHQgaXMgdG8gcmUtcnVuIHRoaXMgb3ZlciBhbmQgb3ZlciBhZ2FpbiBwdXR0aW5nIGFuIG9ic3RhY2xlIGluIGV2ZXJ5IHN0ZXAgYWxvbmcgdGhlIHBhdGg7IHdoaWNoIG1lYW5zIEkgY2FuJ3QgdXNlIGEgZGljdGlvbmFyeSBmb3IgdGhlIG9ic3RhY2xlcw0KDQpgYGB7cn0NCm9idmVjPC1jKCkNCmZvciAoaSBpbiAxOmxlbmd0aChpbnB1dCkpew0KICB4czwtc3RyX2xvY2F0ZV9hbGwoaW5wdXRbaV0sIiMiKVtbMV1dWywxXQ0KICBpZihsZW5ndGgoeHMpPjApew0KICAgIGZvcihqIGluIDE6bGVuZ3RoKHhzKSl7DQogICAgICBvYnZlYzwtYyhvYnZlYyxzdHJfYyh4c1tqXSwifiIsaSkpfX19DQoNCmBgYA0KDQpBbmQgY2hhbmdlIHRoZSBwYXRoZmluZGVyIHRvIHVzZSBhIHZlY3RvciBpbnN0ZWFkIGFuZCByZXR1cm4gdGhlIHN0ZXBzIGFsb25nIHRoZSBwYXRoIA0KDQpgYGB7cn0NCmZkcHY8LWZ1bmN0aW9uKG8sZyxscixsYyl7DQogICMjIyBWZWN0b3Igb2YgdmlzaXRlZCBwb3NpdGlvbnMNCiAgdmlzaXRlZDwtYyhzdHJfZmxhdHRlbihnLGNvbGxhcHNlPSJ+IikpDQogICMjIyBzdGFydGluZyBkaXJlY3Rpb24NCiAgZHI8LSJVIg0KICBrZWVwZ29pbmc8LVRSVUUNCiAgIyMjIHdoaWxlIGl0IGhhc24ndCBoaXQgdGhlIGVkZ2UNCiAgd2hpbGUoa2VlcGdvaW5nKXsNCiAgICAjIyMgZGVwZW5kaW5nIG9uIHRoZSBkaXJlY3Rpb24gLSBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiBmcm9udCwgdHVybiByaWdodC4gIGlmIG5vdCwgbW92ZSBmb3J3YXJkDQogICAgc3dpdGNoKGRyLA0KICAgICAgICAgICAiVSI9e2lmKChzdHJfZmxhdHRlbihnK2MoMCwtMSksY29sbGFwc2U9In4iKSklaW4lbyl7DQogICAgICAgICAgICAgZHI8LSJSIn1lbHNle2c8LWcrYygwLC0xKX19LA0KICAgICAgICAgICAiUiI9e2lmKChzdHJfZmxhdHRlbihnK2MoMSwwKSxjb2xsYXBzZT0ifiIpKSVpbiVvKXsNCiAgICAgICAgICAgICBkcjwtIkQifWVsc2V7ZzwtZytjKDEsMCl9fSwNCiAgICAgICAgICAgIkQiPXtpZigoc3RyX2ZsYXR0ZW4oZytjKDAsMSksY29sbGFwc2U9In4iKSklaW4lbyl7DQogICAgICAgICAgICAgZHI8LSJMIn1lbHNle2c8LWcrYygwLDEpfX0sDQogICAgICAgICAgICJMIj17aWYoKHN0cl9mbGF0dGVuKGcrYygtMSwwKSxjb2xsYXBzZT0ifiIpKSVpbiVvKXsNCiAgICAgICAgICAgICBkcjwtIlUifWVsc2V7ZzwtZytjKC0xLDApfX0sDQogICAgICAgICAgIGNhdCgiYmFkIGRpcmVjdGlvblxuIikpDQogICAgdmlzaXRlZDwtYyh2aXNpdGVkLHN0cl9mbGF0dGVuKGcsY29sbGFwc2U9In4iKSkNCiAgICAjIyMgY2hlY2sgdG8gc2VlIGlmIGFib3V0IHRvIHJ1biBvZmYgdGhlIGVkZ2UNCiAgICBpZigoZHI9PSJVIiYmZ1syXT09MSl8fChkcj09IkwiJiZnWzFdPT0xKXx8KGRyPT0iRCImJmdbMl09PWxyKXx8KGRyPT0iUiImJmdbMV09PWxjKSl7a2VlcGdvaW5nPC1GQUxTRX19DQogIA0KICB2aXNpdGVkPC11bmlxdWUodmlzaXRlZCkNCiAgIyMjIHJldHVybiB2aXNpdGVkIHRvIGdldCB0aGUgcGF0aA0KICB2aXNpdGVkfQ0KDQpgYGANCg0KYGBge3J9DQpndWFyZHBhdGg8LWZkcHYob2J2ZWMsZ3VhcmQsbGFicm93cyxsYWJjb2x1bW5zKQ0KIyMjIHRha2Ugb3V0IHRoZSBzdGFydGluZyBndWFyZCBzcGFjZQ0KZ3VhcmRwYXRoPC1ndWFyZHBhdGhbd2hpY2goZ3VhcmRwYXRoIT1zdHJfZmxhdHRlbihndWFyZCxjb2xsYXBzZT0ifiIpKV0NCmBgYA0KDQpUaGlzIGlzIG11Y2ggdGhlIHNhbWUsIGJ1dCByZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSBndWFyZCBpcyBpbiBhIGxvb3ANCg0KYGBge3J9DQpndWFyZGxvb3A8LWZ1bmN0aW9uKG8sZyxscixsYyl7DQogICMjIyBzdGFydGluZyBkaXJlY3Rpb24NCiAgZHI8LSJVIg0KICAjIyMgY3JlYXRlIGEgZGljdGlvbmFyeSBvZiBwbGFjZXMvZGlyZWN0aW9uIGNvbWJvcw0KICBiZWVudGhlcmU8LWRpY3QoKQ0KICBiZWVudGhlcmUkc2V0KHN0cl9mbGF0dGVuKGMoZyxkciksY29sbGFwc2U9In4iKSwwKQ0KICBrZWVwZ29pbmc8LVRSVUUNCiAgIyMjIHdoaWxlIGl0IGhhc24ndCBoaXQgdGhlIGVkZ2UNCiAgd2hpbGUoa2VlcGdvaW5nKXsNCiAgICAjIyMgZGVwZW5kaW5nIG9uIHRoZSBkaXJlY3Rpb24gLSBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiBmcm9udCwgdHVybiByaWdodC4gIGlmIG5vdCwgbW92ZSBmb3J3YXJkDQogICAgc3dpdGNoKGRyLA0KICAgICAgICAgICAiVSI9e2lmKChzdHJfZmxhdHRlbihnK2MoMCwtMSksY29sbGFwc2U9In4iKSklaW4lbyl7DQogICAgICAgICAgICAgZHI8LSJSIn1lbHNle2c8LWcrYygwLC0xKX19LA0KICAgICAgICAgICAiUiI9e2lmKChzdHJfZmxhdHRlbihnK2MoMSwwKSxjb2xsYXBzZT0ifiIpKSVpbiVvKXsNCiAgICAgICAgICAgICBkcjwtIkQifWVsc2V7ZzwtZytjKDEsMCl9fSwNCiAgICAgICAgICAgIkQiPXtpZigoc3RyX2ZsYXR0ZW4oZytjKDAsMSksY29sbGFwc2U9In4iKSklaW4lbyl7DQogICAgICAgICAgICAgZHI8LSJMIn1lbHNle2c8LWcrYygwLDEpfX0sDQogICAgICAgICAgICJMIj17aWYoKHN0cl9mbGF0dGVuKGcrYygtMSwwKSxjb2xsYXBzZT0ifiIpKSVpbiVvKXsNCiAgICAgICAgICAgICBkcjwtIlUifWVsc2V7ZzwtZytjKC0xLDApfX0sDQogICAgICAgICAgIGNhdCgiYmFkIGRpcmVjdGlvblxuIikpDQogICAgIyMjIGNoZWNrIHRvIHNlZSBpZiBoYXZlIGJlZW4gaW4gdGhpcyBwb3NpdGlvbiBiZWZvcmUgd2l0aCB0aGlzIGRpcmVjdGlvbg0KICAgIGlmKGJlZW50aGVyZSRoYXMoc3RyX2ZsYXR0ZW4oYyhnLGRyKSxjb2xsYXBzZT0ifiIpKSl7DQogICAgICBsb29wPC1UUlVFDQogICAgICBrZWVwZ29pbmc8LUZBTFNFDQogICAgfWVsc2V7DQogICAgICBiZWVudGhlcmUkc2V0KHN0cl9mbGF0dGVuKGMoZyxkciksY29sbGFwc2U9In4iKSwwKX0NCiAgICAjIyMgY2hlY2sgdG8gc2VlIGlmIGFib3V0IHRvIHJ1biBvZmYgdGhlIGVkZ2UsIGlmIHNvLCBsb29wIGlzIEZBTFNFDQogICAgaWYoKGRyPT0iVSImJmdbMl09PTEpfHwoZHI9PSJMIiYmZ1sxXT09MSl8fChkcj09IkQiJiZnWzJdPT1scil8fChkcj09IlIiJiZnWzFdPT1sYykpew0KICAgICAga2VlcGdvaW5nPC1GQUxTRQ0KICAgICAgbG9vcDwtRkFMU0V9fQ0KICBsb29wfQ0KYGBgDQoNCkZpbmFsbHksIGNoZWNrIGVhY2ggc3RlcCBpbiB0aGUgcGF0aCB0byBzZWUgaWYgaXQgaXMgYSBsb29wIG9yIG5vdA0KDQpgYGB7cn0NCm9icGxhY2U8LWZ1bmN0aW9uKG8sZyxscixsYyxncCl7DQogIG9iY291bnRlcjwtMA0KICBmb3IoaSBpbiAxOmxlbmd0aChncCkpew0KICAgICMjIyBjaGVjayB0byBzZWUgaWYgdGhpcyBpcyBhIGxvb3AgaWYgeW91IGFkZCBzb21ldGhpbmcgaW50byANCiAgICBpc2xvb3A8LWd1YXJkbG9vcChjKG8sZ3BbaV0pLGcsbHIsbGMpDQogICAgaWYoaXNsb29wKXtvYmNvdW50ZXI8LW9iY291bnRlcisxfX0NCiAgb2Jjb3VudGVyfQ0KDQoNCmBgYA0KDQpgYGB7cn0NCnBhcnQyPC1vYnBsYWNlKG9idmVjLGd1YXJkLGxhYnJvd3MsbGFiY29sdW1ucyxndWFyZHBhdGgpDQpwYXJ0Mg0KYGBgDQoNCmBgYHtyLGV2YWw9RkFMU0UsaW5jbHVkZT1GQUxTRX0NCiMjIyMgZm9yIGdyYXBocyBvbmx5DQpmZHBncjwtZnVuY3Rpb24obyxnLGxyLGxjKXsNCiAgIyMjIFZlY3RvciBvZiB2aXNpdGVkIHBvc2l0aW9ucw0KICBjdHI8LTANCiAgdmlzaXRlZDwtZGF0YS5mcmFtZShtYXRyaXgobmNvbD0zLG5yb3c9MCkpDQogIHZpc2l0ZWQ8LXJiaW5kKHZpc2l0ZWQsYyhnLGN0cikpDQogICMjIyBzdGFydGluZyBkaXJlY3Rpb24NCiAgZHI8LSJVIg0KICBrZWVwZ29pbmc8LVRSVUUNCiAgIyMjIHdoaWxlIGl0IGhhc24ndCBoaXQgdGhlIGVkZ2UNCiAgd2hpbGUoa2VlcGdvaW5nKXsNCiAgICBjdHI8LWN0cisxDQogICAgIyMjIGRlcGVuZGluZyBvbiB0aGUgZGlyZWN0aW9uIC0gaWYgdGhlcmUncyBzb21ldGhpbmcgaW4gZnJvbnQsIHR1cm4gcmlnaHQuICBpZiBub3QsIG1vdmUgZm9yd2FyZA0KICAgIHN3aXRjaChkciwNCiAgICAgICAgICAgIlUiPXtpZihvJGhhcyhzdHJfZmxhdHRlbihnK2MoMCwtMSksY29sbGFwc2U9In4iKSkpew0KICAgICAgICAgICAgIGRyPC0iUiJ9ZWxzZXtnPC1nK2MoMCwtMSl9fSwNCiAgICAgICAgICAgIlIiPXtpZihvJGhhcyhzdHJfZmxhdHRlbihnK2MoMSwwKSxjb2xsYXBzZT0ifiIpKSl7DQogICAgICAgICAgICAgZHI8LSJEIn1lbHNle2c8LWcrYygxLDApfX0sDQogICAgICAgICAgICJEIj17aWYobyRoYXMoc3RyX2ZsYXR0ZW4oZytjKDAsMSksY29sbGFwc2U9In4iKSkpew0KICAgICAgICAgICAgIGRyPC0iTCJ9ZWxzZXtnPC1nK2MoMCwxKX19LA0KICAgICAgICAgICAiTCI9e2lmKG8kaGFzKHN0cl9mbGF0dGVuKGcrYygtMSwwKSxjb2xsYXBzZT0ifiIpKSl7DQogICAgICAgICAgICAgZHI8LSJVIn1lbHNle2c8LWcrYygtMSwwKX19LA0KICAgICAgICAgICBjYXQoImJhZCBkaXJlY3Rpb25cbiIpKQ0KICAgIHZpc2l0ZWQ8LXJiaW5kKHZpc2l0ZWQsYyhnLGN0cikpDQogICAgIyMjIGNoZWNrIHRvIHNlZSBpZiBhYm91dCB0byBydW4gb2ZmIHRoZSBlZGdlDQogICAgaWYoKGRyPT0iVSImJmdbMl09PTEpfHwoZHI9PSJMIiYmZ1sxXT09MSl8fChkcj09IkQiJiZnWzJdPT1scil8fChkcj09IlIiJiZnWzFdPT1sYykpe2tlZXBnb2luZzwtRkFMU0V9fQ0KICANCiAgdmlzaXRlZH0NCg0KDQpncmFwaHBhdGg8LWZkcGdyKG9ic3QsZ3VhcmQsbGFicm93cyxsYWJjb2x1bW5zKQ0KY29sbmFtZXMoZ3JhcGhwYXRoKTwtYygieCIsInkiLCJ0IikNCmBgYA0KDQpgYGB7cixpbmNsdWRlPUZBTFNFLGV2YWw9RkFMU0V9DQojIyMgZm9yIGdyYXBocyBvbmx5DQpndWFyZGdyYXBoPC1nZ3Bsb3QoZ3JhcGhwYXRoKSsNCiAgZ2VvbV9wb2ludChhZXMoeD14LHk9eSkpKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIikrDQogIHNjYWxlX3lfcmV2ZXJzZSgpKw0KICBjb29yZF9maXhlZCgpKw0KICB0cmFuc2l0aW9uX21hbnVhbCh0LGN1bXVsYXRpdmUgPSBUUlVFKSsNCiAgc2hhZG93X21hcmsoKQ0KDQpndWFyZGFuaW0gPC0gYW5pbWF0ZShndWFyZGdyYXBoLGVuZF9wYXVzZSA9IDEwKQ0KZ3VhcmRhbmltDQpgYGANCg==