# 街コロ+ブロックス簡易2Dゲーム
import random
import numpy as np
import collections
from pprint import pprint
# サイコロの準備
Dice=[i for i in range(1,12)]
# MAP
#l=[['0' for i in range(9)] for j in range(9)]
l=[
['0', '0', '0', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', 'A', '0', '0', '0', '0'],
['0', '0', '0', 'B', '0', 'D', '0', '0', '0'],
['0', '0', '0', '0', 'C', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '0', '0', '0']]
# ターン 回数識別用
Times=0
# 最終目標 必要ないかも
Final_Goal=250
# 誰が目的を達成したか判定用 配列
Final_Goal_Flag=[0,0,0,0]
# ユーザー情報 ポイント
USE=[5,5,5,5]
# 回転済み ブロック
Warehouse_Slot=[[[['1', '0', '0'], ['0', '0', '0'], ['0', '0', '0']], [['0', '0', '1'], ['0', '0', '0'], ['0', '0', '0']], [['0', '0', '0'], ['0', '0', '0'], ['0', '0', '1']], [['0', '0', '0'], ['0', '0', '0'], ['1', '0', '0']]], [[['2', '2', '0'], ['0', '0', '0'], ['0', '0', '0']], [['0', '0', '2'], ['0', '0', '2'], ['0', '0', '0']], [['0', '0', '0'], ['0', '0', '0'], ['0', '2', '2']], [['0', '0', '0'], ['2', '0', '0'], ['2', '0', '0']]], [[['2', '0', '2'], ['0', '0', '0'], ['0', '0', '0']], [['0', '0', '2'], ['0', '0', '0'], ['0', '0', '2']], [['0', '0', '0'], ['0', '0', '0'], ['2', '0', '2']], [['2', '0', '0'], ['0', '0', '0'], ['2', '0', '0']]], [[['2', '0', '0'], ['0', '2', '0'], ['0', '0', '0']], [['0', '0', '2'], ['0', '2', '0'], ['0', '0', '0']], [['0', '0', '0'], ['0', '2', '0'], ['0', '0', '2']], [['0', '0', '0'], ['0', '2', '0'], ['2', '0', '0']]], [[['0', '3', '0'], ['3', '3', '3'], ['0', '0', '0']], [['0', '3', '0'], ['0', '3', '3'], ['0', '3', '0']], [['0', '0', '0'], ['3', '3', '3'], ['0', '3', '0']], [['0', '3', '0'], ['3', '3', '0'], ['0', '3', '0']]], [[['3', '3', '0'], ['3', '0', '0'], ['0', '0', '0']], [['0', '3', '3'], ['0', '0', '3'], ['0', '0', '0']], [['0', '0', '0'], ['0', '0', '3'], ['0', '3', '3']], [['0', '0', '0'], ['3', '0', '0'], ['3', '3', '0']]], [[['0', '5', '0'], ['0', '5', '0'], ['5', '5', '5']], [['5', '0', '0'], ['5', '5', '5'], ['5', '0', '0']], [['5', '5', '5'], ['0', '5', '0'], ['0', '5', '0']], [['0', '0', '5'], ['5', '5', '5'], ['0', '0', '5']]], [[['6', '6', '0'], ['6', '0', '0'], ['6', '6', '0']], [['6', '6', '6'], ['6', '0', '6'], ['0', '0', '0']], [['0', '6', '6'], ['0', '0', '6'], ['0', '6', '6']], [['0', '0', '0'], ['6', '0', '6'], ['6', '6', '6']]], [[['0', '7', '7'], ['7', '7', '0'], ['7', '0', '0']], [['7', '7', '0'], ['0', '7', '7'], ['0', '0', '7']], [['0', '0', '7'], ['0', '7', '7'], ['7', '7', '0']], [['7', '0', '0'], ['7', '7', '0'], ['0', '7', '7']]]]
# ブロックの費用と報酬
Warehouse_Slot_Bloku=[1,4,4,4,12,12,25,30,35]
# サイコロの値
def Sample_Demo_New_Bloku_Random_Number():
global Dice
return random.choice(Dice)
# x=座標x y=座標y z=埋め込む配列 Warehouse_Slot[][] ,xyz=0,1,2,3ユーザー識別
def Sample_Demo01(x,y,z,xyz):
# ポイントからブロック費用 購入処理
for k,v in enumerate(Warehouse_Slot):
for i in v:
if i==z:
if USE[xyz]-Warehouse_Slot_Bloku[k]>=0:
USE[xyz]-=Warehouse_Slot_Bloku[k]
else:
return 0
# ユーザー識別用 IDの付与
Local_Block=z
Local_Block2=[]
Local_Block3=[]
for i in Local_Block:
for j in i:
if '0'==j:
Local_Block2.append(j)
else:
if xyz==0:
j='A'+j
Local_Block2.append(j)
elif xyz==1:
j='B'+j
Local_Block2.append(j)
elif xyz==2:
j='C'+j
Local_Block2.append(j)
elif xyz==3:
j='D'+j
Local_Block2.append(j)
Local_Block2=list(zip(*[iter(Local_Block2)]*3))
for i in Local_Block2:Local_Block3.append(list(i))
#pprint(Local_Block3)
# MAPへの配置
for i_r, i_l in enumerate(range(x, min((x+3, 9)))):
for j_r, j_l in enumerate(range(y, min((y+3, 9)))):
if l[j_l][i_l]=='0':
l[j_l][i_l]=Local_Block3[j_r][i_r]
else:
# ユーザー別 初回のみ座標
if l[j_l][i_l]=='A':
l[3][4]#A
elif l[j_l][i_l]=='B':
l[4][3]#B
elif l[j_l][i_l]=='C':
l[5][4]#C
elif l[j_l][i_l]=='D':
l[4][5]#D
# pass
else:
pass
return l
# 各MAP要素の合計
def Sample_Demo_New_Bloku_Initialization(xyz):
c=[]
for i in range(len(xyz)):
c.append(collections.Counter(xyz[i]))
for j in range(len(c)-1):
c[0]+=c[j+1]
return c[0]
# ブロックの中央座標から隣接マスの取得
INDEX01=[]
INDEX02=[]
# ブロックの置ける中央座標を取得
def Sample_Demo00_index01(xyz):
for k,v in enumerate(l):
if xyz in v:INDEX01.append([k,v.index(xyz)])
Sample_Demo00_index02()
# ブロックの置ける周囲座標を取得
def Sample_Demo00_index02():
global INDEX01
INDEX02.append([[INDEX01[0][0]-1,INDEX01[0][1]-1],[INDEX01[0][0]-1,INDEX01[0][1]],[INDEX01[0][0]-1,INDEX01[0][1]+1],[INDEX01[0][0],INDEX01[0][1]-1],INDEX01[0],[INDEX01[0][0],INDEX01[0][1]+1],[INDEX01[0][0-1],INDEX01[0][1]-1],[INDEX01[0][0]+1,INDEX01[0][1]],[INDEX01[0][0]+1,INDEX01[0][1]+1]])
# MAPの再編集 計算用
def Sample_Demo02(x):
global l
Re_Edit=[]
for i in x:
for j in i:
if j=='0':Re_Edit.append(j)
elif len(j)==2:Re_Edit.append([j[0],int(j[1])])
elif len(j)==3:Re_Edit.append([j[0],int(j[1])+int(j[2])])
Re_Edit=list(zip(*[iter(Re_Edit)]*9))
return Re_Edit
# 取得するポイントの取得 NG
def Sample_Demo03(xyz):
global Nasa
# 一時保留倉庫
Nasa=[0,0,0,0]
# MAPに配置されてるブロック別 ポイント取得
Hangout=Sample_Demo_New_Bloku_Initialization(xyz)
for i in Hangout:
if i=='0' or i=='A' or i=='B' or i=='C' or i=='D':
pass
else:
if 'A' in i:
if len(i)==2:
Nasa[0]+=int(i[1])*Hangout[i]
elif len(i)==3:
Nasa[0]+=int(str(i[1])+str(i[2]))*Hangout[i]
elif 'B' in i:
if len(i)==2:
Nasa[1]+=int(i[1])*Hangout[i]
elif len(i)==3:
Nasa[1]+=int(str(i[1])+str(i[2]))*Hangout[i]
elif 'C' in i:
if len(i)==2:
Nasa[2]+=int(i[1])*Hangout[i]
elif len(i)==3:
Nasa[2]+=int(str(i[1])+str(i[2]))*Hangout[i]
elif 'D' in i:
if len(i)==2:
Nasa[3]+=int(i[1])*Hangout[i]
elif len(i)==3:
Nasa[3]+=int(str(i[1])+str(i[2]))*Hangout[i]
else:
print(i,Hangout[i])
print()
# ユーザーポイント 皆
print('ユーザーポイント [','A',USE[0],'','B',USE[1],'','C',USE[2],'','D',USE[3],']')
# ユーザーAが置ける範囲のindexを取得
Sample_Demo00_index01('A')
# indexの表示
print('Aユーザーが置ける範囲',INDEX02),print()
# ブロックを置く ユーザーID
try:pprint(Sample_Demo01(0,0,Warehouse_Slot[2][0],1))
except IndexError:pass
# ポイント取得 仮
Sample_Demo03(l)
# 表示
print('ABCD 仮ポイント',Nasa)
print('サイコロの値',Sample_Demo_New_Bloku_Random_Number())
print()
# ユーザーポイント 皆
print('ユーザーポイント [','A',USE[0],'','B',USE[1],'','C',USE[2],'','D',USE[3],']')
"""
while 250>=USE[0] or 250>=USE[1] or 250>=USE[2] or 250>=USE[3]:
# ターン処理
# Aユーザー
if Times%4==1:
pass
# Bユーザー
elif Times%4==2:
pass
# Cユーザー
elif Times%4==3:
pass
# Dユーザー
elif Times%4==0:
pass
"""
CiMg6KGX44Kz44Ot77yL44OW44Ot44OD44Kv44K557Ch5piT77ySROOCsuODvOODoAoKCmltcG9ydCByYW5kb20KaW1wb3J0IG51bXB5IGFzIG5wCmltcG9ydCBjb2xsZWN0aW9ucwpmcm9tIHBwcmludCBpbXBvcnQgcHByaW50CgojIOOCteOCpOOCs+ODreOBrua6luWCmQpEaWNlPVtpIGZvciBpIGluIHJhbmdlKDEsMTIpXQojIE1BUAojbD1bWycwJyBmb3IgaSBpbiByYW5nZSg5KV0gZm9yIGogaW4gcmFuZ2UoOSldCgpsPVsKIFsnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICdBJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnQicsICcwJywgJ0QnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICdDJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnXV0KCiMg44K/44O844OzIOWbnuaVsOitmOWIpeeUqApUaW1lcz0wCgojIOacgOe1guebruaomeOAgOW/heimgeOBquOBhOOBi+OCggpGaW5hbF9Hb2FsPTI1MAojIOiqsOOBjOebrueahOOCkumBlOaIkOOBl+OBn+OBi+WIpOWumueUqOOAgOmFjeWIlwpGaW5hbF9Hb2FsX0ZsYWc9WzAsMCwwLDBdCgoKIyDjg6bjg7zjgrbjg7zmg4XloLHjgIDjg53jgqTjg7Pjg4gKVVNFPVs1LDUsNSw1XQoKCiMg5Zue6Lui5riI44G/44CA44OW44Ot44OD44KvCldhcmVob3VzZV9TbG90PVtbW1snMScsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMCddLCBbJzAnLCAnMCcsICcwJ11dLCBbWycwJywgJzAnLCAnMSddLCBbJzAnLCAnMCcsICcwJ10sIFsnMCcsICcwJywgJzAnXV0sIFtbJzAnLCAnMCcsICcwJ10sIFsnMCcsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMSddXSwgW1snMCcsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMCddLCBbJzEnLCAnMCcsICcwJ11dXSwgW1tbJzInLCAnMicsICcwJ10sIFsnMCcsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMCddXSwgW1snMCcsICcwJywgJzInXSwgWycwJywgJzAnLCAnMiddLCBbJzAnLCAnMCcsICcwJ11dLCBbWycwJywgJzAnLCAnMCddLCBbJzAnLCAnMCcsICcwJ10sIFsnMCcsICcyJywgJzInXV0sIFtbJzAnLCAnMCcsICcwJ10sIFsnMicsICcwJywgJzAnXSwgWycyJywgJzAnLCAnMCddXV0sIFtbWycyJywgJzAnLCAnMiddLCBbJzAnLCAnMCcsICcwJ10sIFsnMCcsICcwJywgJzAnXV0sIFtbJzAnLCAnMCcsICcyJ10sIFsnMCcsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMiddXSwgW1snMCcsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMCddLCBbJzInLCAnMCcsICcyJ11dLCBbWycyJywgJzAnLCAnMCddLCBbJzAnLCAnMCcsICcwJ10sIFsnMicsICcwJywgJzAnXV1dLCBbW1snMicsICcwJywgJzAnXSwgWycwJywgJzInLCAnMCddLCBbJzAnLCAnMCcsICcwJ11dLCBbWycwJywgJzAnLCAnMiddLCBbJzAnLCAnMicsICcwJ10sIFsnMCcsICcwJywgJzAnXV0sIFtbJzAnLCAnMCcsICcwJ10sIFsnMCcsICcyJywgJzAnXSwgWycwJywgJzAnLCAnMiddXSwgW1snMCcsICcwJywgJzAnXSwgWycwJywgJzInLCAnMCddLCBbJzInLCAnMCcsICcwJ11dXSwgW1tbJzAnLCAnMycsICcwJ10sIFsnMycsICczJywgJzMnXSwgWycwJywgJzAnLCAnMCddXSwgW1snMCcsICczJywgJzAnXSwgWycwJywgJzMnLCAnMyddLCBbJzAnLCAnMycsICcwJ11dLCBbWycwJywgJzAnLCAnMCddLCBbJzMnLCAnMycsICczJ10sIFsnMCcsICczJywgJzAnXV0sIFtbJzAnLCAnMycsICcwJ10sIFsnMycsICczJywgJzAnXSwgWycwJywgJzMnLCAnMCddXV0sIFtbWyczJywgJzMnLCAnMCddLCBbJzMnLCAnMCcsICcwJ10sIFsnMCcsICcwJywgJzAnXV0sIFtbJzAnLCAnMycsICczJ10sIFsnMCcsICcwJywgJzMnXSwgWycwJywgJzAnLCAnMCddXSwgW1snMCcsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMyddLCBbJzAnLCAnMycsICczJ11dLCBbWycwJywgJzAnLCAnMCddLCBbJzMnLCAnMCcsICcwJ10sIFsnMycsICczJywgJzAnXV1dLCBbW1snMCcsICc1JywgJzAnXSwgWycwJywgJzUnLCAnMCddLCBbJzUnLCAnNScsICc1J11dLCBbWyc1JywgJzAnLCAnMCddLCBbJzUnLCAnNScsICc1J10sIFsnNScsICcwJywgJzAnXV0sIFtbJzUnLCAnNScsICc1J10sIFsnMCcsICc1JywgJzAnXSwgWycwJywgJzUnLCAnMCddXSwgW1snMCcsICcwJywgJzUnXSwgWyc1JywgJzUnLCAnNSddLCBbJzAnLCAnMCcsICc1J11dXSwgW1tbJzYnLCAnNicsICcwJ10sIFsnNicsICcwJywgJzAnXSwgWyc2JywgJzYnLCAnMCddXSwgW1snNicsICc2JywgJzYnXSwgWyc2JywgJzAnLCAnNiddLCBbJzAnLCAnMCcsICcwJ11dLCBbWycwJywgJzYnLCAnNiddLCBbJzAnLCAnMCcsICc2J10sIFsnMCcsICc2JywgJzYnXV0sIFtbJzAnLCAnMCcsICcwJ10sIFsnNicsICcwJywgJzYnXSwgWyc2JywgJzYnLCAnNiddXV0sIFtbWycwJywgJzcnLCAnNyddLCBbJzcnLCAnNycsICcwJ10sIFsnNycsICcwJywgJzAnXV0sIFtbJzcnLCAnNycsICcwJ10sIFsnMCcsICc3JywgJzcnXSwgWycwJywgJzAnLCAnNyddXSwgW1snMCcsICcwJywgJzcnXSwgWycwJywgJzcnLCAnNyddLCBbJzcnLCAnNycsICcwJ11dLCBbWyc3JywgJzAnLCAnMCddLCBbJzcnLCAnNycsICcwJ10sIFsnMCcsICc3JywgJzcnXV1dXQojIOODluODreODg+OCr+OBruiyu+eUqOOBqOWgsemFrApXYXJlaG91c2VfU2xvdF9CbG9rdT1bMSw0LDQsNCwxMiwxMiwyNSwzMCwzNV0KCgoKIAojIOOCteOCpOOCs+ODreOBruWApApkZWYgU2FtcGxlX0RlbW9fTmV3X0Jsb2t1X1JhbmRvbV9OdW1iZXIoKToKCWdsb2JhbCBEaWNlCglyZXR1cm4gcmFuZG9tLmNob2ljZShEaWNlKQoKCgojIHg95bqn5qiZeCB5PeW6p+aomXkgej3ln4vjgoHovrzjgoDphY3liJcgIFdhcmVob3VzZV9TbG90W11bXSAseHl6PTAsMSwyLDPjg6bjg7zjgrbjg7zorZjliKUKZGVmIFNhbXBsZV9EZW1vMDEoeCx5LHoseHl6KToKCQoJIyDjg53jgqTjg7Pjg4jjgYvjgonjg5bjg63jg4Pjgq/osrvnlKjjgIDos7zlhaXlh6bnkIYKCWZvciBrLHYgaW4gZW51bWVyYXRlKFdhcmVob3VzZV9TbG90KToKCQlmb3IgaSBpbiB2OgoJCQlpZiBpPT16OgoJCQkJaWYgVVNFW3h5el0tV2FyZWhvdXNlX1Nsb3RfQmxva3Vba10+PTA6CgkJCQkJVVNFW3h5el0tPVdhcmVob3VzZV9TbG90X0Jsb2t1W2tdCgkJCQllbHNlOgoJCQkJCXJldHVybiAwCgoJCgkKCSMg44Om44O844K244O86K2Y5Yil55So44CASUTjga7ku5jkuI4KCUxvY2FsX0Jsb2NrPXoKCUxvY2FsX0Jsb2NrMj1bXQoJTG9jYWxfQmxvY2szPVtdCglmb3IgaSBpbiBMb2NhbF9CbG9jazoKCQlmb3IgaiBpbiBpOgoJCQlpZiAnMCc9PWo6CgkJCQlMb2NhbF9CbG9jazIuYXBwZW5kKGopCgkJCWVsc2U6CgkJCQlpZiAgIHh5ej09MDoKCQkJCQlqPSdBJytqCgkJCQkJTG9jYWxfQmxvY2syLmFwcGVuZChqKQoJCQkJZWxpZiB4eXo9PTE6CgkJCQkJaj0nQicragoJCQkJCUxvY2FsX0Jsb2NrMi5hcHBlbmQoaikKCQkJCWVsaWYgeHl6PT0yOgoJCQkJCWo9J0MnK2oKCQkJCQlMb2NhbF9CbG9jazIuYXBwZW5kKGopCgkJCQllbGlmIHh5ej09MzoKCQkJCQlqPSdEJytqCgkJCQkJTG9jYWxfQmxvY2syLmFwcGVuZChqKQoJTG9jYWxfQmxvY2syPWxpc3QoemlwKCpbaXRlcihMb2NhbF9CbG9jazIpXSozKSkKCWZvciBpIGluIExvY2FsX0Jsb2NrMjpMb2NhbF9CbG9jazMuYXBwZW5kKGxpc3QoaSkpCgkjcHByaW50KExvY2FsX0Jsb2NrMykKCQoKCQoJCgkjIE1BUOOBuOOBrumFjee9rgoJZm9yIGlfciwgaV9sIGluIGVudW1lcmF0ZShyYW5nZSh4LCBtaW4oKHgrMywgOSkpKSk6CgkJZm9yIGpfciwgal9sIGluIGVudW1lcmF0ZShyYW5nZSh5LCBtaW4oKHkrMywgOSkpKSk6CgkJCWlmIGxbal9sXVtpX2xdPT0nMCc6CgkJCQlsW2pfbF1baV9sXT1Mb2NhbF9CbG9jazNbal9yXVtpX3JdCgkJCWVsc2U6CgkJCQkjIOODpuODvOOCtuODvOWIpeOAgOWIneWbnuOBruOBv+W6p+aomQoJCQkJaWYgICBsW2pfbF1baV9sXT09J0EnOgoJCQkJCWxbM11bNF0jQQoJCQkJZWxpZiBsW2pfbF1baV9sXT09J0InOgoJCQkJCWxbNF1bM10jQgoJCQkJZWxpZiBsW2pfbF1baV9sXT09J0MnOgoJCQkJCWxbNV1bNF0jQwoJCQkJZWxpZiBsW2pfbF1baV9sXT09J0QnOgoJCQkJCWxbNF1bNV0jRAoJCQkJIyBwYXNzCgkJCQllbHNlOgoJCQkJCXBhc3MKCQkJCQoJCQkJCglyZXR1cm4gbAoKCgoKIyDlkIRNQVDopoHntKDjga7lkIjoqIgKZGVmIFNhbXBsZV9EZW1vX05ld19CbG9rdV9Jbml0aWFsaXphdGlvbih4eXopOgoJYz1bXQoJZm9yIGkgaW4gcmFuZ2UobGVuKHh5eikpOgoJCWMuYXBwZW5kKGNvbGxlY3Rpb25zLkNvdW50ZXIoeHl6W2ldKSkKCWZvciBqIGluIHJhbmdlKGxlbihjKS0xKToKCQljWzBdKz1jW2orMV0KCXJldHVybiBjWzBdCgoKCgoKIyDjg5bjg63jg4Pjgq/jga7kuK3lpK7luqfmqJnjgYvjgonpmqPmjqXjg57jgrnjga7lj5blvpcKSU5ERVgwMT1bXQpJTkRFWDAyPVtdCiMg44OW44Ot44OD44Kv44Gu572u44GR44KL5Lit5aSu5bqn5qiZ44KS5Y+W5b6XCmRlZiBTYW1wbGVfRGVtbzAwX2luZGV4MDEoeHl6KToKCWZvciBrLHYgaW4gZW51bWVyYXRlKGwpOgoJCWlmIHh5eiBpbiB2OklOREVYMDEuYXBwZW5kKFtrLHYuaW5kZXgoeHl6KV0pCglTYW1wbGVfRGVtbzAwX2luZGV4MDIoKQojIOODluODreODg+OCr+OBrue9ruOBkeOCi+WRqOWbsuW6p+aomeOCkuWPluW+lwpkZWYgU2FtcGxlX0RlbW8wMF9pbmRleDAyKCk6CglnbG9iYWwgSU5ERVgwMQoJSU5ERVgwMi5hcHBlbmQoW1tJTkRFWDAxWzBdWzBdLTEsSU5ERVgwMVswXVsxXS0xXSxbSU5ERVgwMVswXVswXS0xLElOREVYMDFbMF1bMV1dLFtJTkRFWDAxWzBdWzBdLTEsSU5ERVgwMVswXVsxXSsxXSxbSU5ERVgwMVswXVswXSxJTkRFWDAxWzBdWzFdLTFdLElOREVYMDFbMF0sW0lOREVYMDFbMF1bMF0sSU5ERVgwMVswXVsxXSsxXSxbSU5ERVgwMVswXVswLTFdLElOREVYMDFbMF1bMV0tMV0sW0lOREVYMDFbMF1bMF0rMSxJTkRFWDAxWzBdWzFdXSxbSU5ERVgwMVswXVswXSsxLElOREVYMDFbMF1bMV0rMV1dKQoKCgoKIyBNQVDjga7lho3nt6jpm4bjgIDoqIjnrpfnlKgKZGVmIFNhbXBsZV9EZW1vMDIoeCk6CglnbG9iYWwgbAoJUmVfRWRpdD1bXQoJZm9yIGkgaW4geDoKCQlmb3IgaiBpbiBpOgoJCQlpZiBqPT0nMCc6UmVfRWRpdC5hcHBlbmQoaikKCQkJZWxpZiBsZW4oaik9PTI6UmVfRWRpdC5hcHBlbmQoW2pbMF0saW50KGpbMV0pXSkKCQkJZWxpZiBsZW4oaik9PTM6UmVfRWRpdC5hcHBlbmQoW2pbMF0saW50KGpbMV0pK2ludChqWzJdKV0pCglSZV9FZGl0PWxpc3QoemlwKCpbaXRlcihSZV9FZGl0KV0qOSkpCglyZXR1cm4gUmVfRWRpdAoKCgoKCiMg5Y+W5b6X44GZ44KL44Od44Kk44Oz44OI44Gu5Y+W5b6XIE5HCmRlZiBTYW1wbGVfRGVtbzAzKHh5eik6CglnbG9iYWwgTmFzYQoJIyDkuIDmmYLkv53nlZnlgInluqsKCU5hc2E9WzAsMCwwLDBdCgkKCSMgTUFQ44Gr6YWN572u44GV44KM44Gm44KL44OW44Ot44OD44Kv5Yil44CA44Od44Kk44Oz44OI5Y+W5b6XCglIYW5nb3V0PVNhbXBsZV9EZW1vX05ld19CbG9rdV9Jbml0aWFsaXphdGlvbih4eXopCglmb3IgaSBpbiBIYW5nb3V0OgoJCWlmIGk9PScwJyBvciBpPT0nQScgb3IgaT09J0InIG9yIGk9PSdDJyBvciBpPT0nRCc6CgkJCXBhc3MKCQllbHNlOgoJCQlpZiAnQScgaW4gaToKCQkJCWlmIGxlbihpKT09MjoKCQkJCQlOYXNhWzBdKz1pbnQoaVsxXSkqSGFuZ291dFtpXQoJCQkJZWxpZiBsZW4oaSk9PTM6CgkJCQkJTmFzYVswXSs9aW50KHN0cihpWzFdKStzdHIoaVsyXSkpKkhhbmdvdXRbaV0KCQkJZWxpZiAnQicgaW4gaToKCQkJCWlmIGxlbihpKT09MjoKCQkJCQlOYXNhWzFdKz1pbnQoaVsxXSkqSGFuZ291dFtpXQoJCQkJZWxpZiBsZW4oaSk9PTM6CgkJCQkJTmFzYVsxXSs9aW50KHN0cihpWzFdKStzdHIoaVsyXSkpKkhhbmdvdXRbaV0KCQkJZWxpZiAnQycgaW4gaToKCQkJCWlmIGxlbihpKT09MjoKCQkJCQlOYXNhWzJdKz1pbnQoaVsxXSkqSGFuZ291dFtpXQoJCQkJZWxpZiBsZW4oaSk9PTM6CgkJCQkJTmFzYVsyXSs9aW50KHN0cihpWzFdKStzdHIoaVsyXSkpKkhhbmdvdXRbaV0KCQkJZWxpZiAnRCcgaW4gaToKCQkJCWlmIGxlbihpKT09MjoKCQkJCQlOYXNhWzNdKz1pbnQoaVsxXSkqSGFuZ291dFtpXQoJCQkJZWxpZiBsZW4oaSk9PTM6CgkJCQkJTmFzYVszXSs9aW50KHN0cihpWzFdKStzdHIoaVsyXSkpKkhhbmdvdXRbaV0KCQkJZWxzZToKCQkJCXByaW50KGksSGFuZ291dFtpXSkKCgoKCgoKcHJpbnQoKQojIOODpuODvOOCtuODvOODneOCpOODs+ODiOOAgOeahgpwcmludCgn44Om44O844K244O844Od44Kk44Oz44OIIFsnLCdBJyxVU0VbMF0sJycsJ0InLFVTRVsxXSwnJywnQycsVVNFWzJdLCcnLCdEJyxVU0VbM10sJ10nKQoKIyDjg6bjg7zjgrbjg7xB44GM572u44GR44KL56+E5Zuy44GuaW5kZXjjgpLlj5blvpcKU2FtcGxlX0RlbW8wMF9pbmRleDAxKCdBJykKIyBpbmRleOOBruihqOekugpwcmludCgnQeODpuODvOOCtuODvOOBjOe9ruOBkeOCi+evhOWbsicsSU5ERVgwMikscHJpbnQoKQoKIyDjg5bjg63jg4Pjgq/jgpLnva7jgY/jgIDjg6bjg7zjgrbjg7xJRAp0cnk6cHByaW50KFNhbXBsZV9EZW1vMDEoMCwwLFdhcmVob3VzZV9TbG90WzJdWzBdLDEpKQpleGNlcHQgSW5kZXhFcnJvcjpwYXNzCgojIOODneOCpOODs+ODiOWPluW+lyDku64KU2FtcGxlX0RlbW8wMyhsKQojIOihqOekugpwcmludCgnQUJDRCDku67jg53jgqTjg7Pjg4gnLE5hc2EpCgpwcmludCgn44K144Kk44Kz44Ot44Gu5YCkJyxTYW1wbGVfRGVtb19OZXdfQmxva3VfUmFuZG9tX051bWJlcigpKQpwcmludCgpCgoKCiMg44Om44O844K244O844Od44Kk44Oz44OI44CA55qGCnByaW50KCfjg6bjg7zjgrbjg7zjg53jgqTjg7Pjg4ggWycsJ0EnLFVTRVswXSwnJywnQicsVVNFWzFdLCcnLCdDJyxVU0VbMl0sJycsJ0QnLFVTRVszXSwnXScpCgoKCgoKCiIiIgp3aGlsZSAyNTA+PVVTRVswXSBvciAyNTA+PVVTRVsxXSBvciAyNTA+PVVTRVsyXSBvciAyNTA+PVVTRVszXToKCSMg44K/44O844Oz5Yem55CGCgkjIEHjg6bjg7zjgrbjg7wKCWlmIFRpbWVzJTQ9PTE6CgkJcGFzcwoKCSMgQuODpuODvOOCtuODvAoJZWxpZiBUaW1lcyU0PT0yOgoJCXBhc3MKCSMgQ+ODpuODvOOCtuODvAoJZWxpZiBUaW1lcyU0PT0zOgoJCXBhc3MKCSMgROODpuODvOOCtuODvAoJZWxpZiBUaW1lcyU0PT0wOgoJCXBhc3MKIiIiCg==