なんかあの格差(?)のやつ

Twitterで見ました。オリジナルではありません。

100円を持ったN人の人がいました。それぞれの人は、毎ターン、ランダムに決めたある参加者に対してお金を1円を渡します(自分にあげることも可)。これをtimes回繰り返します。さて、皆さんどれくらいのお金を持っているでしょうか?

N=10、100ターンやるとこんな感じ(貧乏な順にソート)。5回やってみましょう。
[73, 82, 87, 92, 96, 99, 102, 106, 128, 135]
[61, 82, 86, 91, 95, 96, 108, 114, 132, 135]
[47, 75, 76, 89, 97, 99, 122, 126, 131, 138]
[46, 65, 82, 84, 94, 107, 121, 125, 126, 150]
[48, 59, 75, 76, 97, 109, 110, 132, 133, 161]
まあまあ格差ありますね。

300ターンにします。
[40, 68, 74, 77, 82, 107, 115, 139, 144, 154]
[30, 57, 57, 60, 75, 103, 141, 155, 157, 165]
[35, 42, 55, 56, 83, 125, 139, 143, 160, 162]
[21, 43, 46, 56, 91, 137, 140, 141, 147, 178]
[18, 30, 46, 52, 105, 116, 136, 161, 164, 172]
格差広がりました??

1000ターン
[26, 39, 84, 87, 99, 103, 107, 122, 126, 207]
[40, 42, 53, 70, 85, 102, 114, 114, 162, 218]
[11, 26, 30, 96, 109, 112, 130, 142, 150, 194]
[19, 21, 25, 49, 99, 104, 128, 153, 183, 219]
[3, 24, 43, 49, 66, 107, 139, 162, 195, 212]
もっと広がっている??

上の操作を100回繰り返して、最も貧乏な人の平均値と、最も裕福な人の平均値を出してみます。

100ターン:最小27.06、最大219.82
300ターン:最小10.58、最大272.67
1000ターン:最小8.93、最大319.29

ターンが増えると格差も増えそう?ランダムなので、平均値ですら安定しないのですが....。


import random
N=100 #人数
give = 1 #1回で渡すお金
Prime_money=100 #初期のお金
times = 100 #何回繰り返すか?
M=100 #何回の平均を取るか?

ave_min=0 #最もお金を持っている人の平均
ave_max=0 #最もお金を持っていない人の平均

prime=[]
L=[]
for i in range(N):
    prime.append(Prime_money)

for i in range(M):
    #res(N,give,Prime_money,times,prime)
    L=prime
    for j in range(times):
        for i in range(N):
            if L[i] != 0:
                k = random.randint(0,N-1)
                L[i] -= give
                L[k] += give
    s_L = sorted(L)
    ave_min += s_L[0]
    ave_max += s_L[N-1]
    
print(str(ave_min / M)+" , "+str(ave_max / M))

paiza 問題「日別訪問者数の最大平均区間 Python3編」

眠い。問題はこちら。
paiza.jp
こういう問題できるようになってきた気がする。明日からはまじめに講義やります。

s = input().split()
n= int(s[0])
sec = int(s[1])

log = list(map(int , input().split()) )
res = []

for i in range(n-sec+1):
    #print("i is "+str(i))
    sum = 0
    for j in range(sec):
        #print("  i+j is "+str(i+j))
        sum += log[i+j]
    ave = sum/sec
    res.append(ave)
#print(res)
sorted_res = sorted(res , reverse = True)
#print(sorted_res)
max = sorted_res[0]
first = res.index(max) + 1
num = res.count(max)

print(str(num) + " " + str(first))

paizaの問題 Vtuber

in を使って実行時間が長くなってしまった。

f:id:realname:20210712002244p:plain
辞書を使わないとこうなるんだよ
# coding: utf-8
# Your code here!
n = int(input())

mem=[]
spc_m=[]
spc_c=[]
spc=[]

for i in range(n):
    s =input().split()
    if s[1] == 'give':
        if s[0] in spc_m:
            spc_c[spc_m.index(s[0])] += int(s[2])
        else :
            spc_m.append(s[0])
            spc_c.append( int(s[2]) )
        
    elif s[1] == 'join':
        mem.append( s[0] )

for i in range( len(spc_m) ):
    spc.append([ spc_c[i] , spc_m[i]])

spc.sort(reverse=True)
mem.sort()

#print(spc)
#print(mem)

spc.sort( reverse = True )

for i in spc:
    print(i[1])
for i in mem:
    print(i)

辞書型でもやろうとしたけど、うまくいってない。

n = int(input())

mem=[]
spc={}

for i in range(n):
    s =input().split()
    if s[1] == 'give':
        if s[0] in spc:
            spc[s[0]] += int(s[2])
        else:
            spc[s[0]] = int(s[2])
        
    elif s[1] == 'join':
        mem.append( s[0] )

print(spc)
print(mem)
res_spc = sorted(spc.items(), key = lambda x : x[1] , reverse = True)
res_spc = sorted( res_spc )
mem.sort()

print(res_spc)

for i in res_spc:
    print(i[0])
for i in mem:
    print(i)

paiza 問題「五目並べ Python3編」

for str in line:
の書き方すっかり忘れてたわ。実行時間0.02 sだったしいいか。

縦横斜めでOとXの数をカウントしていき、5個あればflagを立てて勝者確定。その後のカウントはスキップする。もし、OとXが両方出てきたら、すぐにカウント終了する。

1ループごとにOfとXfの数を判定しているのがすごく無駄な気がしているのだが...。for ループが終わってからOfとXfの判定をするようにしたい....。

問題はこちら。
五目並べ | レベルアップ問題集 | プログラミング学習サービス【paizaラーニング】

s=[]
for i in range(5):
    temp = [s for s in input()]
    s.append(temp)
    
#print(s)
flag=0 #勝者決まったら1に
res = 'D' #result。勝者なければそのままDで
#横の判定
for i in range(5):
    Of = 0
    Xf = 0
    for j in range(5):
        if s[i][j] == 'O':
            Of += 1
        elif s[i][j] == 'X':
            Xf += 1
        elif Xf>0 and Of>0:
            break
    
    if Of == 5:
        res = 'O'
        flag = 1
        break
    
    elif Xf == 5:
        res = 'X'
        flag = 1
        break

if flag == 0:
    #縦の判定
    for i in range(5):
        Of = 0
        Xf = 0
        for j in range(5):
            if s[j][i] == 'O':
                Of += 1
            elif s[j][i] == 'X':
                Xf += 1
            elif Xf>0 and Of>0:
                break
        
        if Of == 5:
            res = 'O'
            flag = 1
            break
        elif Xf == 5:
            res = 'X'
            flag = 1
            break

if flag == 0:
    #斜めの判定(右下がり)
    Of = 0
    Xf = 0
    for i in range(5):
        if s[i][i] == 'O':
            Of += 1
        elif s[i][i] == 'X':
            Xf += 1
        elif Xf>0 and Of>0:
            break
    if Of == 5:
        res = 'O'
    elif Xf == 5:
        res = 'X'

if flag == 0:
    #斜めの判定(左上がり)
    Of = 0
    Xf = 0
    for i in range(5):
        if s[i][4-i] == 'O':
            Of += 1
        elif s[i][i] == 'X':
            Xf += 1
        elif Xf>0 and Of>0:
            break
    if Of == 5:
        res = 'O'
    elif Xf == 5:
        res = 'X'

print(res)

paiza 問題「長テーブルのうなぎ屋 Python3編」解けました

300日ぶりくらいにやってみたら解けたという。寝かせてみるもんですね。
問題はhttps://paiza.jp/works/mondai/skillcheck_sample/long-table

  • 配列sheetで席を表現して、人が座ってたら1、座ってなかったら0にする。
  • グループiのj番目の人が座れるかどうかを順番に判定してダメだったら即ループを脱出するようにした。
  • なんかこう、実行時間が長めかと。最後のテストは0.04秒かかってしまった。
s = input().split()
#print(s)
num_sheet = int(s[0])
group = int(s[1])

c=[]
for i in range(group):
    c.append(list( map(int , input().split()) ) )

#print(c)

sheet =[]
for i in range(num_sheet):
    sheet.append(0)
#print(sheet)

for i in range(group): #i番目のグループ
    flag = 0
    #print("Group "+str(i) )
    
    for j in range(c[i][0]):
        #print("  j+c[i][1]-1 is "+str(j+c[i][1]-1) )
        
        if (j+c[i][1]-1) <= (num_sheet - 1): #i番目のグループのj番目の人がnum_sheeetを超えないとき
            if sheet[j+c[i][1]-1] ==1 : #人がいたらBreak
                #print("  break")
                break
            else :
                flag += 1
                
        elif (j+c[i][1]-1) > (num_sheet - 1) : #i番目のグループのj番目の人がnum_sheeetを超えたとき
            if sheet[j+c[i][1]-1-num_sheet] ==1 : #人がいたらBreak
                #print("  break")
                break
            else :
                flag += 1
    
    if flag == c[i][0] : #みんな座れたら次に進む
        #print("  this group can be seated!")
        for k in range(c[i][0]):
            if k+c[i][1]-1 <= (num_sheet - 1): #i番目のグループのj番目の人がnum_sheeetを超えないとき
                sheet[k+c[i][1]-1] = 1
            else : #i番目のグループのj番目の人がnum_sheeetを超えたとき
                sheet[k+c[i][1]-1-num_sheet] = 1 
    #print(sheet)

res=0
for i in range(num_sheet):
    if sheet[i]==1:
        res += 1
        
print(res)

paiza 問題「じゃんけんの手の出し方」

実験でpyてょnをやったので、1年ぶりくらいにpaizaを解いた。深夜にやることではない。バカアホ全探索の巻。まあ全探索が正解らしいが。問題は↓↓
paiza.jp

デバッグ用のいろいろを省いた提出用版。各データ0.02秒で処理できたはず。

# coding: utf-8
# Your code here!

s = input().split()
times = int(s[0])
finger = int(s[1])

win = 0
G = 0
C = 0
P = 0

order = list(input())

for i in range(times):
    if order[i] == 'C':
        C += 1
    elif order[i] == 'G':
        G += 1
    elif order[i] == 'P':
        P += 1

temp_win = 0
for i in range(min(times , int(finger/5) ) + 1): 
    if (finger-i*5)%2 == 0 and times >= (i + (finger - i*5)/2): 
        myP = i
        myC = (finger - i*5)/2
        myG = times - myC - myP
        i_win = min(myP , G) + min(myC , P) + min(myG , C)
        temp_win = max(i_win , temp_win)

win += temp_win 
print(int(win))

こっちはデバッグ用。めちゃめちゃprintします。見にくいわ。

s = input().split()
times = int(s[0]) #じゃんけんの回数
finger = int(s[1]) #指の本数
#自分の出すGCPの回数
myG=0 
myC=0
myP=0
#自分の出したGCPの数の最終結果(デバッグ用)
res_myP = 0
res_myC = 0

order = list(input()) #相手の出すGCPをリストで格納
win = 0 #自分の勝利数
#相手の出すGCPの数
G = 0
C = 0
P = 0

print(order)#確認用

#相手の出すGCPをカウント
for i in range(times):
    if order[i] == 'C':
        C += 1
    elif order[i] == 'G':
        G += 1
    elif order[i] == 'P':
        P += 1

print(G) #確認用
print(C)
print(P)

#fingerをmyPとmyCにどれだけ割り振れるかを考える?
#temp_winが最大になる手の出し方を考える。
temp_win = 0 
for i in range(min(times , int(finger/5) ) + 1): #myPをi回出す場合を考える。
    print("the i is "+str(i))
    if (finger-i*5)%2 == 0 and times >= (i + (finger - i*5)/2): #myPをi回出して、残りのfingerが2で割り切れるか?そして回数制限は大丈夫か?
        #自分の出すGCPの回数を求める
        myP = i 
        myC = (finger - i*5)/2
        myG = times - myC - myP
        
        #myPがiの時の勝利回数i_winを求める
        i_win = min(myP , G) + min(myC , P) + min(myG , C)
        
        #確認用
        print("  myP is "+str(myP))
        print("  myC is "+str(myC))
        print("  myG is "+str(myG))
        print("  i_win is "+str(i_win))
        
        #temp_win = max(i_win , temp_win)
        #i_win と temp_win の大小比較。temp_winが更新されたらres_myP,Cも変更
        if temp_win < i_win :
            temp_win = i_win 
            res_myP = myP #確認用
            res_myC = myC #確認用
            print("    temp_win is changed") #確認用
    else :#確認用
        print("  skipped") #確認用
        
print("") #確認用
win += temp_win #winの最終結果を求める。
print("win is ...") #確認用
print(win) #出力
print("check is ...")#Fingerの数と出した手の数が合っているか確認
print(finger==(res_myC*2 + res_myP*5))  #確認用

長テーブルのうなぎ屋 (paizaランク B 相当)

解けてないんだけど、保存で。

'''
1行目にはn(座席数)とm(グループ数)が半角スペース区切りで入力されます。
i+1行目(1≦i≦m)には2個の整数a_i(グループの人数)とb_i(着席開始座席番号)が半角スペース区切りで入力されます。
'''
a = input().split( )

seet_num = int(a[0])
group_num = int(a[1])

seet = []
for i in range(seet_num):
    seet.append("")
    
data=[]
for i in range(group_num):
    [c,d] = input().split( )
    data.append([int(c) , int(d)])

count = 0
print(data)

#指定範囲を考える
for i in range(group_num):
    print(seet)
    cut = []
    start = data[i][1] - 1 #この番号のリストから調べ始めます
    end = data[i][0] + data[i][1] 
    if end <= seet_num -1 :
        for j in range(start, end):
            cut.append(seet[j])
        print("cut is ",end="")
        print(cut)
        if "#" not in cut:
            count += data[i][0]
            for j in range(start, end):
                seet[j] = "#"
    else :
        end = end - seet_num
        for k in range(start , seet_num):
            cut.append(seet[k])
        for l in range(0 , end):
            cut.append(seet[l])
        if "#" not in cut:
            count += data[i][0]
            for m in range(start , seet_num):
                seet[j] = "#"
            for n in range(0 , end):
                seet[k] = "#"
                
print(seet)
print(count)