#!/usr/bin/env python3
### 余再帰
class unfoldr:
def __init__ ( self , f, seed) :
self .f = f
self .seed = seed
def __iter__ ( self ) :
return self
def __next__( self ) :
match self .f ( self .seed ) :
case a, b:
self .seed = b
return a
case None :
raise StopIteration
## 練習問題 1:
## “SPAM”という単語を 10 回表示するプログラムを作成しなさい。
def one( n = 10 ) :
print ( '' .join ( unfoldr( lambda x: None if x == 0 else ( 'SPAM\n ' , x - 1 ) , n) ) )
## 練習問題 2
## 九九、三の段( 3 ~ 27 の 3 の倍数)を表示するプログラムを作成しなさい。
def two( n = 3 ) :
print ( '' .join ( unfoldr( lambda x: None if x > 9 else ( f'{n * x}\n ' , x + 1 ) , 1 ) ) )
## 練習問題 3
## 2 の 1 乗から 8 乗までを計算し表示するプログラムを作成しなさい。
def three( base = 2 , power = 8 ) :
print ( '' .join ( unfoldr( lambda x: None if x > power else ( f'{base ** x}\n ' , x + 1 ) , 1 ) ) )
## 練習問題 4
## 7 の階乗を計算し、表示するプログラムを作成しなさい。
## ※ 階乗:1 から n までの積。1 × 2 × 3 × … ×( n - 1 )× n
def four( n = 7 ) :
from functools import reduce
print ( reduce ( lambda x, y: x * y, unfoldr( lambda x: None if x == 0 else ( x, x - 1 ) , n) ) )
## 練習問題 5
## 整数を 10 回入力し、平均値を求めるプログラムを作成しなさい。
## ※ 計算は整数で行い、小数点以下は切り捨ててよい。
def five( n = 10 ) :
from statistics import mean
from math import floor
return floor( mean( unfoldr( lambda x: None if x == 0 else ( int ( input ( ) ) , x - 1 ) , n) ) )
## 練習問題 6
## 整数、0 か 1 を 10 回入力する。これを対戦成績と考え、0 を負け、1 を勝ちとして、勝ちの総数、負けの総数を表示するプログラムを作成しなさい。
def six( n = 10 ) :
match_results = list ( unfoldr( lambda x: None if x == 0 else ( int ( input ( ) ) , x - 1 ) , n) )
print ( match_results.count ( 1 ) , match_results.count ( 0 ) )
## 練習問題 7
## 次のプログラムを作成しなさい。
## 巨人、阪神戦で毎回の得点を入力する。(1 回 ~ 9 回)
## 入力が終わったら、それぞれの得点とどちらが勝ったか、引き分けかを表示する。
## ※ 試合は巨人の先行とする。
## 1回表、巨人の得点は? 0
## 1回裏、阪神の得点は? 0
## 2回表、巨人の得点は? 0
## 2回裏、阪神の得点は? 1
## :
## :
## :
## 9回表、巨人の得点は? 0
## 9回裏、阪神の得点は? 1
##
## 巨人:5点, 阪神:6点
## 阪神の勝ち
def seven( n = 9 ) :
games = unfoldr( lambda x: None if x > n else
( ( int ( input ( f'{x}回表、巨人の得点は?' ) ) ,
int ( input ( f'{x}回裏、阪神の得点は?' ) ) ) ,
x + 1 ) , 1 )
giants, tigers = [ sum ( i) for i in zip ( *games) ]
print ( f'巨人: {giants}点, 阪神: {tigers}点\n \t {' 阪神' if tigers > giants else ' 巨人'}の勝ち' )
## 練習問題 8
## 自然数(正の整数)を 10 回入力し、最大値を求めるプログラムを作成しなさい。
def eight( n = 10 ) :
return max ( unfoldr( lambda x: None if x == 0 else ( int ( input ( ) ) , x - 1 ) , n) )
## 練習問題 9
## 整数を 10 回入力し、最大値と最小値を求めるプログラムを作成しなさい。
def nine( n = 10 ) :
lst = list ( unfoldr( lambda x: None if x == 0 else ( int ( input ( ) ) , x - 1 ) , n) )
return max ( lst) , min ( lst)
## 練習問題 10
## 個数を示す数値を入力し、その個数分だけ‘*’を表示するプログラムを作成しなさい。
def ten( n) :
print ( '' .join ( unfoldr( lambda x: None if x == 0 else ( '*' , x - 1 ) , n) ) )
## 練習問題 11
## 個数を示す数値を入力し、その個数分だけ 0 ~ 9 の数字を表示するプログラムを作成しなさい。数字は 0 , 1 , 2 , 3 , , の順に表示し、9 の次は 0 に戻るものとします。
def eleven( n) :
print ( '' .join ( unfoldr( lambda x: None if x >= n else ( str ( x % 10 ) , x + 1 ) , 0 ) ) )
## 練習問題 12
## 10000 より小さい 3 の累乗( 3, 9, 27, , , )をすべて表示するプログラムを作成しなさい。
def twelve( n = 10000 , d = 3 ) :
from math import floor, log
y = floor( log( n) / log( d) )
print ( '' .join ( unfoldr( lambda x: None if x > y else ( f'{d ** x}\n ' , x + 1 ) , 1 ) ) )
## 練習問題 13
## 数値を繰り返し入力し、合計が 100 を超えたら入力を止めて合計を表示するプログラムを作成しなさい。
def thirteen( n = 100 ) :
print ( sum ( unfoldr( lambda x: None if x > n else ( x, x + int ( input ( ) ) ) , int ( input ( ) ) ) ) )
## 練習問題 14
## ストライク・カウントを数えるプログラムを作成しなさい。
## 1球ごとにストライクかボールかを入力する。
## 3ストライクまたは4ボールになったら入力を止め、ストライクとボールのカウントを表示する。
## ※ ストライクの場合は 1、ボールの場合は 2 を入力する。
## ストライク=1 or ボール=2 ?
## 1
## ストライク=1 or ボール=2 ?
## 2
## ストライク=1 or ボール=2 ?
## 1
## ストライク=1 or ボール=2 ?
## 1
## 1ボール,3ストライク
def fourteen( ) :
strike_max, ball_max = 3 , 4
def foo( lst) :
lst[ int ( input ( 'ストライク=1 or ボール=2 ?\n ' ) ) - 1 ] += 1
return lst
print ( '{1}ボール, {0}ストライク' .format ( *list ( unfoldr( lambda x: None if x[ 0 ] == strike_max or x[ 1 ] == ball_max else ( x, foo( x) ) , foo( [ 0 , 0 ] ) ) ) [ -1 ] ) )
## 練習問題 15
## 前の問題に次の修正を加えなさい。
## 1球ごとにストライク、ボール、ファウルの何れかを入力する。(残念ながらヒットにはなりません)
## ファウルの場合、2ストライクまではストライクにカウントするが、3ストライクにはならない。
## 3ストライクまたは4ボールになったら入力を止め、ストライクとボールのカウントを表示する。
def fifteen( ) :
strike_max, ball_max = 3 , 4
def foo( lst) :
try :
lst[ int ( input ( 'ストライク=1 or ボール=2 ?\n ' ) ) - 1 ] += 1
except IndexError :
if lst[ 0 ] < 2 :
lst[ 0 ] += 1
finally :
return lst
print ( '{1}ボール, {0}ストライク' .format ( *list ( unfoldr( lambda x: None if x[ 0 ] == strike_max or x[ 1 ] == ball_max else ( x, foo( x) ) , foo( [ 0 , 0 ] ) ) ) [ -1 ] ) )
## 練習問題 16
## 入力された数が素数かどうかを判定するプログラムを作成しなさい。
## ※ 判定する数は 4 以上としてよい。
def sixteen( n) :
def foo( x) :
nonlocal n
if x > n:
return None
else :
while n % x != 0 :
x += 1
return ( n if x ** 2 > n else x, x + 1 )
return len ( list ( unfoldr( foo, 2 ) ) ) == 1
## 練習問題 17
## 2 以上の数値を入力し、素因数分解した結果を表示しなさい。
## 例:
## 20100
## 2 2 3 5 5 67
def seventeen( n) :
from math import sqrt, ceil
def foo( x) :
nonlocal n
if x > ceil( sqrt( n) ) :
return None
else :
while True :
if sixteen( x) and n % x == 0 :
n /= x
return ( f'{x} ' , x)
x += 1
return print ( '' .join ( unfoldr( foo, 2 ) ) )
## 練習問題 18
## 九九表(一の段~九の段)を表示するプログラムを作成しなさい。
## ※ printf(" %2d", x ); のように、%2d と記述すると表示が 2 桁に揃う。
def eighteen( ) :
print ( '' .join ( unfoldr( lambda x: None if x[ 1 ] > 9 else
( f'{x[0]:2} × {x[1]:2} = {x[0] * x[1]:2}{"\n " if x[0] == 9 else " "}' ,
( x[ 0 ] + 1 , x[ 1 ] ) if x[ 0 ] < 9 else ( 1 , x[ 1 ] + 1 ) ) , ( 1 , 1 ) ) ) )
## 練習問題 19
## 数値を繰り返して入力し、0 が入力されたら入力を止め、それまでの合計を表示するプログラムを作成しなさい。
def nineteen( ) :
print ( sum ( unfoldr( lambda x: None if x == 0 else ( x, int ( input ( ) ) ) , int ( input ( ) ) ) ) )
## 練習問題 20
## 数値を繰り返して入力し、0 が入力されたら入力を止め、平均値を表示するプログラムを作成しなさい。
## ※ 計算は整数で行い、小数点以下は切り捨ててよい。
## ※ 最後に入力された 0 は平均に含めない。
## ※ 少なくとも 1 回は入力が行われるものとする。(最初に 0 を入力してはいけない)
def twenty( ) :
from statistics import mean
from math import floor
print ( floor( mean( list ( unfoldr(
lambda x: None if x == 0 else ( x, int ( input ( ) ) ) , int ( input ( ) ) ) ) ) ) )
## 練習問題 21
## サイズを示す数値を入力し、何等かの文字で例のような三角形を表示するプログラムを作成しなさい。
## サイズ 4 の例
## $
## $$
## $$$
## $$$$
def twentyOne( n) :
print ( '' .join ( unfoldr( lambda x: None if x > n else ( '$' * x + '\n ' , x + 1 ) , 1 ) ) )
## 練習問題 22
## サイズを示す数値を入力し、何等かの文字で、そのサイズの×印を表示するプログラムを作成しなさい。
## サイズ 3 の例
## X X
## X
## X X
## サイズ 4 の例
## X X
## XX
## XX
## X X
## サイズ 5 の例
## X X
## X X
## X
## X X
## X X
def twentyTwo( n) :
print ( '' .join ( unfoldr( lambda x: None if x > n - 1 else
( '' .join ( unfoldr( lambda i: None if i > n else
( 'X' if i == x or i == n - x - 1 else ' ' , i + 1 ) , 0 ) ) + '\n ' , x + 1 ) , 0 ) ) )
## 練習問題 23
## フィボナッチ数列を表示するプログラムを作成しなさい。
## 最初の2つの項を 0、1 とし、1000 まで( 1000 以下の項)を表示するものとします。
## ※ フィボナッチ数列:
## それぞれの項がその直前の2つの項の和になっている数列のこと。
## 例:0, 1, 1, 2, 3, 5, 8, 13, 21, ...
def twentyThree( n = 1000 ) :
print ( ', ' .join ( unfoldr( lambda x: None if x[ 0 ] > n else ( f'{x[0]}' , ( x[ 1 ] , x[ 0 ] + x[ 1 ] ) ) , ( 0 , 1 ) ) ) )
if __name__ == '__main__' :
## one()
## two()
## three()
## four()
## print(five())
## six()
## seven()
## print(eight())
## print('{} {}'.format(*nine()))
## ten(int(input()))
## eleven(int(input()))
## twelve()
## thirteen()
## fourteen()
## fifteen()
## print(sixteen(int(input())))
## seventeen(20100)
## eighteen()
## nineteen()
## twenty()
## twentyOne(4)
## [twentyTwo(i) for i in (3, 4, 5)]
twentyThree( )
IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwoKIyMjIOS9meWGjeW4sApjbGFzcyB1bmZvbGRyOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGYsIHNlZWQpOgogICAgICAgIHNlbGYuZiA9IGYKICAgICAgICBzZWxmLnNlZWQgPSBzZWVkCiAgICBkZWYgX19pdGVyX18oc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYKICAgIGRlZiBfX25leHRfXyhzZWxmKToKICAgICAgICBtYXRjaCBzZWxmLmYoc2VsZi5zZWVkKToKICAgICAgICAgICAgY2FzZSBhLCBiOgogICAgICAgICAgICAgICAgc2VsZi5zZWVkID0gYgogICAgICAgICAgICAgICAgcmV0dXJuIGEKICAgICAgICAgICAgY2FzZSBOb25lOgogICAgICAgICAgICAgICAgcmFpc2UgU3RvcEl0ZXJhdGlvbgoKIyMg57e057+S5ZWP6aGMIDE6CiMjIOKAnFNQQU3igJ3jgajjgYTjgYbljZjoqp7jgpIgMTAg5Zue6KGo56S644GZ44KL44OX44Ot44Kw44Op44Og44KS5L2c5oiQ44GX44Gq44GV44GE44CCCmRlZiBvbmUobiA9IDEwKToKICAgIHByaW50KCcnLmpvaW4odW5mb2xkcihsYW1iZGEgeDogTm9uZSBpZiB4ID09IDAgZWxzZSAoJ1NQQU1cbicsIHggLSAxKSwgbikpKQoKIyMg57e057+S5ZWP6aGMIDIKIyMg5Lmd5Lmd44CB5LiJ44Gu5q6177yIIDMg772eIDI3IOOBriAzIOOBruWAjeaVsO+8ieOCkuihqOekuuOBmeOCi+ODl+ODreOCsOODqeODoOOCkuS9nOaIkOOBl+OBquOBleOBhOOAggpkZWYgdHdvKG4gPSAzKToKICAgIHByaW50KCcnLmpvaW4odW5mb2xkcihsYW1iZGEgeDogTm9uZSBpZiB4ID4gOSBlbHNlIChmJ3tuICogeH1cbicsIHggKyAxKSwgMSkpKQoKIyMg57e057+S5ZWP6aGMIDMKIyMgMiDjga4gMSDkuZfjgYvjgokgOCDkuZfjgb7jgafjgpLoqIjnrpfjgZfooajnpLrjgZnjgovjg5fjg63jgrDjg6njg6DjgpLkvZzmiJDjgZfjgarjgZXjgYTjgIIKZGVmIHRocmVlKGJhc2UgPSAyLCBwb3dlciA9IDgpOgogICAgcHJpbnQoJycuam9pbih1bmZvbGRyKGxhbWJkYSB4OiBOb25lIGlmIHggPiBwb3dlciBlbHNlIChmJ3tiYXNlICoqIHh9XG4nLCB4ICsgMSksIDEpKSkKCiMjIOe3tOe/kuWVj+mhjCA0CiMjIDcg44Gu6ZqO5LmX44KS6KiI566X44GX44CB6KGo56S644GZ44KL44OX44Ot44Kw44Op44Og44KS5L2c5oiQ44GX44Gq44GV44GE44CCCiMjIOKAuyAJ6ZqO5LmX77yaMSDjgYvjgokgbiDjgb7jgafjga7nqY3jgIIxIMOXIDIgw5cgMyDDlyDigKYgw5fvvIggbiDvvI0gMSDvvInDlyBuCmRlZiBmb3VyKG4gPSA3KToKICAgIGZyb20gZnVuY3Rvb2xzIGltcG9ydCByZWR1Y2UKICAgIHByaW50KHJlZHVjZShsYW1iZGEgeCwgeTogeCAqIHksIHVuZm9sZHIobGFtYmRhIHg6IE5vbmUgaWYgeCA9PSAwIGVsc2UgKHgsIHggLSAxKSwgbikpKQoKIyMg57e057+S5ZWP6aGMIDUKIyMg5pW05pWw44KSIDEwIOWbnuWFpeWKm+OBl+OAgeW5s+Wdh+WApOOCkuaxguOCgeOCi+ODl+ODreOCsOODqeODoOOCkuS9nOaIkOOBl+OBquOBleOBhOOAggojIyDigLsgCeioiOeul+OBr+aVtOaVsOOBp+ihjOOBhOOAgeWwj+aVsOeCueS7peS4i+OBr+WIh+OCiuaNqOOBpuOBpuOCiOOBhOOAggpkZWYgZml2ZShuID0gMTApOgogICAgZnJvbSBzdGF0aXN0aWNzIGltcG9ydCBtZWFuCiAgICBmcm9tIG1hdGggaW1wb3J0IGZsb29yCiAgICByZXR1cm4gZmxvb3IobWVhbih1bmZvbGRyKGxhbWJkYSB4OiBOb25lIGlmIHggPT0gMCBlbHNlIChpbnQoaW5wdXQoKSksIHggLSAxKSwgbikpKQoKIyMg57e057+S5ZWP6aGMIDYKIyMg5pW05pWw44CBMCDjgYsgMSDjgpIgMTAg5Zue5YWl5Yqb44GZ44KL44CC44GT44KM44KS5a++5oim5oiQ57i+44Go6ICD44GI44CBMCDjgpLosqDjgZHjgIExIOOCkuWLneOBoeOBqOOBl+OBpuOAgeWLneOBoeOBrue3j+aVsOOAgeiyoOOBkeOBrue3j+aVsOOCkuihqOekuuOBmeOCi+ODl+ODreOCsOODqeODoOOCkuS9nOaIkOOBl+OBquOBleOBhOOAggpkZWYgc2l4KG4gPSAxMCk6CiAgICBtYXRjaF9yZXN1bHRzID0gbGlzdCh1bmZvbGRyKGxhbWJkYSB4OiBOb25lIGlmIHggPT0gMCBlbHNlKGludChpbnB1dCgpKSwgeCAtIDEpLCBuKSkKICAgIHByaW50KG1hdGNoX3Jlc3VsdHMuY291bnQoMSksIG1hdGNoX3Jlc3VsdHMuY291bnQoMCkpCgojIyDnt7Tnv5LllY/poYwgNwojIyDmrKHjga7jg5fjg63jgrDjg6njg6DjgpLkvZzmiJDjgZfjgarjgZXjgYTjgIIKIyMg5beo5Lq644CB6Ziq56We5oim44Gn5q+O5Zue44Gu5b6X54K544KS5YWl5Yqb44GZ44KL44CC77yIMSDlm54g772eIDkg5Zue77yJCiMjIOWFpeWKm+OBjOe1guOCj+OBo+OBn+OCieOAgeOBneOCjOOBnuOCjOOBruW+l+eCueOBqOOBqeOBoeOCieOBjOWLneOBo+OBn+OBi+OAgeW8leOBjeWIhuOBkeOBi+OCkuihqOekuuOBmeOCi+OAggojIyDigLsgCeippuWQiOOBr+W3qOS6uuOBruWFiOihjOOBqOOBmeOCi+OAggojIyAx5Zue6KGo44CB5beo5Lq644Gu5b6X54K544Gv77yfIDAKIyMgMeWbnuijj+OAgemYquelnuOBruW+l+eCueOBr++8nyAwCiMjIDLlm57ooajjgIHlt6jkurrjga7lvpfngrnjga/vvJ8gMAojIyAy5Zue6KOP44CB6Ziq56We44Gu5b6X54K544Gv77yfIDEKIyMg77yaCiMjIO+8mgojIyDvvJoKIyMgOeWbnuihqOOAgeW3qOS6uuOBruW+l+eCueOBr++8nyAwCiMjIDnlm57oo4/jgIHpmKrnpZ7jga7lvpfngrnjga/vvJ8gMQojIyAKIyMg5beo5Lq677yaNeeCuSwg6Ziq56We77yaNueCuQojIyDjgIDjgIDjgIDpmKrnpZ7jga7li53jgaEKZGVmIHNldmVuKG4gPSA5KToKICAgIGdhbWVzID0gdW5mb2xkcihsYW1iZGEgeDogTm9uZSBpZiB4ID4gbiBlbHNlCiAgICAgICAgICAgICAgICAgICAgKChpbnQoaW5wdXQoZid7eH3lm57ooajjgIHlt6jkurrjga7lvpfngrnjga8/JykpLAogICAgICAgICAgICAgICAgICAgICAgaW50KGlucHV0KGYne3h95Zue6KOP44CB6Ziq56We44Gu5b6X54K544GvPycpKSksCiAgICAgICAgICAgICAgICAgICAgIHggKyAxKSwgMSkKICAgIGdpYW50cywgdGlnZXJzID0gW3N1bShpKSBmb3IgaSBpbiB6aXAoKmdhbWVzKV0KICAgIHByaW50KGYn5beo5Lq6OiB7Z2lhbnRzfeeCuSwg6Ziq56WeOiB7dGlnZXJzfeeCuVxuXHR7J+mYquelnicgaWYgdGlnZXJzID4gZ2lhbnRzIGVsc2UgJ+W3qOS6uid944Gu5Yud44GhJykKCiMjIOe3tOe/kuWVj+mhjCA4CiMjIOiHqueEtuaVsO+8iOato+OBruaVtOaVsO+8ieOCkiAxMCDlm57lhaXlipvjgZfjgIHmnIDlpKflgKTjgpLmsYLjgoHjgovjg5fjg63jgrDjg6njg6DjgpLkvZzmiJDjgZfjgarjgZXjgYTjgIIKZGVmIGVpZ2h0KG4gPSAxMCk6CiAgICByZXR1cm4gbWF4KHVuZm9sZHIobGFtYmRhIHg6IE5vbmUgaWYgeCA9PSAwIGVsc2UoaW50KGlucHV0KCkpLCB4IC0gMSksIG4pKQoKIyMg57e057+S5ZWP6aGMIDkKIyMg5pW05pWw44KSIDEwIOWbnuWFpeWKm+OBl+OAgeacgOWkp+WApOOBqOacgOWwj+WApOOCkuaxguOCgeOCi+ODl+ODreOCsOODqeODoOOCkuS9nOaIkOOBl+OBquOBleOBhOOAggpkZWYgbmluZShuID0gMTApOgogICAgbHN0ID0gbGlzdCh1bmZvbGRyKGxhbWJkYSB4OiBOb25lIGlmIHggPT0gMCBlbHNlIChpbnQoaW5wdXQoKSksIHggLSAxKSwgbikpCiAgICByZXR1cm4gbWF4KGxzdCksIG1pbihsc3QpCgojIyDnt7Tnv5LllY/poYwgMTAKIyMg5YCL5pWw44KS56S644GZ5pWw5YCk44KS5YWl5Yqb44GX44CB44Gd44Gu5YCL5pWw5YiG44Gg44GR4oCYKuKAmeOCkuihqOekuuOBmeOCi+ODl+ODreOCsOODqeODoOOCkuS9nOaIkOOBl+OBquOBleOBhOOAggpkZWYgdGVuKG4pOgogICAgcHJpbnQoJycuam9pbih1bmZvbGRyKGxhbWJkYSB4OiBOb25lIGlmIHggPT0gMCBlbHNlICgnKicsIHggLSAxKSwgbikpKQoKIyMg57e057+S5ZWP6aGMIDExCiMjIOWAi+aVsOOCkuekuuOBmeaVsOWApOOCkuWFpeWKm+OBl+OAgeOBneOBruWAi+aVsOWIhuOBoOOBkSAwIO+9niA5IOOBruaVsOWtl+OCkuihqOekuuOBmeOCi+ODl+ODreOCsOODqeODoOOCkuS9nOaIkOOBl+OBquOBleOBhOOAguaVsOWtl+OBryAwICwgMSAsIDIgLCAzICwgLCDjga7poIbjgavooajnpLrjgZfjgIE5ICDjga7mrKHjga8gMCDjgavmiLvjgovjgoLjga7jgajjgZfjgb7jgZnjgIIKZGVmIGVsZXZlbihuKToKICAgIHByaW50KCcnLmpvaW4odW5mb2xkcihsYW1iZGEgeDogTm9uZSBpZiB4ID49IG4gZWxzZShzdHIoeCAlIDEwKSwgeCArIDEpLCAwKSkpCgojIyDnt7Tnv5LllY/poYwgMTIKIyMgMTAwMDAg44KI44KK5bCP44GV44GEIDMg44Gu57Sv5LmX77yIIDMsIDksIDI3LCAsICwg77yJ44KS44GZ44G544Gm6KGo56S644GZ44KL44OX44Ot44Kw44Op44Og44KS5L2c5oiQ44GX44Gq44GV44GE44CCCmRlZiB0d2VsdmUobiA9IDEwMDAwLCBkID0gMyk6CiAgICBmcm9tIG1hdGggaW1wb3J0IGZsb29yLCBsb2cKICAgIHkgPSBmbG9vcihsb2cobikgLyBsb2coZCkpCiAgICBwcmludCgnJy5qb2luKHVuZm9sZHIobGFtYmRhIHg6IE5vbmUgaWYgeCA+IHkgZWxzZSAoZid7ZCAqKiB4fVxuJywgeCArIDEpLCAxKSkpCgojIyDnt7Tnv5LllY/poYwgMTMKIyMg5pWw5YCk44KS57mw44KK6L+U44GX5YWl5Yqb44GX44CB5ZCI6KiI44GMIDEwMCDjgpLotoXjgYjjgZ/jgonlhaXlipvjgpLmraLjgoHjgablkIjoqIjjgpLooajnpLrjgZnjgovjg5fjg63jgrDjg6njg6DjgpLkvZzmiJDjgZfjgarjgZXjgYTjgIIKZGVmIHRoaXJ0ZWVuKG4gPSAxMDApOgogICAgcHJpbnQoc3VtKHVuZm9sZHIobGFtYmRhIHg6IE5vbmUgaWYgeCA+IG4gZWxzZSAoeCwgeCArIGludChpbnB1dCgpKSksIGludChpbnB1dCgpKSkpKQoKIyMg57e057+S5ZWP6aGMIDE0CiMjIOOCueODiOODqeOCpOOCr+ODu+OCq+OCpuODs+ODiOOCkuaVsOOBiOOCi+ODl+ODreOCsOODqeODoOOCkuS9nOaIkOOBl+OBquOBleOBhOOAggojIyDvvJHnkIPjgZTjgajjgavjgrnjg4jjg6njgqTjgq/jgYvjg5zjg7zjg6vjgYvjgpLlhaXlipvjgZnjgovjgIIKIyMg77yT44K544OI44Op44Kk44Kv44G+44Gf44Gv77yU44Oc44O844Or44Gr44Gq44Gj44Gf44KJ5YWl5Yqb44KS5q2i44KB44CB44K544OI44Op44Kk44Kv44Go44Oc44O844Or44Gu44Kr44Km44Oz44OI44KS6KGo56S644GZ44KL44CCCiMjIOKAuyAJ44K544OI44Op44Kk44Kv44Gu5aC05ZCI44GvIDHjgIHjg5zjg7zjg6vjga7loLTlkIjjga8gMiDjgpLlhaXlipvjgZnjgovjgIIKIyMg44K544OI44Op44Kk44KvPTEgb3Ig44Oc44O844OrPTIg77yfCiMjIDEKIyMg44K544OI44Op44Kk44KvPTEgb3Ig44Oc44O844OrPTIg77yfCiMjIDIKIyMg44K544OI44Op44Kk44KvPTEgb3Ig44Oc44O844OrPTIg77yfCiMjIDEKIyMg44K544OI44Op44Kk44KvPTEgb3Ig44Oc44O844OrPTIg77yfCiMjIDEKIyMgMeODnOODvOODqywz44K544OI44Op44Kk44KvCmRlZiBmb3VydGVlbigpOgogICAgc3RyaWtlX21heCwgYmFsbF9tYXggPSAzLCA0CiAgICBkZWYgZm9vKGxzdCk6CiAgICAgICAgbHN0W2ludChpbnB1dCgn44K544OI44Op44Kk44KvPTEgb3Ig44Oc44O844OrPTIgP1xuJykpIC0gMV0gKz0gMQogICAgICAgIHJldHVybiBsc3QKICAgIHByaW50KCd7MX3jg5zjg7zjg6ssIHswfeOCueODiOODqeOCpOOCrycuZm9ybWF0KCpsaXN0KHVuZm9sZHIobGFtYmRhIHg6IE5vbmUgaWYgeFswXSA9PSBzdHJpa2VfbWF4IG9yIHhbMV0gPT0gYmFsbF9tYXggZWxzZSAoeCwgZm9vKHgpKSwgZm9vKFswLCAwXSkpKVstMV0pKQoKIyMg57e057+S5ZWP6aGMIDE1CiMjIOWJjeOBruWVj+mhjOOBq+asoeOBruS/ruato+OCkuWKoOOBiOOBquOBleOBhOOAggojIyDvvJHnkIPjgZTjgajjgavjgrnjg4jjg6njgqTjgq/jgIHjg5zjg7zjg6vjgIHjg5XjgqHjgqbjg6vjga7kvZXjgozjgYvjgpLlhaXlipvjgZnjgovjgILvvIjmrovlv7XjgarjgYzjgonjg5Ljg4Pjg4jjgavjga/jgarjgorjgb7jgZvjgpPvvIkKIyMg44OV44Kh44Km44Or44Gu5aC05ZCI44CB77yS44K544OI44Op44Kk44Kv44G+44Gn44Gv44K544OI44Op44Kk44Kv44Gr44Kr44Km44Oz44OI44GZ44KL44GM44CB77yT44K544OI44Op44Kk44Kv44Gr44Gv44Gq44KJ44Gq44GE44CCCiMjIO+8k+OCueODiOODqeOCpOOCr+OBvuOBn+OBr++8lOODnOODvOODq+OBq+OBquOBo+OBn+OCieWFpeWKm+OCkuatouOCgeOAgeOCueODiOODqeOCpOOCr+OBqOODnOODvOODq+OBruOCq+OCpuODs+ODiOOCkuihqOekuuOBmeOCi+OAggpkZWYgZmlmdGVlbigpOgogICAgc3RyaWtlX21heCwgYmFsbF9tYXggPSAzLCA0CiAgICBkZWYgZm9vKGxzdCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBsc3RbaW50KGlucHV0KCfjgrnjg4jjg6njgqTjgq89MSBvciDjg5zjg7zjg6s9MiA/XG4nKSkgLSAxXSArPSAxCiAgICAgICAgZXhjZXB0IEluZGV4RXJyb3I6CiAgICAgICAgICAgIGlmIGxzdFswXSA8IDI6CiAgICAgICAgICAgICAgICBsc3RbMF0gKz0gMQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIHJldHVybiBsc3QKICAgIHByaW50KCd7MX3jg5zjg7zjg6ssIHswfeOCueODiOODqeOCpOOCrycuZm9ybWF0KCpsaXN0KHVuZm9sZHIobGFtYmRhIHg6IE5vbmUgaWYgeFswXSA9PSBzdHJpa2VfbWF4IG9yIHhbMV0gPT0gYmFsbF9tYXggZWxzZSAoeCwgZm9vKHgpKSwgZm9vKFswLCAwXSkpKVstMV0pKQoKIyMg57e057+S5ZWP6aGMIDE2CiMjIOWFpeWKm+OBleOCjOOBn+aVsOOBjOe0oOaVsOOBi+OBqeOBhuOBi+OCkuWIpOWumuOBmeOCi+ODl+ODreOCsOODqeODoOOCkuS9nOaIkOOBl+OBquOBleOBhOOAggojIyDigLsgCeWIpOWumuOBmeOCi+aVsOOBryA0IOS7peS4iuOBqOOBl+OBpuOCiOOBhOOAggpkZWYgc2l4dGVlbihuKToKICAgIGRlZiBmb28oeCk6CiAgICAgICAgbm9ubG9jYWwgbgogICAgICAgIGlmIHggPiBuOgogICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHdoaWxlIG4gJSB4ICE9IDA6CiAgICAgICAgICAgICAgICB4ICs9IDEKICAgICAgICAgICAgcmV0dXJuIChuIGlmIHggKiogMiA+IG4gZWxzZSB4LCB4ICsgMSkKICAgIHJldHVybiBsZW4obGlzdCh1bmZvbGRyKGZvbywgMikpKSA9PSAxCgojIyDnt7Tnv5LllY/poYwgMTcKIyMgMiDku6XkuIrjga7mlbDlgKTjgpLlhaXlipvjgZfjgIHntKDlm6DmlbDliIbop6PjgZfjgZ/ntZDmnpzjgpLooajnpLrjgZfjgarjgZXjgYTjgIIKIyMg5L6LOgojI+OAgDIwMTAwCiMj44CAMiAyIDMgNSA1IDY3CmRlZiBzZXZlbnRlZW4obik6CiAgICBmcm9tIG1hdGggaW1wb3J0IHNxcnQsIGNlaWwKICAgIGRlZiBmb28oeCk6CiAgICAgICAgbm9ubG9jYWwgbgogICAgICAgIGlmIHggPiBjZWlsKHNxcnQobikpOgogICAgICAgICAgICByZXR1cm4gTm9uZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgICAgICBpZiBzaXh0ZWVuKHgpIGFuZCBuICUgeCA9PSAwOgogICAgICAgICAgICAgICAgICAgIG4gLz0geAogICAgICAgICAgICAgICAgICAgIHJldHVybiAoZid7eH0gJywgeCkKICAgICAgICAgICAgICAgIHggKz0gMQogICAgcmV0dXJuIHByaW50KCcnLmpvaW4odW5mb2xkcihmb28sIDIpKSkKCiMjIOe3tOe/kuWVj+mhjCAxOAojIyDkuZ3kuZ3ooajvvIjkuIDjga7mrrXvvZ7kuZ3jga7mrrXvvInjgpLooajnpLrjgZnjgovjg5fjg63jgrDjg6njg6DjgpLkvZzmiJDjgZfjgarjgZXjgYTjgIIKIyMg4oC7IAlwcmludGYoIiAlMmQiLCB4ICk7IOOBruOCiOOBhuOBq+OAgSUyZCDjgajoqJjov7DjgZnjgovjgajooajnpLrjgYwgMiDmoYHjgavmj4PjgYbjgIIKZGVmIGVpZ2h0ZWVuKCk6CiAgICBwcmludCgnJy5qb2luKHVuZm9sZHIobGFtYmRhIHg6IE5vbmUgaWYgeFsxXSA+IDkgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgIChmJ3t4WzBdOjJ9IMOXIHt4WzFdOjJ9ID0ge3hbMF0gKiB4WzFdOjJ9eyJcbiIgaWYgeFswXSA9PSA5IGVsc2UgIiAifScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICh4WzBdICsgMSwgeFsxXSkgaWYgeFswXSA8IDkgZWxzZSAoMSwgeFsxXSArIDEpKSwgKDEsIDEpKSkpCgojIyDnt7Tnv5LllY/poYwgMTkKIyMg5pWw5YCk44KS57mw44KK6L+U44GX44Gm5YWl5Yqb44GX44CBMCDjgYzlhaXlipvjgZXjgozjgZ/jgonlhaXlipvjgpLmraLjgoHjgIHjgZ3jgozjgb7jgafjga7lkIjoqIjjgpLooajnpLrjgZnjgovjg5fjg63jgrDjg6njg6DjgpLkvZzmiJDjgZfjgarjgZXjgYTjgIIKZGVmIG5pbmV0ZWVuKCk6CiAgICBwcmludChzdW0odW5mb2xkcihsYW1iZGEgeDogTm9uZSBpZiB4ID09IDAgZWxzZSAoeCwgaW50KGlucHV0KCkpKSwgaW50KGlucHV0KCkpKSkpCgojIyDnt7Tnv5LllY/poYwgMjAKIyMg5pWw5YCk44KS57mw44KK6L+U44GX44Gm5YWl5Yqb44GX44CBMCDjgYzlhaXlipvjgZXjgozjgZ/jgonlhaXlipvjgpLmraLjgoHjgIHlubPlnYflgKTjgpLooajnpLrjgZnjgovjg5fjg63jgrDjg6njg6DjgpLkvZzmiJDjgZfjgarjgZXjgYTjgIIKIyMg4oC7IAnoqIjnrpfjga/mlbTmlbDjgafooYzjgYTjgIHlsI/mlbDngrnku6XkuIvjga/liIfjgormjajjgabjgabjgojjgYTjgIIKIyMg4oC7IAnmnIDlvozjgavlhaXlipvjgZXjgozjgZ8gMCDjga/lubPlnYfjgavlkKvjgoHjgarjgYTjgIIKIyMg4oC7IAnlsJHjgarjgY/jgajjgoIgMSDlm57jga/lhaXlipvjgYzooYzjgo/jgozjgovjgoLjga7jgajjgZnjgovjgILvvIjmnIDliJ3jgasgMCDjgpLlhaXlipvjgZfjgabjga/jgYTjgZHjgarjgYTvvIkKZGVmIHR3ZW50eSgpOgogICAgZnJvbSBzdGF0aXN0aWNzIGltcG9ydCBtZWFuCiAgICBmcm9tIG1hdGggaW1wb3J0IGZsb29yCiAgICBwcmludChmbG9vcihtZWFuKGxpc3QodW5mb2xkcigKICAgICAgICBsYW1iZGEgeDogTm9uZSBpZiB4ID09IDAgZWxzZSAoeCwgaW50KGlucHV0KCkpKSwgaW50KGlucHV0KCkpKSkpKSkKCiMjIOe3tOe/kuWVj+mhjCAyMQojIyDjgrXjgqTjgrrjgpLnpLrjgZnmlbDlgKTjgpLlhaXlipvjgZfjgIHkvZXnrYnjgYvjga7mloflrZfjgafkvovjga7jgojjgYbjgarkuInop5LlvaLjgpLooajnpLrjgZnjgovjg5fjg63jgrDjg6njg6DjgpLkvZzmiJDjgZfjgarjgZXjgYTjgIIKIyMg44K144Kk44K6IDQg44Gu5L6LCiMjICQKIyMgJCQKIyMgJCQkCiMjICQkJCQKZGVmIHR3ZW50eU9uZShuKToKICAgIHByaW50KCcnLmpvaW4odW5mb2xkcihsYW1iZGEgeDogTm9uZSBpZiB4ID4gbiBlbHNlICgnJCcgKiB4ICsgJ1xuJywgeCArIDEpLCAxKSkpCgojIyDnt7Tnv5LllY/poYwgMjIKIyMg44K144Kk44K644KS56S644GZ5pWw5YCk44KS5YWl5Yqb44GX44CB5L2V562J44GL44Gu5paH5a2X44Gn44CB44Gd44Gu44K144Kk44K644Guw5fljbDjgpLooajnpLrjgZnjgovjg5fjg63jgrDjg6njg6DjgpLkvZzmiJDjgZfjgarjgZXjgYTjgIIKIyMg44K144Kk44K6IDMg44Gu5L6LCiMjIFjjgIBYCiMjIOOAgFgKIyMgWOOAgFgKIyMg44K144Kk44K6IDQg44Gu5L6LCiMjIFjjgIDjgIBYCiMjIOOAgFhYCiMjIOOAgFhYCiMjIFjjgIDjgIBYCiMjIOOCteOCpOOCuiA1IOOBruS+iwojIyBY44CA44CA44CAWAojIyDjgIBY44CAWAojIyDjgIDjgIBYCiMjIOOAgFjjgIBYCiMjIFjjgIDjgIDjgIBYIApkZWYgdHdlbnR5VHdvKG4pOgogICAgcHJpbnQoJycuam9pbih1bmZvbGRyKGxhbWJkYSB4OiBOb25lIGlmIHggPiBuIC0gMSBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgKCcnLmpvaW4odW5mb2xkcihsYW1iZGEgaTogTm9uZSBpZiBpID4gbiBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJ1gnIGlmIGkgPT0geCBvciBpID09IG4gLSB4IC0gMSBlbHNlICcgJywgaSArIDEpLCAwKSkgKyAnXG4nLCB4ICsgMSksIDApKSkKCiMjIOe3tOe/kuWVj+mhjCAyMwojIyDjg5XjgqPjg5zjg4rjg4Pjg4HmlbDliJfjgpLooajnpLrjgZnjgovjg5fjg63jgrDjg6njg6DjgpLkvZzmiJDjgZfjgarjgZXjgYTjgIIKIyMg5pyA5Yid44Gu77yS44Gk44Gu6aCF44KSIDDjgIExIOOBqOOBl+OAgTEwMDAg44G+44Gn77yIIDEwMDAg5Lul5LiL44Gu6aCF77yJ44KS6KGo56S644GZ44KL44KC44Gu44Go44GX44G+44GZ44CCCiMjIOKAuyAJICAgICAgICAg44OV44Kj44Oc44OK44OD44OB5pWw5YiX77yaCiMjIOOAgOOBneOCjOOBnuOCjOOBrumgheOBjOOBneOBruebtOWJjeOBru+8kuOBpOOBrumgheOBruWSjOOBq+OBquOBo+OBpuOBhOOCi+aVsOWIl+OBruOBk+OBqOOAggojIyAgICAgICAgICDkvovvvJowLCAxLCAxLCAyLCAzLCA1LCA4LCAxMywgMjEsIC4uLgpkZWYgdHdlbnR5VGhyZWUobiA9IDEwMDApOgogICAgcHJpbnQoJywgJy5qb2luKHVuZm9sZHIobGFtYmRhIHg6IE5vbmUgaWYgeFswXSA+IG4gZWxzZSAoZid7eFswXX0nLCAoeFsxXSwgeFswXSArIHhbMV0pKSwgKDAsIDEpKSkpCmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CiMjICAgIG9uZSgpCiMjICAgIHR3bygpCiMjICAgIHRocmVlKCkKIyMgICAgZm91cigpCiMjICAgIHByaW50KGZpdmUoKSkKIyMgICAgc2l4KCkKIyMgICAgc2V2ZW4oKQojIyAgICBwcmludChlaWdodCgpKQojIyAgICBwcmludCgne30ge30nLmZvcm1hdCgqbmluZSgpKSkKIyMgICAgdGVuKGludChpbnB1dCgpKSkKIyMgICAgZWxldmVuKGludChpbnB1dCgpKSkKIyMgICAgdHdlbHZlKCkKIyMgICAgdGhpcnRlZW4oKQojIyAgICBmb3VydGVlbigpCiMjICAgIGZpZnRlZW4oKQojIyAgICBwcmludChzaXh0ZWVuKGludChpbnB1dCgpKSkpCiMjICAgIHNldmVudGVlbigyMDEwMCkKIyMgICAgZWlnaHRlZW4oKQojIyAgICBuaW5ldGVlbigpCiMjICAgIHR3ZW50eSgpCiMjICAgIHR3ZW50eU9uZSg0KQojIyAgICBbdHdlbnR5VHdvKGkpIGZvciBpIGluICgzLCA0LCA1KV0KICAgIHR3ZW50eVRocmVlKCkK