# -*- coding: utf-8 -*-
import copy
from collections import defaultdict
from itertools import product
FALL = '|'
RIVER = '~'
POOL = 'N'
SOURCE = 'x'
SOURCE_AND_FALL = '*'
SOURCE_AND_RIVER = 'X'
SOURCE_AND_POOL = '%'
BLOCK = '#'
LRAMP = '/'
RRAMP = '\\ '
SPACE = ' '
LRAMP_AND_FALL = 'd'
RRAMP_AND_FALL = 'b'
LRAMP_AND_RIVER = '}'
RRAMP_AND_RIVER = '{'
LRAMP_AND_POOL = ']'
RRAMP_AND_POOL = '['
def isSource( cell) :
return cell in [ SOURCE, SOURCE_AND_FALL, SOURCE_AND_RIVER, SOURCE_AND_POOL]
def isLRamp( cell) :
return cell in [ LRAMP, LRAMP_AND_FALL, LRAMP_AND_RIVER, LRAMP_AND_POOL]
def isRRamp( cell) :
return cell in [ RRAMP, RRAMP_AND_FALL, RRAMP_AND_RIVER, RRAMP_AND_POOL]
def isRamp( cell) :
return isLRamp( cell) or isRRamp( cell)
def isFall( cell) :
return cell in [ FALL, SOURCE_AND_FALL, LRAMP_AND_FALL, RRAMP_AND_FALL]
def isRiver( cell) :
return cell in [ RIVER, LRAMP_AND_RIVER, RRAMP_AND_RIVER, SOURCE_AND_RIVER]
def isPool( cell) :
return cell in [ POOL, LRAMP_AND_POOL, RRAMP_AND_POOL, SOURCE_AND_POOL]
def isSpace( cell) :
return cell in [ SPACE, SOURCE, LRAMP, RRAMP]
def isWetAndLeaky( cell) :
return isFall( cell) or isRiver( cell) or isPool( cell) # or isSource(cell) #TODO Should we include source here?
def supportsRiver( cell) :
return cell == BLOCK or isPool( cell)
def isOpenAtBottom( cell) :
return not ( isRamp( cell) or cell == BLOCK)
def waterCanFlowIn( grid, i, j) :
# Can water flow in from left
if not isRRamp( grid[ ( i, j) ] ) and grid[ ( i, j-1 ) ] in [ RIVER, POOL, SOURCE_AND_RIVER, SOURCE_AND_POOL, RRAMP_AND_RIVER, RRAMP_AND_POOL] :
return True
# Can water flow in from left
return not isLRamp( grid[ ( i, j) ] ) and grid[ ( i, j+1 ) ] in [ RIVER, POOL, SOURCE_AND_RIVER, SOURCE_AND_POOL, LRAMP_AND_RIVER, LRAMP_AND_POOL]
def findBackground( cell) :
if cell in [ SPACE, FALL, RIVER, POOL] :
return SPACE
elif cell in [ BLOCK] :
return BLOCK
elif isSource( cell) :
return SOURCE
elif isLRamp( cell) :
return LRAMP
elif isRRamp( cell) :
return RRAMP
raise Exception
def makeSpace( cell) :
background = findBackground( cell)
if background == SPACE:
return SPACE
elif background == SOURCE:
return SOURCE
elif background == LRAMP:
return LRAMP
elif background == RRAMP:
return RRAMP
raise Exception
def makeFall( cell) :
background = findBackground( cell)
if background == SPACE:
return FALL
elif background == SOURCE:
return SOURCE_AND_FALL
elif background == LRAMP:
return LRAMP_AND_RIVER
elif background == RRAMP:
return RRAMP_AND_RIVER
raise Exception
def makeRiver( cell) :
background = findBackground( cell)
if background == SPACE:
return RIVER
elif background == SOURCE:
return SOURCE_AND_RIVER
elif background == LRAMP:
return LRAMP_AND_RIVER
elif background == RRAMP:
return RRAMP_AND_RIVER
raise Exception
def makePool( cell) :
background = findBackground( cell)
if background == SPACE:
return POOL
elif background == SOURCE:
return SOURCE_AND_POOL
elif background == LRAMP:
return LRAMP_AND_POOL
elif background == RRAMP:
return RRAMP_AND_POOL
raise Exception
def isRiverComplete( grid, i, j) :
# Check to left
if not isRRamp( grid[ i, j] ) :
a = j-1
while ( isRiver( grid[ i, a] ) or isPool( grid[ i, a] ) ) and not isRamp( grid[ i, a] ) :
a -= 1
if ( isSpace( grid[ i, a] ) or isFall( grid[ i, a] ) ) and not isLRamp( grid[ i, a] ) :
return False
# Check to right
if not isLRamp( grid[ i, j] ) :
a = j+1
while ( isRiver( grid[ i, a] ) or isPool( grid[ i, a] ) ) and not isRamp( grid[ i, a] ) :
a += 1
if ( isSpace( grid[ i, a] ) or isFall( grid[ i, a] ) ) and not isRRamp( grid[ i, a] ) :
return False
return True
gridStr = """\
x
# #
# #
# #
#### #####
#### #####
#### #####
##########"""
gridCells = map ( lambda x: list ( x) , gridStr.split ( '\n ' ) )
height = len ( gridCells)
width = len ( gridCells[ 0 ] )
grid = defaultdict( lambda : SPACE)
for i in range ( height) :
for j in range ( width) :
grid[ ( i, j) ] = gridCells[ i] [ j]
def displayGrid( grid) :
print
for i in range ( height) :
row = ''
for j in range ( width) :
row = row+grid[ ( i, j) ]
print row
t = 0
while t < 26 :
displayGrid( grid)
newGrid = defaultdict( lambda : SPACE)
for i, j in product( range ( height) , range ( width) ) :
cell = grid[ ( i, j) ]
if cell == FALL and supportsRiver( grid[ ( i+1 , j) ] ) :
#A water fall with ground or pool under it becomes a river.
newGrid[ ( i, j) ] = makeRiver( cell)
elif isSpace( cell) and supportsRiver( grid[ ( i+1 , j) ] ) and waterCanFlowIn( grid, i, j) :
#A space with ground or pool under it and river next to it becomes a river.
newGrid[ ( i, j) ] = makeRiver( cell)
elif isSpace( cell) and isWetAndLeaky( grid[ ( i-1 , j) ] ) :
#A space with a water fall, spring or river above it becomes a water fall.
newGrid[ ( i, j) ] = makeFall( cell)
elif isSpace( cell) and waterCanFlowIn( grid, i, j) :
#A space with a river or pool next to it, and no support below becomes a water fall.
newGrid[ ( i, j) ] = makeFall( cell)
elif isRiver( cell) and isRiverComplete( grid, i, j) :
#A horizontal row of rivers squares bounded at both ends by walls/ramps becomes a horizontal row of pool squares.
newGrid[ ( i, j) ] = makePool( cell)
elif isOpenAtBottom( cell) and isPool( grid[ ( i+1 , j) ] ) and not isPool( cell) :
#A space above a pool becomes a river
newGrid[ ( i, j) ] = makeRiver( cell)
elif isSource( cell) :
#A dry source becomes wet
newGrid[ ( i, j) ] = makeFall( cell)
else :
#Else by default things stay the same
newGrid[ ( i, j) ] = cell
# TODO Drying up rules
#A pool or river without ground under it becomes a water fall (e.g. could be caused by bashing).
#A pool with water fall next to it becomes a river.
#A horizontal collection of river tiles without a water fall or spring above them dries up (I think this rule in particular needs some thinking about).
grid = newGrid
t += 1
displayGrid( grid)
IyAtKi0gY29kaW5nOiB1dGYtOCAtKi0KaW1wb3J0IGNvcHkKZnJvbSBjb2xsZWN0aW9ucyBpbXBvcnQgZGVmYXVsdGRpY3QKZnJvbSBpdGVydG9vbHMgaW1wb3J0IHByb2R1Y3QKIApGQUxMID0gJ3wnClJJVkVSID0gJ34nClBPT0wgPSAnTicKIApTT1VSQ0UgPSAneCcKU09VUkNFX0FORF9GQUxMID0gJyonClNPVVJDRV9BTkRfUklWRVIgPSAnWCcKU09VUkNFX0FORF9QT09MID0gJyUnCiAKQkxPQ0sgPSAnIycKTFJBTVAgPSAnLycKUlJBTVAgPSAnXFwnClNQQUNFID0gJyAnCiAKTFJBTVBfQU5EX0ZBTEwgPSAnZCcKUlJBTVBfQU5EX0ZBTEwgPSAnYicKTFJBTVBfQU5EX1JJVkVSID0gJ30nClJSQU1QX0FORF9SSVZFUiA9ICd7JwpMUkFNUF9BTkRfUE9PTCA9ICddJwpSUkFNUF9BTkRfUE9PTCA9ICdbJwogCmRlZiBpc1NvdXJjZShjZWxsKToKICAgIHJldHVybiBjZWxsIGluIFtTT1VSQ0UsIFNPVVJDRV9BTkRfRkFMTCwgU09VUkNFX0FORF9SSVZFUiwgU09VUkNFX0FORF9QT09MXQogCmRlZiBpc0xSYW1wKGNlbGwpOgogICAgcmV0dXJuIGNlbGwgaW4gW0xSQU1QLCBMUkFNUF9BTkRfRkFMTCwgTFJBTVBfQU5EX1JJVkVSLCBMUkFNUF9BTkRfUE9PTF0KZGVmIGlzUlJhbXAoY2VsbCk6CiAgICByZXR1cm4gY2VsbCBpbiBbUlJBTVAsIFJSQU1QX0FORF9GQUxMLCBSUkFNUF9BTkRfUklWRVIsIFJSQU1QX0FORF9QT09MXQpkZWYgaXNSYW1wKGNlbGwpOgogICAgcmV0dXJuIGlzTFJhbXAoY2VsbCkgb3IgaXNSUmFtcChjZWxsKQogCmRlZiBpc0ZhbGwoY2VsbCk6CiAgICByZXR1cm4gY2VsbCBpbiBbRkFMTCwgU09VUkNFX0FORF9GQUxMLCBMUkFNUF9BTkRfRkFMTCwgUlJBTVBfQU5EX0ZBTExdCmRlZiBpc1JpdmVyKGNlbGwpOgogICAgcmV0dXJuIGNlbGwgaW4gW1JJVkVSLCBMUkFNUF9BTkRfUklWRVIsIFJSQU1QX0FORF9SSVZFUiwgU09VUkNFX0FORF9SSVZFUl0KZGVmIGlzUG9vbChjZWxsKToKICAgIHJldHVybiBjZWxsIGluIFtQT09MLCBMUkFNUF9BTkRfUE9PTCwgUlJBTVBfQU5EX1BPT0wsIFNPVVJDRV9BTkRfUE9PTF0KZGVmIGlzU3BhY2UoY2VsbCk6CiAgICByZXR1cm4gY2VsbCBpbiBbU1BBQ0UsIFNPVVJDRSwgTFJBTVAsIFJSQU1QXQogCmRlZiBpc1dldEFuZExlYWt5KGNlbGwpOgogICAgcmV0dXJuIGlzRmFsbChjZWxsKSBvciBpc1JpdmVyKGNlbGwpIG9yIGlzUG9vbChjZWxsKSMgb3IgaXNTb3VyY2UoY2VsbCkgI1RPRE8gU2hvdWxkIHdlIGluY2x1ZGUgc291cmNlIGhlcmU/CmRlZiBzdXBwb3J0c1JpdmVyKGNlbGwpOgogICAgcmV0dXJuIGNlbGwgPT0gQkxPQ0sgb3IgaXNQb29sKGNlbGwpCmRlZiBpc09wZW5BdEJvdHRvbShjZWxsKToKICAgIHJldHVybiBub3QgKGlzUmFtcChjZWxsKSBvciBjZWxsID09IEJMT0NLKQogCmRlZiB3YXRlckNhbkZsb3dJbihncmlkLCBpLCBqKToKICAgICMgQ2FuIHdhdGVyIGZsb3cgaW4gZnJvbSBsZWZ0CiAgICBpZiBub3QgaXNSUmFtcChncmlkWyhpLGopXSkgYW5kIGdyaWRbKGksIGotMSldIGluIFtSSVZFUiwgUE9PTCwgU09VUkNFX0FORF9SSVZFUiwgU09VUkNFX0FORF9QT09MLCBSUkFNUF9BTkRfUklWRVIsIFJSQU1QX0FORF9QT09MXToKICAgICAgICByZXR1cm4gVHJ1ZQogICAgIyBDYW4gd2F0ZXIgZmxvdyBpbiBmcm9tIGxlZnQKICAgIHJldHVybiBub3QgaXNMUmFtcChncmlkWyhpLGopXSkgYW5kIGdyaWRbKGksIGorMSldIGluIFtSSVZFUiwgUE9PTCwgU09VUkNFX0FORF9SSVZFUiwgU09VUkNFX0FORF9QT09MLCBMUkFNUF9BTkRfUklWRVIsIExSQU1QX0FORF9QT09MXQogCmRlZiBmaW5kQmFja2dyb3VuZChjZWxsKToKICAgIGlmIGNlbGwgaW4gW1NQQUNFLCBGQUxMLCBSSVZFUiwgUE9PTF06CiAgICAgICAgcmV0dXJuIFNQQUNFCiAgICBlbGlmIGNlbGwgaW4gW0JMT0NLXToKICAgICAgICByZXR1cm4gQkxPQ0sKICAgIGVsaWYgaXNTb3VyY2UoY2VsbCk6CiAgICAgICAgcmV0dXJuIFNPVVJDRQogICAgZWxpZiBpc0xSYW1wKGNlbGwpOgogICAgICAgIHJldHVybiBMUkFNUAogICAgZWxpZiBpc1JSYW1wKGNlbGwpOgogICAgICAgIHJldHVybiBSUkFNUAogICAgcmFpc2UgRXhjZXB0aW9uCiAKZGVmIG1ha2VTcGFjZShjZWxsKToKICAgIGJhY2tncm91bmQgPSBmaW5kQmFja2dyb3VuZChjZWxsKQogICAgaWYgYmFja2dyb3VuZCA9PSBTUEFDRToKICAgICAgICByZXR1cm4gU1BBQ0UKICAgIGVsaWYgYmFja2dyb3VuZCA9PSBTT1VSQ0U6CiAgICAgICAgcmV0dXJuIFNPVVJDRQogICAgZWxpZiBiYWNrZ3JvdW5kID09IExSQU1QOgogICAgICAgIHJldHVybiBMUkFNUAogICAgZWxpZiBiYWNrZ3JvdW5kID09IFJSQU1QOgogICAgICAgIHJldHVybiBSUkFNUAogICAgcmFpc2UgRXhjZXB0aW9uCmRlZiBtYWtlRmFsbChjZWxsKToKICAgIGJhY2tncm91bmQgPSBmaW5kQmFja2dyb3VuZChjZWxsKQogICAgaWYgYmFja2dyb3VuZCA9PSBTUEFDRToKICAgICAgICByZXR1cm4gRkFMTAogICAgZWxpZiBiYWNrZ3JvdW5kID09IFNPVVJDRToKICAgICAgICByZXR1cm4gU09VUkNFX0FORF9GQUxMCiAgICBlbGlmIGJhY2tncm91bmQgPT0gTFJBTVA6CiAgICAgICAgcmV0dXJuIExSQU1QX0FORF9SSVZFUgogICAgZWxpZiBiYWNrZ3JvdW5kID09IFJSQU1QOgogICAgICAgIHJldHVybiBSUkFNUF9BTkRfUklWRVIKICAgIHJhaXNlIEV4Y2VwdGlvbgpkZWYgbWFrZVJpdmVyKGNlbGwpOgogICAgYmFja2dyb3VuZCA9IGZpbmRCYWNrZ3JvdW5kKGNlbGwpCiAgICBpZiBiYWNrZ3JvdW5kID09IFNQQUNFOgogICAgICAgIHJldHVybiBSSVZFUgogICAgZWxpZiBiYWNrZ3JvdW5kID09IFNPVVJDRToKICAgICAgICByZXR1cm4gU09VUkNFX0FORF9SSVZFUgogICAgZWxpZiBiYWNrZ3JvdW5kID09IExSQU1QOgogICAgICAgIHJldHVybiBMUkFNUF9BTkRfUklWRVIKICAgIGVsaWYgYmFja2dyb3VuZCA9PSBSUkFNUDoKICAgICAgICByZXR1cm4gUlJBTVBfQU5EX1JJVkVSCiAgICByYWlzZSBFeGNlcHRpb24KZGVmIG1ha2VQb29sKGNlbGwpOgogICAgYmFja2dyb3VuZCA9IGZpbmRCYWNrZ3JvdW5kKGNlbGwpCiAgICBpZiBiYWNrZ3JvdW5kID09IFNQQUNFOgogICAgICAgIHJldHVybiBQT09MCiAgICBlbGlmIGJhY2tncm91bmQgPT0gU09VUkNFOgogICAgICAgIHJldHVybiBTT1VSQ0VfQU5EX1BPT0wKICAgIGVsaWYgYmFja2dyb3VuZCA9PSBMUkFNUDoKICAgICAgICByZXR1cm4gTFJBTVBfQU5EX1BPT0wKICAgIGVsaWYgYmFja2dyb3VuZCA9PSBSUkFNUDoKICAgICAgICByZXR1cm4gUlJBTVBfQU5EX1BPT0wKICAgIHJhaXNlIEV4Y2VwdGlvbgogCmRlZiBpc1JpdmVyQ29tcGxldGUoZ3JpZCwgaSwgaik6CiAgICAjIENoZWNrIHRvIGxlZnQKICAgIGlmIG5vdCBpc1JSYW1wKGdyaWRbaSxqXSk6CiAgICAgICAgYSA9IGotMQogICAgICAgIHdoaWxlIChpc1JpdmVyKGdyaWRbaSwgYV0pIG9yIGlzUG9vbChncmlkW2ksIGFdKSkgYW5kIG5vdCBpc1JhbXAoZ3JpZFtpLCBhXSk6CiAgICAgICAgICAgIGEgLT0gMQogICAgICAgIGlmIChpc1NwYWNlKGdyaWRbaSwgYV0pIG9yIGlzRmFsbChncmlkW2ksIGFdKSkgYW5kIG5vdCBpc0xSYW1wKGdyaWRbaSwgYV0pOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgICMgQ2hlY2sgdG8gcmlnaHQKICAgIGlmIG5vdCBpc0xSYW1wKGdyaWRbaSxqXSk6CiAgICAgICAgYSA9IGorMQogICAgICAgIHdoaWxlIChpc1JpdmVyKGdyaWRbaSwgYV0pIG9yIGlzUG9vbChncmlkW2ksIGFdKSkgYW5kIG5vdCBpc1JhbXAoZ3JpZFtpLCBhXSk6CiAgICAgICAgICAgIGEgKz0gMQogICAgICAgIGlmIChpc1NwYWNlKGdyaWRbaSwgYV0pIG9yIGlzRmFsbChncmlkW2ksIGFdKSkgYW5kIG5vdCBpc1JSYW1wKGdyaWRbaSwgYV0pOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgIHJldHVybiBUcnVlCiAKZ3JpZFN0ciA9ICIiIlwKICAgeCAgICAgIAojICAgICAgICAjCiMgICAgICAgICMKIyAgICAgICAgIwojIyMjICMjIyMjCiMjIyMgIyMjIyMKIyMjIyAjIyMjIwojIyMjIyMjIyMjIiIiCmdyaWRDZWxscyA9IG1hcChsYW1iZGEgeDogbGlzdCh4KSwgZ3JpZFN0ci5zcGxpdCgnXG4nKSkKaGVpZ2h0ID0gbGVuKGdyaWRDZWxscykKd2lkdGggPSBsZW4oZ3JpZENlbGxzWzBdKQpncmlkID0gZGVmYXVsdGRpY3QobGFtYmRhIDogU1BBQ0UpCmZvciBpIGluIHJhbmdlKGhlaWdodCk6CiAgICBmb3IgaiBpbiByYW5nZSh3aWR0aCk6CiAgICAgICAgZ3JpZFsoaSxqKV0gPSBncmlkQ2VsbHNbaV1bal0KIApkZWYgZGlzcGxheUdyaWQoZ3JpZCk6CiAgICBwcmludAogICAgZm9yIGkgaW4gcmFuZ2UoaGVpZ2h0KToKICAgICAgICByb3cgPSAnJwogICAgICAgIGZvciBqIGluIHJhbmdlKHdpZHRoKToKICAgICAgICAgICAgcm93ID0gcm93K2dyaWRbKGksaildCiAgICAgICAgcHJpbnQgcm93CiAKdCA9IDAKd2hpbGUgdCA8IDI2OgogICAgZGlzcGxheUdyaWQoZ3JpZCkKICAgIG5ld0dyaWQgPSBkZWZhdWx0ZGljdChsYW1iZGEgOiBTUEFDRSkKICAgIGZvciBpLCBqIGluIHByb2R1Y3QocmFuZ2UoaGVpZ2h0KSwgcmFuZ2Uod2lkdGgpKToKICAgICAgICBjZWxsID0gZ3JpZFsoaSxqKV0KICAgICAgICBpZiBjZWxsID09IEZBTEwgYW5kIHN1cHBvcnRzUml2ZXIoZ3JpZFsoaSsxLCBqKV0pOgogICAgICAgICAgICAjQSB3YXRlciBmYWxsIHdpdGggZ3JvdW5kIG9yIHBvb2wgdW5kZXIgaXQgYmVjb21lcyBhIHJpdmVyLgogICAgICAgICAgICBuZXdHcmlkWyhpLGopXSA9IG1ha2VSaXZlcihjZWxsKQogICAgICAgIGVsaWYgaXNTcGFjZShjZWxsKSBhbmQgc3VwcG9ydHNSaXZlcihncmlkWyhpKzEsIGopXSkgYW5kIHdhdGVyQ2FuRmxvd0luKGdyaWQsIGksIGopOgogICAgICAgICAgICAjQSBzcGFjZSB3aXRoIGdyb3VuZCBvciBwb29sIHVuZGVyIGl0IGFuZCByaXZlciBuZXh0IHRvIGl0IGJlY29tZXMgYSByaXZlci4KICAgICAgICAgICAgbmV3R3JpZFsoaSxqKV0gPSBtYWtlUml2ZXIoY2VsbCkKICAgICAgICBlbGlmIGlzU3BhY2UoY2VsbCkgYW5kIGlzV2V0QW5kTGVha3koZ3JpZFsoaS0xLGopXSk6CiAgICAgICAgICAgICNBIHNwYWNlIHdpdGggYSB3YXRlciBmYWxsLCBzcHJpbmcgb3Igcml2ZXIgYWJvdmUgaXQgYmVjb21lcyBhIHdhdGVyIGZhbGwuCiAgICAgICAgICAgIG5ld0dyaWRbKGksaildID0gbWFrZUZhbGwoY2VsbCkKICAgICAgICBlbGlmIGlzU3BhY2UoY2VsbCkgYW5kIHdhdGVyQ2FuRmxvd0luKGdyaWQsIGksIGopOgogICAgICAgICAgICAjQSBzcGFjZSB3aXRoIGEgcml2ZXIgb3IgcG9vbCBuZXh0IHRvIGl0LCBhbmQgbm8gc3VwcG9ydCBiZWxvdyBiZWNvbWVzIGEgd2F0ZXIgZmFsbC4KICAgICAgICAgICAgbmV3R3JpZFsoaSxqKV0gPSBtYWtlRmFsbChjZWxsKQogICAgICAgIGVsaWYgaXNSaXZlcihjZWxsKSBhbmQgaXNSaXZlckNvbXBsZXRlKGdyaWQsIGksIGopOgogICAgICAgICAgICAjQSBob3Jpem9udGFsIHJvdyBvZiByaXZlcnMgc3F1YXJlcyBib3VuZGVkIGF0IGJvdGggZW5kcyBieSB3YWxscy9yYW1wcyBiZWNvbWVzIGEgaG9yaXpvbnRhbCByb3cgb2YgcG9vbCBzcXVhcmVzLgogICAgICAgICAgICBuZXdHcmlkWyhpLGopXSA9IG1ha2VQb29sKGNlbGwpCiAgICAgICAgZWxpZiBpc09wZW5BdEJvdHRvbShjZWxsKSBhbmQgaXNQb29sKGdyaWRbKGkrMSwgaildKSBhbmQgbm90IGlzUG9vbChjZWxsKToKICAgICAgICAgICAgI0Egc3BhY2UgYWJvdmUgYSBwb29sIGJlY29tZXMgYSByaXZlcgogICAgICAgICAgICBuZXdHcmlkWyhpLGopXSA9IG1ha2VSaXZlcihjZWxsKQogICAgICAgIGVsaWYgaXNTb3VyY2UoY2VsbCk6CiAgICAgICAgICAgICNBIGRyeSBzb3VyY2UgYmVjb21lcyB3ZXQKICAgICAgICAgICAgbmV3R3JpZFsoaSxqKV0gPSBtYWtlRmFsbChjZWxsKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgICNFbHNlIGJ5IGRlZmF1bHQgdGhpbmdzIHN0YXkgdGhlIHNhbWUKICAgICAgICAgICAgbmV3R3JpZFsoaSxqKV0gPSBjZWxsCiAKIyBUT0RPIERyeWluZyB1cCBydWxlcyAgICAgICAgICAgIAojQSBwb29sIG9yIHJpdmVyIHdpdGhvdXQgZ3JvdW5kIHVuZGVyIGl0IGJlY29tZXMgYSB3YXRlciBmYWxsIChlLmcuIGNvdWxkIGJlIGNhdXNlZCBieSBiYXNoaW5nKS4KI0EgcG9vbCB3aXRoIHdhdGVyIGZhbGwgbmV4dCB0byBpdCBiZWNvbWVzIGEgcml2ZXIuCiNBIGhvcml6b250YWwgY29sbGVjdGlvbiBvZiByaXZlciB0aWxlcyB3aXRob3V0IGEgd2F0ZXIgZmFsbCBvciBzcHJpbmcgYWJvdmUgdGhlbSBkcmllcyB1cCAoSSB0aGluayB0aGlzIHJ1bGUgaW4gcGFydGljdWxhciBuZWVkcyBzb21lIHRoaW5raW5nIGFib3V0KS4KIAogICAgZ3JpZCA9IG5ld0dyaWQKICAgIHQgKz0gMQogCmRpc3BsYXlHcmlkKGdyaWQp