iT邦幫忙

0

[D-344] Python 7/100天_綜合案例2

  • 分享至 

  • xImage
  •  

==今天的課題
課本:https://reurl.cc/ROvEv6
综合案例2:约瑟夫环问题。
這次不用餵狗,老師貼心的給了個故事內容
想法:
《幸运的基督徒》
有15个基督徒和15个非基督徒在海上遇险,为了能让一部分人活下来不得不将其中15个人扔到海里面去,有个人想了个办法就是大家围成一个圈,由某个人开始从1报数,报到9的人就扔到海里面,他后面的人接着从1开始报数,报到9的人继续扔到海里面,直到扔掉15个人。由于上帝的保佑,15个基督徒都幸免于难,问这些人最开始是怎么站的,哪些位置是基督徒哪些位置是非基督徒。
嘗試找出規律=先把問題簡化
假設今天只有4個人,o基x不基,數到三丟的話,站法會是
第一回合(o=2/2,x=2/2)
oxxo
123
第二回合(o=2/2,x=1/2)
oxo
231
··········基督教勝利(o=2/2,x=0/2)
思路:
1.建立一個空list當作排隊的基礎
2.順序隨機(用前一次練習雙色球的電腦選號法,兩色球各15號?)
3.刪除隊伍中的第九位list.pop(8)
4.用if搭配list.count檢查剩餘基督是否為15,若True則print
==
試著參考了前面幾個練習學到的東東,結果算是完成了一個堪用的

def line_up(people=30):
    line=[]
    for _ in range(people//2):
        line.append('A')
        line.append('B')
    line=sample(line,30)
    return line
def resecute(line):
    kill=True
    result=line[:]
    while kill:
        result.pop(8)
        if len(result)==15:
            kill=False
        number=result.count('A')
    return number
def yep():
    LordWin=True
    last_stand_christian=0
    while LordWin:
        last_stand_christian=resecute(line_up())
        if last_stand_christian==14:
            LordWin=False
            print(line_up())
yep()

說是堪用的原因是我run了很多次才找到剩餘基督徒=14的答案,15還沒run成功過
這或許代表
1.我的電腦太爛
2.程式執行了太多重複的東西,或許可以進行簡化
看答案

def main():
    persons = [True] * 30 #在列表中建立30個布林=30個活人
    counter, index, number = 0, 0, 0 #擊殺數、死亡宣告器/、9計數器
    while counter < 15: #擊殺數小於15前會執行下列程式碼:
        if persons[index]: #若人未死(index=True)執行以下程式碼:
            number += 1 #計數器+1
            if number == 9: #若計數器達9執行以下程式碼:
                persons[index] = False #宣判死亡
                counter += 1 #擊殺數+1
                number = 0 #計數器歸零
        index += 1 #下面一位~
        index %= 30 #這邊不大懂
    for person in persons:
        print('基' if person else '非', end='')


if __name__ == '__main__':
    main()

index %= 30 #這邊不大懂為何要這樣做,不過在我改了一下他的數字後出現的是index out of range,所以或許這就是讓程式簡潔的關鍵
總之目前觀察到,我的邏輯是:
產生兩人隊伍_隨機組合_九步一殺_找出完美的組合
老師的邏輯是:
產生活人隊伍_九步1殺_標記剩餘的組合
重構一波

def line_up(people=30):
    line=[True]*people
    return line
def kill(line):
    index,count,kill=0,0,0
    count=line.count(False)
    while count<15:
        if line[index]:
            kill+=1
            if kill==9:
                line[index]=False
                kill=0
    return last_line
def assign(last_line):
    print('C'if True else'X')
assign(kill(line_up))

目前遇到的問題是'function' object has no attribute 'count'
下班再繼續~
====
結果下了個班以後有一堆事情,弄一弄就過了四天才能重拾程式碼,沒有固定時間學習的壞處就在這,不過固定時間學習的壞處就是不太能接受突發的狀況呢
重看了一遍我四天前寫的東西,感覺錯的點不在於我怎麼寫,而是一開始的分析:
邏輯上雖然縮小了整個問題的隊伍規模,但我如果把整個流程抽出來應該不難發現除了「排隊把可能性一個一個試過再挑出需要的」以外還有更簡單的作法
沒有把整件事情的邏輯都整理好就急著開始寫是這次的問題
後面看了答案之後在重構時,因為不想把老師的答案複製貼上,於是嘗試保留自己原先設想的部分,目標想以我的東西為基礎像是把整個流程分為三個function加上老師的概念來寫
但是又遇到新的問題,我上面有記錄下來
====
先說結論:
因為學習進度實在落後到有點多,所以我打算把這題先解析到這裡先進行下一章的學習
感謝前一篇中有位前輩在文章的回應中表示看了答案之後要不把自己的程式碼進行重構永遠不會變成經驗,這句話從側面點醒了我
原本學習的方式是筆直的前進,遇到難題就一直停在那邊想,雖然這件事情可以很好的培養耐心,但隨著難度加大,停留的時間越來越久,這種學習方式會產生的壞處就越顯而易見,其中最明顯的莫過於對程式的手感越來越生疏了。
原本死不看答案的原因就是怕看了答案會失去這次進步的機會,但前輩的話讓我明白就算看了答案不重構就還是不會。
也就是說其實我可以在遇到任何程式就直接解析一波,這樣很容易就能知道自己是不會還是忘記,再針對發現的問題去做下一步的學習/補強
希望這個發現能讓我掌握最佳的學習節奏,補強我在自學最缺乏的--安排進度的能力ㄋ


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言