Translate

2016年4月1日 星期五

[Python] 分糖果

這一題我想了比較久,一直在想用什麼方式來做比較好。

題目: 十個小孩圍成一圈分糖果。 老師給第一個小孩10顆,第2個2顆,第3個8顆,第4個22顆,

第5個16顆, 第6個4顆,第7個10顆,第8個6顆,第9個14顆第10個20顆。

然後,所有的小孩同時將手中的糖分一半給右邊的小孩,糖果數為奇數的人可以向老師要一顆。 問 經過幾次後大家手上的糖果數一樣多? 每人各有多少個糖果。




# -*- coding: utf-8 -*-
"""
Created on Sun Mar 27 21:53:58 2016
@author: Moon
分糖果,老師分給
1 > 10個
2 > 2個
3 > 8個
4 > 22個
5 > 16個
6 > 4個
7 > 10個
8 > 6個
9 > 14個
10 > 20個
"""
children = [10, 2, 8, 22, 16, 4, 10, 6, 14, 20]
a = [i*2 for i in range(5)]
b = [i*2-1 for i in range(1,6)]

c = [a+b for a, b in zip(a,b)]
#print(a)
d = [int(i/2) for i in a]


#print(d)

def oddPlusOne(list):
    new_list = []
    for i in list:
        if i % 2 == 0:
            new_list.append(i)
        else:
            i = i + 1
            new_list.append(i)
    return(new_list)
    
test = oddPlusOne(children)

e = sum(children)/len(children)
f = len(children)

def avgList(list):
    avg = sum(list)/len(list)
    return(avg)

def notEnd(list):
    avg = avgList(list)
    index = 0
    for i in list:
        if i == avg:
            pass
        else:
            index = index + 1
    return(index)

def candyNumGive(list):
    give = oddPlusOne(list)
    last = give.pop(len(give) - 1)
    give.insert(0,last)
    give = [int(i/2) for i in give]
    return(give)
    

#temp = [children-give_to for children, give_to in zip(children, give_to)]
times = 0
while notEnd(children) != 0:
    times = times + 1
    children = oddPlusOne(children)
    
    receive = candyNumGive(children)
    children = [int(i/2) for i in children]
    children = [children + receive for children, receive in zip(children, receive)]
    print("次數: " + str(times) + " 過程: " + str(children) )
print('times is ' + str(times))

print("Result is " + str(children))
結果:
次數: 1 過程: [15, 6, 5, 15, 19, 10, 7, 8, 10, 17]
次數: 2 過程: [17, 11, 6, 11, 18, 15, 9, 8, 9, 14]
次數: 3 過程: [16, 15, 9, 9, 15, 17, 13, 9, 9, 12]
次數: 4 過程: [14, 16, 13, 10, 13, 17, 16, 12, 10, 11]
次數: 5 過程: [13, 15, 15, 12, 12, 16, 17, 14, 11, 11]
次數: 6 過程: [13, 15, 16, 14, 12, 14, 17, 16, 13, 12]
次數: 7 過程: [13, 15, 16, 15, 13, 13, 16, 17, 15, 13]
次數: 8 過程: [14, 15, 16, 16, 15, 14, 15, 17, 17, 15]
次數: 9 過程: [15, 15, 16, 16, 16, 15, 15, 17, 18, 17]
次數: 10 過程: [17, 16, 16, 16, 16, 16, 16, 17, 18, 18]
次數: 11 過程: [18, 17, 16, 16, 16, 16, 16, 17, 18, 18]
次數: 12 過程: [18, 18, 17, 16, 16, 16, 16, 17, 18, 18]
次數: 13 過程: [18, 18, 18, 17, 16, 16, 16, 17, 18, 18]
次數: 14 過程: [18, 18, 18, 18, 17, 16, 16, 17, 18, 18]
次數: 15 過程: [18, 18, 18, 18, 18, 17, 16, 17, 18, 18]
次數: 16 過程: [18, 18, 18, 18, 18, 18, 17, 17, 18, 18]
次數: 17 過程: [18, 18, 18, 18, 18, 18, 18, 18, 18, 18]
times is 17
Result is [18, 18, 18, 18, 18, 18, 18, 18, 18, 18]
雖然答案是16次,不過那應該不是重點,因為書上是問分幾次。 而且跑出來的答案是一樣的。
程式碼的自問自答
def oddPlusOne(list):
    new_list = []
    for i in list:
        if i % 2 == 0:
            new_list.append(i)
        else:
            i = i + 1
            new_list.append(i)
    return(new_list)
這是為了符合題目,如果遇到糖果數不是偶數,則和老師多要一個糖果。
所以把每個list裡面的元素拿出來判斷一次,如果是偶數,則原封不動存入list,如果是奇數,則加 1 後存入list
def avgList(list):
    avg = sum(list)/len(list)
    return(avg)

def notEnd(list):
    avg = avgList(list)
    index = 0
    for i in list:
        if i == avg:
            pass
        else:
            index = index + 1
    return(index)
這兩個def要一起看,python 好像沒有內建list平均的函數。
所以要自已用一個,
avg list就是拿來算平均的。
notEnd 則是拿來判斷是不是已經到了條件要的狀態
如果大家都一樣,那就表示每個人手上持有的糖果和全體的平均一樣
這邊應該有更好的判斷方式,不過我還沒想到
notEnd把每個人手上的糖果和平均比對,如果一樣,則給予 0 的值,如果不一樣,則給予 1 值。
最後把整個list相加,如果是0,則達到終點,如果不是0,那就表示還沒有到終點,要繼續分。
def candyNumGive(list):
    give = oddPlusOne(list)
    last = give.pop(len(give) - 1)
    give.insert(0,last)
    give = [int(i/2) for i in give]
    return(give)
這邊則是把要相加的list獨立出來
因為小朋友們是坐成一圈,所以list中的最後一個,會把手上的糖果給到第一個,也就是children[0]
所以這個 def 會 用
last = give.pop(len(give) - 1)
取出最後一個元素,再用
give.insert(0,last)
插到最後一行
等這些函式都寫出來後,核心的部分自然就出來了
while notEnd(children) != 0:
    times = times + 1
    children = oddPlusOne(children)
    
    receive = candyNumGive(children)
    children = [int(i/2) for i in children]
    children = [children + receive for children, receive in zip(children, receive)]
    print("次數: " + str(times) + " 過程: " + str(children) )
print('times is ' + str(times))

print("Result is " + str(children))
只要 notEnd判斷children還沒達到終點狀態,就要繼續分糖。

沒有留言:

張貼留言