#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 街コロ+ブロックス簡易2Dゲーム
import random
import numpy as np
import collections
from pprint import pprint
# サイコロの準備
Dice=[i for i in range(1,12)]
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=[50,50,50,50]
# 回転済み ブロック
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)
pprint(Hangout)
# 1つずつチェック
def Only_One(xyz):
global Nasa
# 一時保留倉庫
Nasa=[0,0,0,0]
# MAPに配置されてるブロック別 ポイント取得
Hangout=Sample_Demo_New_Bloku_Initialization(xyz)
#pprint(Hangout)
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:
pass
#print(i,Hangout[i])
# for k,v in enumerate(Nasa):
# USE[k]+=int(v)
import numpy as np
# 誰のターン A1,B2,C3,D0
Whose_thing=[1,2,3,0]
# 右に1要素分ずらす
def Rotation(Rotating_Objects):
global Whose_thing
xx1=np.array(Whose_thing)
Whose_thing=xx1.tolist()
# MAP上の点数計算
def Sample_Demo04():
# 小屋
if Times%4==Whose_thing[0] or Times%4==Whose_thing[1] or Times%4==Whose_thing[2] or Times%4==Whose_thing[3] and Sample_Demo_New_Bloku_Random_Number==1:
Only_One(l)
# 家
if Times%4==Whose_thing[0] and Sample_Demo_New_Bloku_Random_Number==2:
Only_One(l)
# 倉庫
if Times%4==Whose_thing[1] and Sample_Demo_New_Bloku_Random_Number==3:
Only_One(l)
# パン屋
if Times%4==Whose_thing[0]:pass
elif Times%4==Whose_thing[1] or Times%4==Whose_thing[2] or Times%4==Whose_thing[3] and Sample_Demo_New_Bloku_Random_Number==4:
Only_One(l)
# 豪邸
if Times%4==Whose_thing[0] and Sample_Demo_New_Bloku_Random_Number==5:
Only_One(l)
# 喫茶店
if Times%4==Whose_thing[0]:pass
elif Times%4==Whose_thing[1] or Times%4==Whose_thing[2] or Times%4==Whose_thing[3] and Sample_Demo_New_Bloku_Random_Number==6:
Only_One(l)
# 農園
if Times%4==Whose_thing[0] and Sample_Demo_New_Bloku_Random_Number==7:
Only_One(l)
# 工場
if Times%4==Whose_thing[0]:pass
elif Times%4==Whose_thing[1] or Times%4==Whose_thing[2] or Times%4==Whose_thing[3] and Sample_Demo_New_Bloku_Random_Number==8:
Only_One(l)
# 資源[農園工場]
if Times%4==Whose_thing[0] or Times%4==Whose_thing[1] or Times%4==Whose_thing[2] or Times%4==Whose_thing[3] and Sample_Demo_New_Bloku_Random_Number==9:
Only_One(l)
def MIKI():
print()
# ユーザーポイント 皆
print('ユーザーポイント [','A',USE[0],'','B',USE[1],'','C',USE[2],'','D',USE[3],']')
# ユーザーが置ける範囲のindexを取得
# ユーザー入力
Coffee=list(map(int,input().split()))
#print(Coffee)# 2 3 2 1
# ブロックの置ける場所がindexに含まれるか
for i in INDEX02:
try:
try:i.index([Coffee[0], Coffee[1]])
except IndexError:pass
# ブロックを置く ユーザーID
try:pprint(Sample_Demo01(Coffee[0],Coffee[1],Warehouse_Slot[Coffee[2]][Coffee[3]],Times%4==1))
except IndexError:pass
except (SyntaxError,ValueError):pass
# 点数計算
Sample_Demo04()
# 点数計算を横にズラす
Rotation(Whose_thing)
# ポイント取得 仮
Sample_Demo03(l)
# 表示
print('ABCD 仮ポイント',Nasa)
print('サイコロの値',Sample_Demo_New_Bloku_Random_Number())
print()
while 250>=USE[0] or 250>=USE[1] or 250>=USE[2] or 250>=USE[3]:
if USE[0]>=250:
print('END',USE[0])
elif USE[1]>=250:
print('END',USE[1])
elif USE[2]>=250:
print('END',USE[2])
elif USE[3]>=250:
print('END',USE[3])
# ターン処理
Times+=1
# Aユーザー
if Times%4==1:
# ユーザーが置ける範囲のindexを取得
Sample_Demo00_index01('A')
MIKI()
# Bユーザー
elif Times%4==2:
Sample_Demo00_index01('B')
MIKI()
# Cユーザー
elif Times%4==3:
Sample_Demo00_index01('C')
MIKI()
# Dユーザー
elif Times%4==0:
Sample_Demo00_index01('D')
MIKI()
IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCiMgLSotIGNvZGluZzogdXRmLTggLSotCgoKIyDooZfjgrPjg63vvIvjg5bjg63jg4Pjgq/jgrnnsKHmmJPvvJJE44Ky44O844OgCgoKaW1wb3J0IHJhbmRvbQppbXBvcnQgbnVtcHkgYXMgbnAKaW1wb3J0IGNvbGxlY3Rpb25zCmZyb20gcHByaW50IGltcG9ydCBwcHJpbnQKCiMg44K144Kk44Kz44Ot44Gu5rqW5YKZCkRpY2U9W2kgZm9yIGkgaW4gcmFuZ2UoMSwxMildCgpsPVsKIFsnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICdBJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnQicsICcwJywgJ0QnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICdDJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnXSwKIFsnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnLCAnMCcsICcwJywgJzAnXV0KCiMg44K/44O844OzIOWbnuaVsOitmOWIpeeUqApUaW1lcz0wCgojIOacgOe1guebruaomeOAgOW/heimgeOBquOBhOOBi+OCggpGaW5hbF9Hb2FsPTI1MAojIOiqsOOBjOebrueahOOCkumBlOaIkOOBl+OBn+OBi+WIpOWumueUqOOAgOmFjeWIlwpGaW5hbF9Hb2FsX0ZsYWc9WzAsMCwwLDBdCgoKIyDjg6bjg7zjgrbjg7zmg4XloLHjgIDjg53jgqTjg7Pjg4gKVVNFPVs1MCw1MCw1MCw1MF0KCiMg5Zue6Lui5riI44G/44CA44OW44Ot44OD44KvCldhcmVob3VzZV9TbG90PVtbW1snMScsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMCddLCBbJzAnLCAnMCcsICcwJ11dLCBbWycwJywgJzAnLCAnMSddLCBbJzAnLCAnMCcsICcwJ10sIFsnMCcsICcwJywgJzAnXV0sIFtbJzAnLCAnMCcsICcwJ10sIFsnMCcsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMSddXSwgW1snMCcsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMCddLCBbJzEnLCAnMCcsICcwJ11dXSwgW1tbJzInLCAnMicsICcwJ10sIFsnMCcsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMCddXSwgW1snMCcsICcwJywgJzInXSwgWycwJywgJzAnLCAnMiddLCBbJzAnLCAnMCcsICcwJ11dLCBbWycwJywgJzAnLCAnMCddLCBbJzAnLCAnMCcsICcwJ10sIFsnMCcsICcyJywgJzInXV0sIFtbJzAnLCAnMCcsICcwJ10sIFsnMicsICcwJywgJzAnXSwgWycyJywgJzAnLCAnMCddXV0sIFtbWycyJywgJzAnLCAnMiddLCBbJzAnLCAnMCcsICcwJ10sIFsnMCcsICcwJywgJzAnXV0sIFtbJzAnLCAnMCcsICcyJ10sIFsnMCcsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMiddXSwgW1snMCcsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMCddLCBbJzInLCAnMCcsICcyJ11dLCBbWycyJywgJzAnLCAnMCddLCBbJzAnLCAnMCcsICcwJ10sIFsnMicsICcwJywgJzAnXV1dLCBbW1snMicsICcwJywgJzAnXSwgWycwJywgJzInLCAnMCddLCBbJzAnLCAnMCcsICcwJ11dLCBbWycwJywgJzAnLCAnMiddLCBbJzAnLCAnMicsICcwJ10sIFsnMCcsICcwJywgJzAnXV0sIFtbJzAnLCAnMCcsICcwJ10sIFsnMCcsICcyJywgJzAnXSwgWycwJywgJzAnLCAnMiddXSwgW1snMCcsICcwJywgJzAnXSwgWycwJywgJzInLCAnMCddLCBbJzInLCAnMCcsICcwJ11dXSwgW1tbJzAnLCAnMycsICcwJ10sIFsnMycsICczJywgJzMnXSwgWycwJywgJzAnLCAnMCddXSwgW1snMCcsICczJywgJzAnXSwgWycwJywgJzMnLCAnMyddLCBbJzAnLCAnMycsICcwJ11dLCBbWycwJywgJzAnLCAnMCddLCBbJzMnLCAnMycsICczJ10sIFsnMCcsICczJywgJzAnXV0sIFtbJzAnLCAnMycsICcwJ10sIFsnMycsICczJywgJzAnXSwgWycwJywgJzMnLCAnMCddXV0sIFtbWyczJywgJzMnLCAnMCddLCBbJzMnLCAnMCcsICcwJ10sIFsnMCcsICcwJywgJzAnXV0sIFtbJzAnLCAnMycsICczJ10sIFsnMCcsICcwJywgJzMnXSwgWycwJywgJzAnLCAnMCddXSwgW1snMCcsICcwJywgJzAnXSwgWycwJywgJzAnLCAnMyddLCBbJzAnLCAnMycsICczJ11dLCBbWycwJywgJzAnLCAnMCddLCBbJzMnLCAnMCcsICcwJ10sIFsnMycsICczJywgJzAnXV1dLCBbW1snMCcsICc1JywgJzAnXSwgWycwJywgJzUnLCAnMCddLCBbJzUnLCAnNScsICc1J11dLCBbWyc1JywgJzAnLCAnMCddLCBbJzUnLCAnNScsICc1J10sIFsnNScsICcwJywgJzAnXV0sIFtbJzUnLCAnNScsICc1J10sIFsnMCcsICc1JywgJzAnXSwgWycwJywgJzUnLCAnMCddXSwgW1snMCcsICcwJywgJzUnXSwgWyc1JywgJzUnLCAnNSddLCBbJzAnLCAnMCcsICc1J11dXSwgW1tbJzYnLCAnNicsICcwJ10sIFsnNicsICcwJywgJzAnXSwgWyc2JywgJzYnLCAnMCddXSwgW1snNicsICc2JywgJzYnXSwgWyc2JywgJzAnLCAnNiddLCBbJzAnLCAnMCcsICcwJ11dLCBbWycwJywgJzYnLCAnNiddLCBbJzAnLCAnMCcsICc2J10sIFsnMCcsICc2JywgJzYnXV0sIFtbJzAnLCAnMCcsICcwJ10sIFsnNicsICcwJywgJzYnXSwgWyc2JywgJzYnLCAnNiddXV0sIFtbWycwJywgJzcnLCAnNyddLCBbJzcnLCAnNycsICcwJ10sIFsnNycsICcwJywgJzAnXV0sIFtbJzcnLCAnNycsICcwJ10sIFsnMCcsICc3JywgJzcnXSwgWycwJywgJzAnLCAnNyddXSwgW1snMCcsICcwJywgJzcnXSwgWycwJywgJzcnLCAnNyddLCBbJzcnLCAnNycsICcwJ11dLCBbWyc3JywgJzAnLCAnMCddLCBbJzcnLCAnNycsICcwJ10sIFsnMCcsICc3JywgJzcnXV1dXQojIOODluODreODg+OCr+OBruiyu+eUqOOBqOWgsemFrApXYXJlaG91c2VfU2xvdF9CbG9rdT1bMSw0LDQsNCwxMiwxMiwyNSwzMCwzNV0KCgoKCiMg44K144Kk44Kz44Ot44Gu5YCkCmRlZiBTYW1wbGVfRGVtb19OZXdfQmxva3VfUmFuZG9tX051bWJlcigpOgoJZ2xvYmFsIERpY2UKCXJldHVybiByYW5kb20uY2hvaWNlKERpY2UpCgoKCiMgeD3luqfmqJl4IHk95bqn5qiZeSB6PeWfi+OCgei+vOOCgOmFjeWIlyAgV2FyZWhvdXNlX1Nsb3RbXVtdICx4eXo9MCwxLDIsM+ODpuODvOOCtuODvOitmOWIpQpkZWYgU2FtcGxlX0RlbW8wMSh4LHkseix4eXopOgoJCgkjIOODneOCpOODs+ODiOOBi+OCieODluODreODg+OCr+iyu+eUqOOAgOizvOWFpeWHpueQhgoJZm9yIGssdiBpbiBlbnVtZXJhdGUoV2FyZWhvdXNlX1Nsb3QpOgoJCWZvciBpIGluIHY6CgkJCWlmIGk9PXo6CgkJCQlpZiBVU0VbeHl6XS1XYXJlaG91c2VfU2xvdF9CbG9rdVtrXT49MDoKCQkJCQlVU0VbeHl6XS09V2FyZWhvdXNlX1Nsb3RfQmxva3Vba10KCQkJCWVsc2U6CgkJCQkJcmV0dXJuIDAKCgkKCQoJIyDjg6bjg7zjgrbjg7zorZjliKXnlKjjgIBJROOBruS7mOS4jgoJTG9jYWxfQmxvY2s9egoJTG9jYWxfQmxvY2syPVtdCglMb2NhbF9CbG9jazM9W10KCWZvciBpIGluIExvY2FsX0Jsb2NrOgoJCWZvciBqIGluIGk6CgkJCWlmICcwJz09ajoKCQkJCUxvY2FsX0Jsb2NrMi5hcHBlbmQoaikKCQkJZWxzZToKCQkJCWlmICAgeHl6PT0wOgoJCQkJCWo9J0EnK2oKCQkJCQlMb2NhbF9CbG9jazIuYXBwZW5kKGopCgkJCQllbGlmIHh5ej09MToKCQkJCQlqPSdCJytqCgkJCQkJTG9jYWxfQmxvY2syLmFwcGVuZChqKQoJCQkJZWxpZiB4eXo9PTI6CgkJCQkJaj0nQycragoJCQkJCUxvY2FsX0Jsb2NrMi5hcHBlbmQoaikKCQkJCWVsaWYgeHl6PT0zOgoJCQkJCWo9J0QnK2oKCQkJCQlMb2NhbF9CbG9jazIuYXBwZW5kKGopCglMb2NhbF9CbG9jazI9bGlzdCh6aXAoKltpdGVyKExvY2FsX0Jsb2NrMildKjMpKQoJZm9yIGkgaW4gTG9jYWxfQmxvY2syOkxvY2FsX0Jsb2NrMy5hcHBlbmQobGlzdChpKSkKCSNwcHJpbnQoTG9jYWxfQmxvY2szKQoJCgoJCgkKCSMgTUFQ44G444Gu6YWN572uCglmb3IgaV9yLCBpX2wgaW4gZW51bWVyYXRlKHJhbmdlKHgsIG1pbigoeCszLCA5KSkpKToKCQlmb3Igal9yLCBqX2wgaW4gZW51bWVyYXRlKHJhbmdlKHksIG1pbigoeSszLCA5KSkpKToKCQkJaWYgbFtqX2xdW2lfbF09PScwJzoKCQkJCWxbal9sXVtpX2xdPUxvY2FsX0Jsb2NrM1tqX3JdW2lfcl0KCQkJZWxzZToKCQkJCSMg44Om44O844K244O85Yil44CA5Yid5Zue44Gu44G/5bqn5qiZCgkJCQlpZiAgIGxbal9sXVtpX2xdPT0nQSc6CgkJCQkJbFszXVs0XSNBCgkJCQllbGlmIGxbal9sXVtpX2xdPT0nQic6CgkJCQkJbFs0XVszXSNCCgkJCQllbGlmIGxbal9sXVtpX2xdPT0nQyc6CgkJCQkJbFs1XVs0XSNDCgkJCQllbGlmIGxbal9sXVtpX2xdPT0nRCc6CgkJCQkJbFs0XVs1XSNECgkJCQkjIHBhc3MKCQkJCWVsc2U6CgkJCQkJcGFzcwoJCQkJCgkJCQkKCXJldHVybiBsCgoKCgoKIyDlkIRNQVDopoHntKDjga7lkIjoqIgKZGVmIFNhbXBsZV9EZW1vX05ld19CbG9rdV9Jbml0aWFsaXphdGlvbih4eXopOgoJYz1bXQoJZm9yIGkgaW4gcmFuZ2UobGVuKHh5eikpOgoJCWMuYXBwZW5kKGNvbGxlY3Rpb25zLkNvdW50ZXIoeHl6W2ldKSkKCWZvciBqIGluIHJhbmdlKGxlbihjKS0xKToKCQljWzBdKz1jW2orMV0KCXJldHVybiBjWzBdCgoKCgojIOODluODreODg+OCr+OBruS4reWkruW6p+aomeOBi+OCiemao+aOpeODnuOCueOBruWPluW+lwpJTkRFWDAxPVtdCklOREVYMDI9W10KIyDjg5bjg63jg4Pjgq/jga7nva7jgZHjgovkuK3lpK7luqfmqJnjgpLlj5blvpcKZGVmIFNhbXBsZV9EZW1vMDBfaW5kZXgwMSh4eXopOgoJZm9yIGssdiBpbiBlbnVtZXJhdGUobCk6CgkJaWYgeHl6IGluIHY6SU5ERVgwMS5hcHBlbmQoW2ssdi5pbmRleCh4eXopXSkKCVNhbXBsZV9EZW1vMDBfaW5kZXgwMigpCiMg44OW44Ot44OD44Kv44Gu572u44GR44KL5ZGo5Zuy5bqn5qiZ44KS5Y+W5b6XCmRlZiBTYW1wbGVfRGVtbzAwX2luZGV4MDIoKToKCWdsb2JhbCBJTkRFWDAxCglJTkRFWDAyLmFwcGVuZChbW0lOREVYMDFbMF1bMF0tMSxJTkRFWDAxWzBdWzFdLTFdLFtJTkRFWDAxWzBdWzBdLTEsSU5ERVgwMVswXVsxXV0sW0lOREVYMDFbMF1bMF0tMSxJTkRFWDAxWzBdWzFdKzFdLFtJTkRFWDAxWzBdWzBdLElOREVYMDFbMF1bMV0tMV0sSU5ERVgwMVswXSxbSU5ERVgwMVswXVswXSxJTkRFWDAxWzBdWzFdKzFdLFtJTkRFWDAxWzBdWzAtMV0sSU5ERVgwMVswXVsxXS0xXSxbSU5ERVgwMVswXVswXSsxLElOREVYMDFbMF1bMV1dLFtJTkRFWDAxWzBdWzBdKzEsSU5ERVgwMVswXVsxXSsxXV0pCgoKCgojIE1BUOOBruWGjee3qOmbhuOAgOioiOeul+eUqApkZWYgU2FtcGxlX0RlbW8wMih4KToKCWdsb2JhbCBsCglSZV9FZGl0PVtdCglmb3IgaSBpbiB4OgoJCWZvciBqIGluIGk6CgkJCWlmIGo9PScwJzpSZV9FZGl0LmFwcGVuZChqKQoJCQllbGlmIGxlbihqKT09MjpSZV9FZGl0LmFwcGVuZChbalswXSxpbnQoalsxXSldKQoJCQllbGlmIGxlbihqKT09MzpSZV9FZGl0LmFwcGVuZChbalswXSxpbnQoalsxXSkraW50KGpbMl0pXSkKCVJlX0VkaXQ9bGlzdCh6aXAoKltpdGVyKFJlX0VkaXQpXSo5KSkKCXJldHVybiBSZV9FZGl0CgoKCiMg5Y+W5b6X44GZ44KL44Od44Kk44Oz44OI44Gu5Y+W5b6XIE5HCmRlZiBTYW1wbGVfRGVtbzAzKHh5eik6CglnbG9iYWwgTmFzYQoJIyDkuIDmmYLkv53nlZnlgInluqsKCU5hc2E9WzAsMCwwLDBdCgkKCSMgTUFQ44Gr6YWN572u44GV44KM44Gm44KL44OW44Ot44OD44Kv5Yil44CA44Od44Kk44Oz44OI5Y+W5b6XCglIYW5nb3V0PVNhbXBsZV9EZW1vX05ld19CbG9rdV9Jbml0aWFsaXphdGlvbih4eXopCglwcHJpbnQoSGFuZ291dCkKCgoKIyAx44Gk44Ga44Gk44OB44Kn44OD44KvCmRlZiBPbmx5X09uZSh4eXopOgoJZ2xvYmFsIE5hc2EKCSMg5LiA5pmC5L+d55WZ5YCJ5bqrCglOYXNhPVswLDAsMCwwXQoJCgkjIE1BUOOBq+mFjee9ruOBleOCjOOBpuOCi+ODluODreODg+OCr+WIpeOAgOODneOCpOODs+ODiOWPluW+lwoJSGFuZ291dD1TYW1wbGVfRGVtb19OZXdfQmxva3VfSW5pdGlhbGl6YXRpb24oeHl6KQoJI3BwcmludChIYW5nb3V0KQoJCglmb3IgaSBpbiBIYW5nb3V0OgoJCWlmIGk9PScwJyBvciBpPT0nQScgb3IgaT09J0InIG9yIGk9PSdDJyBvciBpPT0nRCc6CgkJCXBhc3MKCQllbHNlOgoJCQlpZiAnQScgaW4gaToKCQkJCWlmIGxlbihpKT09MjoKCQkJCQlOYXNhWzBdKz1pbnQoaVsxXSkqSGFuZ291dFtpXQoJCQkJZWxpZiBsZW4oaSk9PTM6CgkJCQkJTmFzYVswXSs9aW50KHN0cihpWzFdKStzdHIoaVsyXSkpKkhhbmdvdXRbaV0KCQkJZWxpZiAnQicgaW4gaToKCQkJCWlmIGxlbihpKT09MjoKCQkJCQlOYXNhWzFdKz1pbnQoaVsxXSkqSGFuZ291dFtpXQoJCQkJZWxpZiBsZW4oaSk9PTM6CgkJCQkJTmFzYVsxXSs9aW50KHN0cihpWzFdKStzdHIoaVsyXSkpKkhhbmdvdXRbaV0KCQkJZWxpZiAnQycgaW4gaToKCQkJCWlmIGxlbihpKT09MjoKCQkJCQlOYXNhWzJdKz1pbnQoaVsxXSkqSGFuZ291dFtpXQoJCQkJZWxpZiBsZW4oaSk9PTM6CgkJCQkJTmFzYVsyXSs9aW50KHN0cihpWzFdKStzdHIoaVsyXSkpKkhhbmdvdXRbaV0KCQkJZWxpZiAnRCcgaW4gaToKCQkJCWlmIGxlbihpKT09MjoKCQkJCQlOYXNhWzNdKz1pbnQoaVsxXSkqSGFuZ291dFtpXQoJCQkJZWxpZiBsZW4oaSk9PTM6CgkJCQkJTmFzYVszXSs9aW50KHN0cihpWzFdKStzdHIoaVsyXSkpKkhhbmdvdXRbaV0KCQkJZWxzZToKCQkJCXBhc3MKCQkJCSNwcmludChpLEhhbmdvdXRbaV0pCgkJCiMJCWZvciBrLHYgaW4gZW51bWVyYXRlKE5hc2EpOgojCQkJVVNFW2tdKz1pbnQodikKCgoKCgppbXBvcnQgbnVtcHkgYXMgbnAKIyDoqrDjga7jgr/jg7zjg7MgQTEsQjIsQzMsRDAKV2hvc2VfdGhpbmc9WzEsMiwzLDBdCgojIOWPs+OBqzHopoHntKDliIbjgZrjgonjgZkKZGVmIFJvdGF0aW9uKFJvdGF0aW5nX09iamVjdHMpOgoJZ2xvYmFsIFdob3NlX3RoaW5nCgl4eDE9bnAuYXJyYXkoV2hvc2VfdGhpbmcpCglXaG9zZV90aGluZz14eDEudG9saXN0KCkKCgoKIyBNQVDkuIrjga7ngrnmlbDoqIjnrpcKZGVmIFNhbXBsZV9EZW1vMDQoKToKCSMg5bCP5bGLCglpZiBUaW1lcyU0PT1XaG9zZV90aGluZ1swXSBvciBUaW1lcyU0PT1XaG9zZV90aGluZ1sxXSBvciBUaW1lcyU0PT1XaG9zZV90aGluZ1syXSBvciBUaW1lcyU0PT1XaG9zZV90aGluZ1szXSBhbmQgU2FtcGxlX0RlbW9fTmV3X0Jsb2t1X1JhbmRvbV9OdW1iZXI9PTE6CgkJT25seV9PbmUobCkKCgkjIOWutgoJaWYgVGltZXMlND09V2hvc2VfdGhpbmdbMF0gYW5kIFNhbXBsZV9EZW1vX05ld19CbG9rdV9SYW5kb21fTnVtYmVyPT0yOgoJCU9ubHlfT25lKGwpCgoJIyDlgInluqsKCWlmICBUaW1lcyU0PT1XaG9zZV90aGluZ1sxXSBhbmQgU2FtcGxlX0RlbW9fTmV3X0Jsb2t1X1JhbmRvbV9OdW1iZXI9PTM6CgkJT25seV9PbmUobCkKCQoJIyDjg5Hjg7PlsYsKCWlmIFRpbWVzJTQ9PVdob3NlX3RoaW5nWzBdOnBhc3MKCWVsaWYgVGltZXMlND09V2hvc2VfdGhpbmdbMV0gb3IgVGltZXMlND09V2hvc2VfdGhpbmdbMl0gb3IgVGltZXMlND09V2hvc2VfdGhpbmdbM10gYW5kIFNhbXBsZV9EZW1vX05ld19CbG9rdV9SYW5kb21fTnVtYmVyPT00OgoJCU9ubHlfT25lKGwpCgkKCSMg6LGq6YK4CglpZiBUaW1lcyU0PT1XaG9zZV90aGluZ1swXSBhbmQgU2FtcGxlX0RlbW9fTmV3X0Jsb2t1X1JhbmRvbV9OdW1iZXI9PTU6CgkJT25seV9PbmUobCkKCgkjIOWWq+iMtuW6lwoJaWYgVGltZXMlND09V2hvc2VfdGhpbmdbMF06cGFzcwoJZWxpZiBUaW1lcyU0PT1XaG9zZV90aGluZ1sxXSBvciBUaW1lcyU0PT1XaG9zZV90aGluZ1syXSBvciBUaW1lcyU0PT1XaG9zZV90aGluZ1szXSBhbmQgU2FtcGxlX0RlbW9fTmV3X0Jsb2t1X1JhbmRvbV9OdW1iZXI9PTY6CgkJT25seV9PbmUobCkKCQoJIyDovrLlnJIKCWlmIFRpbWVzJTQ9PVdob3NlX3RoaW5nWzBdIGFuZCBTYW1wbGVfRGVtb19OZXdfQmxva3VfUmFuZG9tX051bWJlcj09NzoKCQlPbmx5X09uZShsKQoKCSMg5bel5aC0CglpZiBUaW1lcyU0PT1XaG9zZV90aGluZ1swXTpwYXNzCgllbGlmIFRpbWVzJTQ9PVdob3NlX3RoaW5nWzFdIG9yIFRpbWVzJTQ9PVdob3NlX3RoaW5nWzJdIG9yIFRpbWVzJTQ9PVdob3NlX3RoaW5nWzNdIGFuZCBTYW1wbGVfRGVtb19OZXdfQmxva3VfUmFuZG9tX051bWJlcj09ODoKCQlPbmx5X09uZShsKQoJCQoJIyAg6LOH5rqQW+i+suWckuW3peWgtF0KCWlmIFRpbWVzJTQ9PVdob3NlX3RoaW5nWzBdIG9yIFRpbWVzJTQ9PVdob3NlX3RoaW5nWzFdIG9yIFRpbWVzJTQ9PVdob3NlX3RoaW5nWzJdIG9yIFRpbWVzJTQ9PVdob3NlX3RoaW5nWzNdIGFuZCBTYW1wbGVfRGVtb19OZXdfQmxva3VfUmFuZG9tX051bWJlcj09OToKCQlPbmx5X09uZShsKQoKCmRlZiBNSUtJKCk6CglwcmludCgpCgkjIOODpuODvOOCtuODvOODneOCpOODs+ODiOOAgOeahgoJcHJpbnQoJ+ODpuODvOOCtuODvOODneOCpOODs+ODiCBbJywnQScsVVNFWzBdLCcnLCdCJyxVU0VbMV0sJycsJ0MnLFVTRVsyXSwnJywnRCcsVVNFWzNdLCddJykKCQoJIyDjg6bjg7zjgrbjg7zjgYznva7jgZHjgovnr4Tlm7Ljga5pbmRleOOCkuWPluW+lwoKCSMg44Om44O844K244O85YWl5YqbCglDb2ZmZWU9bGlzdChtYXAoaW50LGlucHV0KCkuc3BsaXQoKSkpCgkjcHJpbnQoQ29mZmVlKSMgMiAzIDIgMQoJCgkjIOODluODreODg+OCr+OBrue9ruOBkeOCi+WgtOaJgOOBjGluZGV444Gr5ZCr44G+44KM44KL44GLCglmb3IgaSBpbiBJTkRFWDAyOgoJCXRyeToKCQkJdHJ5OmkuaW5kZXgoW0NvZmZlZVswXSwgQ29mZmVlWzFdXSkKCQkJZXhjZXB0IEluZGV4RXJyb3I6cGFzcwoJCQkjIOODluODreODg+OCr+OCkue9ruOBj+OAgOODpuODvOOCtuODvElECgkJCXRyeTpwcHJpbnQoU2FtcGxlX0RlbW8wMShDb2ZmZWVbMF0sQ29mZmVlWzFdLFdhcmVob3VzZV9TbG90W0NvZmZlZVsyXV1bQ29mZmVlWzNdXSxUaW1lcyU0PT0xKSkKCQkJZXhjZXB0IEluZGV4RXJyb3I6cGFzcwoJCWV4Y2VwdCAoU3ludGF4RXJyb3IsVmFsdWVFcnJvcik6cGFzcwoJIyDngrnmlbDoqIjnrpcKCVNhbXBsZV9EZW1vMDQoKQoJIyDngrnmlbDoqIjnrpfjgpLmqKrjgavjgrrjg6njgZkKCVJvdGF0aW9uKFdob3NlX3RoaW5nKQoJCgkjIOODneOCpOODs+ODiOWPluW+lyDku64KCVNhbXBsZV9EZW1vMDMobCkKCSMg6KGo56S6CglwcmludCgnQUJDRCDku67jg53jgqTjg7Pjg4gnLE5hc2EpCglwcmludCgn44K144Kk44Kz44Ot44Gu5YCkJyxTYW1wbGVfRGVtb19OZXdfQmxva3VfUmFuZG9tX051bWJlcigpKQoJcHJpbnQoKQoKCgp3aGlsZSAyNTA+PVVTRVswXSBvciAyNTA+PVVTRVsxXSBvciAyNTA+PVVTRVsyXSBvciAyNTA+PVVTRVszXToKCWlmIFVTRVswXT49MjUwOgoJCXByaW50KCdFTkQnLFVTRVswXSkKCWVsaWYgVVNFWzFdPj0yNTA6CgkJcHJpbnQoJ0VORCcsVVNFWzFdKQoJZWxpZiBVU0VbMl0+PTI1MDoKCQlwcmludCgnRU5EJyxVU0VbMl0pCgllbGlmIFVTRVszXT49MjUwOgoJCXByaW50KCdFTkQnLFVTRVszXSkKCSMg44K/44O844Oz5Yem55CGCglUaW1lcys9MQoJCgkjIEHjg6bjg7zjgrbjg7wKCWlmIFRpbWVzJTQ9PTE6CgkJIyDjg6bjg7zjgrbjg7zjgYznva7jgZHjgovnr4Tlm7Ljga5pbmRleOOCkuWPluW+lwoJCVNhbXBsZV9EZW1vMDBfaW5kZXgwMSgnQScpCgkJTUlLSSgpCgoJIyBC44Om44O844K244O8CgllbGlmIFRpbWVzJTQ9PTI6CgkJU2FtcGxlX0RlbW8wMF9pbmRleDAxKCdCJykKCQlNSUtJKCkKCSMgQ+ODpuODvOOCtuODvAoJZWxpZiBUaW1lcyU0PT0zOgoJCVNhbXBsZV9EZW1vMDBfaW5kZXgwMSgnQycpCgkJTUlLSSgpCgkjIETjg6bjg7zjgrbjg7wKCWVsaWYgVGltZXMlND09MDoKCQlTYW1wbGVfRGVtbzAwX2luZGV4MDEoJ0QnKQoJCU1JS0koKQoK