2021年4月15日 星期四

Python 河內塔 (漢諾塔)

河內塔(中國大陸:漢諾塔,香港:河內塔)是根據一個傳說形成的數學問題

有三根杆子A,B,C。A杆上有 N 個 (N>1) 穿孔圓盤,盤的尺寸由下到上依次變小。要求按下列規則將所有圓盤移至 C 杆:

A.每次只能移動一個圓盤;
B.大盤不能疊在小盤上面。

提示:可將圓盤臨時置於 B 杆,也可將從 A 杆移出的圓盤重新移回 A 杆,但都必須遵循上述兩條規則。

先用迴圈來寫,但寫得不好,有些違反 "每次只能移動一個圓盤" ,下次再修改

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
start_list=list()
Buffer_list=list()
End_list=list()

def print_list():
    print("START  : ",start_list)
    print("BUFFER : ",Buffer_list)
    print("END    : ",End_list)
    print("=================================")

Level_num=int(input("請輸入Hanoi塔層數 (>2) : "))
End_num=0

for i in range(1,Level_num+1):
    start_list.append(i)

print (start_list)
if len(Buffer_list)==0:
    Buffer_list.append(start_list[0])
    del start_list[0]
if len(End_list)==0:    
    End_list.append(start_list[0])
    del start_list[0]
print_list()

while True:
    if len(Buffer_list)>0:
        if Buffer_list[0]< End_list[0]:
            End_list.insert(0,Buffer_list[0])
            del Buffer_list[0]
        print_list()
    if len(End_list)>=2 and len(Buffer_list)==0:
        for x in range(len(End_list)):
            Buffer_list.append(End_list[x])
        del End_list[:]
    print_list()
    if len(End_list)==0:    
        End_list.append(start_list[0])
        del start_list[0]
    print_list()
    if len(End_list)>0 and Buffer_list[-1]<End_list[0]:
        for x in range(len(Buffer_list)):
            End_list.insert(x,Buffer_list[x])
        del Buffer_list[:]
    print_list()

    End_num=len(End_list)
    if End_num==Level_num:
        break

再來用遞迴寫,參考一些作法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
start_list=list()
Buffer_list=list()
End_list=list()

def print_list():
    print("START  : ",start_list)
    print("BUFFER : ",Buffer_list)
    print("END    : ",End_list)
    print("=================================")

def hanoi(n,x,y,z):
    if n==1 : 
        if len(z)==0: z.append(x[0])
        else:z.insert(0,x[0])
        del x[0]
        print_list()
    else:
        hanoi(n-1,x,z,y)
        z.insert(0,x[0])
        del x[0]
        print_list()
        hanoi(n-1,y,x,z)

Level_num=int(input("請輸入Hanoi塔層數 (>2) : "))

for i in range(1,Level_num+1):
    start_list.append(i)
print_list()

hanoi(Level_num,start_list,Buffer_list,End_list)

執行結果:


請輸入Hanoi塔層數 (>2) : 3
START  :  [1, 2, 3]
BUFFER :  []
END    :  []
=================================
START  :  [2, 3]
BUFFER :  []
END    :  [1]
=================================
START  :  [3]
BUFFER :  [2]
END    :  [1]
=================================
START  :  [3]
BUFFER :  [1, 2]
END    :  []
=================================
START  :  []
BUFFER :  [1, 2]
END    :  [3]
=================================
START  :  [1]
BUFFER :  [2]
END    :  [3]
=================================
START  :  [1]
BUFFER :  []
END    :  [2, 3]
=================================
START  :  []
BUFFER :  []
END    :  [1, 2, 3]
=================================



2021年3月27日 星期六

Python 測驗題(四)

 第十題

這是三個題目寫在一起,題目如下

A. 輸入一個整數 n,求出從 1 ~ n 所有可以被 3 整除及又可以被 7 整除所有的數字的總和的程式
B. 輸入一個整數 n,撰寫一個程式,可以計算從 1 到 n 的整數中,所有奇數的相乘積並印出
C. 現在有 n 個蛋,一打是 12 個,請設計 python 程式, 輸入一個整數 n, 計算此 n 個蛋是幾打,還剩下幾個蛋

程式如下

val_num=list()
val_odd=list()

#輸入一個整數 n,求出從 1 ~ n 所有可以被 3 整除及又可以被 7 整除所有的數字的總和的程式。

val=int(input("請輸入一個正整數 :"))

for i in range (2,val+1):
    if (i%3) ==0 and (i%7)==0:
        val_num.append(i)

print("可以被 3 整除及又可以被 7 整除,所有的數字的總和 : ",sum(val_num))

print("============================================================")

#輸入一個整數 n,撰寫一個程式,可以計算從 1 到 n 的整數中,所有奇數的相乘積並印出。

val=int(input("請輸入一個正整數 :"))

for i in range(1,val+1,2):
    val_odd.append(i)

odd_a=1
x=len(val_odd)
for i in range(x):
    odd_a=odd_a*val_odd[i]

print("所有奇數的相乘積 : ",odd_a)

print("============================================================")

#現在有 n 個蛋,一打是 12 個,請設計 python 程式, 輸入一個整數 n, 計算此 n 個蛋是幾打,還剩下幾個蛋。

val=int(input("請輸入有幾顆蛋 :"))
egg_a=val%12
egg_b=(val-egg_a)/12

print("可以分 ", egg_b," 打,剩下 ", egg_a , "顆蛋")

輸出結果

請輸入一個正整數 :42
可以被 3 整除及又可以被 7 整除,所有的數字的總和 :  63      
============================================================
請輸入一個正整數 :12
所有奇數的相乘積 :  10395
============================================================
請輸入有幾顆蛋 :87
可以分  7.0  ,剩下  3 顆蛋

第十一題

請使用迴圈敘述撰寫一程式,讓使用者輸入一個正整數(<100),然後以三角形的方式依序輸出此數的階乘結果。
* 提示:輸出欄寬為 4,且需靠右對齊。

程式如下

val=int(input("請輸入一個正整數(<100) :"))

for i in range(0,val+1):
    for j in range(1,i+1):
        print("{:>4d}".format(j*i),end='')
    print("")

輸出結果

請輸入一個正整數(<100) :10

   1
   2   4
   3   6   9
   4   8  12  16
   5  10  15  20  25
   6  12  18  24  30  36
   7  14  21  28  35  42  49
   8  16  24  32  40  48  56  64        
   9  18  27  36  45  54  63  72  81    
  10  20  30  40  50  60  70  80  90 100


2021年3月26日 星期五

Python 測驗題(三)

 第七題

請撰寫一程式,輸入並建立兩組數組,各以-9999為結束點(數組中不包含-9999)。將此兩數組合併並從小到大排序之,顯示排序前的數組和排序後的串列。

主要是 陣列的合併 List = List1+List2

程式如下 ,這題寫了二種方式

listA=list()
listB=list()
           
print("建立第一個列表")

while True:     #-9999 結束
    val=int(input("請輸入一個數字 (-9999結束輸入) :"))
    if val==-9999:
        break
    else:
        listA.append(val)

print("建立第二個列表")

while True:     #-9999 結束
    val=int(input("請輸入一個數字 (-9999結束輸入) :"))
    if val==-9999:
        break
    else:
        listB.append(val)

listC=listA + listB

print("原始數列 : " , listC)
x=sorted(listC)
print("從小到大排序 :" ,x)

仔細看,有些程式碼重複了,可以把重複的程式獨立出來,寫成副程式 Function ,如下

listA=list()
listB=list()

def list_Append(listX):
    while True:     #-9999 結束
        val=int(input("請輸入一個數字 (-9999結束輸入) :"))
        if val==-9999:
            break
        else:
            listX.append(val)
    return listX             

print("建立第一個列表")
listA=list_Append(listA)

print("建立第二個列表")
listB=list_Append(listB)

listC=listA + listB

print("原始數列 : " , listC)
x=sorted(listC)
print("從小到大排序 :" ,x)

輸出如下

建立第一個列表
請輸入一個數字 (-9999結束輸入) :9
請輸入一個數字 (-9999結束輸入) :0
請輸入一個數字 (-9999結束輸入) :-1
請輸入一個數字 (-9999結束輸入) :3
請輸入一個數字 (-9999結束輸入) :8
請輸入一個數字 (-9999結束輸入) :-9999
建立第二個列表
請輸入一個數字 (-9999結束輸入) :28
請輸入一個數字 (-9999結束輸入) :16
請輸入一個數字 (-9999結束輸入) :39
請輸入一個數字 (-9999結束輸入) :56
請輸入一個數字 (-9999結束輸入) :78
請輸入一個數字 (-9999結束輸入) :88
請輸入一個數字 (-9999結束輸入) :-9999
原始數列 :  [9, 0, -1, 3, 8, 28, 16, 39, 56, 78, 88]   
從小到大排序 : [-1, 0, 3, 8, 9, 16, 28, 39, 56, 78, 88]

第八題

請撰寫一程式,要求使用者輸入一字串,顯示該字串每個字元的對應ASCII碼及其總和。
主要是字串字元的處理,放進陣列中去加總即可
ord(字元) : 轉換ASCII

程式如下

str_val=""
ascii_val=list()

str_val=input("請輸入一個字串: ")
x=len(str_val)
for i in range(x):
    y=ord(str_val[i])
    ascii_val.append(y)
    print("ASCII code for " , "'", str_val[i],"' is ", y )

print("每個字元ASCII碼的總和 :", sum(ascii_val))

輸出結果

請輸入一個字串: Kingdom
ASCII code for  ' K ' is  75 
ASCII code for  ' i ' is  105
ASCII code for  ' n ' is  110
ASCII code for  ' g ' is  103
ASCII code for  ' d ' is  100
ASCII code for  ' o ' is  111
ASCII code for  ' m ' is  109
每個字元ASCII碼的總和 : 713

第九題

請撰寫一程式,讀取read.txt的內容(內容為數字,以空白分隔)並將這些數字加總,接著再顯示檔案內容和加總的結果。檔案讀取完成後要關閉。

用 with open() as file 來開啟檔案

read.txt 內容存放如下,故意放進二行數據

1 2 3 99 54 36 97
10 20 30 40 50 60 70 80 90

程式如下

val=list()

with open("read.txt" , mode="r",encoding="utf-8") as file:
    for line in file:
        print (line.split())
        val=val+line.split()

sum_val = list(map(int, val))
print(sum(sum_val))

輸出結果

['1', '2', '3', '99', '54', '36', '97']
['10', '20', '30', '40', '50', '60', '70', '80', '90']
742


Python 測驗題(二)

第四題

請撰寫一程式,讓使用者輸入數字,輸入的動作直到輸入值為9999才結束,然後找出其最小值,並輸出最小值。

主要就是 先設定一個無窮迴圈,把輸入的數值放進陣列List 中,直到9999就跳出無窮迴圈

程式如下

value=list()

while True :
    val=int(input("請輸入一個正整數 (9999 結束輸入) :"))
    if val==9999 :
        value.append(val)
        break
    else:
        value.append(val)

print (len(value)," 個數值中,最小值是 ",min(value))

輸出結果

請輸入一個正整數 (9999 結束輸入) :29
請輸入一個正整數 (9999 結束輸入) :100
請輸入一個正整數 (9999 結束輸入) :948
請輸入一個正整數 (9999 結束輸入) :377
請輸入一個正整數 (9999 結束輸入) :-28
請輸入一個正整數 (9999 結束輸入) :0
請輸入一個正整數 (9999 結束輸入) :-388
請輸入一個正整數 (9999 結束輸入) :9999
8  個數值中,最小值是  -388

第五題

請撰寫一程式,將使用者輸入的兩個數字作為參數傳遞給一個名為compute(x, y)的函式,此函式將回傳x和y的乘積。

這題就不需解釋了,直接看程式

def compute(x,y):
    z=x*y
    return z

vala=int(input("請輸入一個正整數 :"))
valb=int(input("請輸入一個正整數 :"))

Value=compute(vala,valb)
print(Value)

輸出結果

請輸入一個正整數 :56
請輸入一個正整數 :11
616

第六題

請撰寫一程式,讓使用者輸入52張牌中的5張,計算並輸出其總和。提示:J、Q、K以及A分別代表11、12、13以及1。

1. 可以將牌的點數先存放在陣列 List 中
2. 判別 A , J , Q , K
3. 把輸入的點數轉成數字,存放在另一個陣列

程式如下

pok=("2","3","4","5","6","7","8","9","10","A","J","Q","K","a","j","q","k")
poksum=list()
i=0
while True:
    Str="請輸入第" + str(i+1) +"張牌 :"
    pok_val=input(Str)
    if (pok_val in pok):
        if pok_val=="A" or pok_val=="a":
            poksum.append(1)
        elif  pok_val=="J" or pok_val=="j":
            poksum.append(11)
        elif  pok_val=="Q" or pok_val=="q":
            poksum.append(12)
        elif  pok_val=="k" or pok_val=="K":
            poksum.append(13)
        else:
            poksum.append(int(pok_val))            
        i=i+1
    if i == 5 :
        break

print (len(poksum) , "張牌的點數總和是 : " , sum(poksum))

輸出結果

請輸入第1張牌 :5
請輸入第2張牌 :10
請輸入第3張牌 :k
請輸入第4張牌 :3
請輸入第5張牌 :a
5 張牌的點數總和是 :  32

Python 測驗題(一)

第一題

請撰寫一程式,輸入四個分別含有小數1到4位的浮點數,然後將這四個浮點數以欄寬為7、每列印兩個的方式,先列印向右靠齊,再列印向左靠齊,左右皆以直線|作為邊界。提示:輸出浮點數到小數點後第二位。

這題有點煩,格式需要轉來轉去,不熟悉還真的搞很久
程式如下

val_floatA=float(input("請輸入一個浮點數 :"))
val_floatB=float(input("請輸入一個浮點數 :"))
val_floatC=float(input("請輸入一個浮點數 :"))
val_floatD=float(input("請輸入一個浮點數 :"))

val_floatA='%.2f' % val_floatA
val_floatB='%.2f' % val_floatB
val_floatC='%.2f' % val_floatC
val_floatD='%.2f' % val_floatD

val_A=str(val_floatA)
val_B=str(val_floatB)
val_C=str(val_floatC)
val_D=str(val_floatD)

print("|" , val_A.rjust(7)+val_B.rjust(7),"|")
print("|" , val_C.rjust(7)+val_D.rjust(7),"|")

print("|" , val_A.ljust(7)+val_B.ljust(7),"|")
print("|" , val_C.ljust(7)+val_D.ljust(7),"|")

輸出結果

請輸入一個浮點數 :23.12
請輸入一個浮點數 :395.3
請輸入一個浮點數 :100.4617
請輸入一個浮點數 :564.329
|   23.12 395.30 |
|  100.46 564.33 |
| 23.12  395.30  |
| 100.46 564.33  |

更正,第一題下列的寫法,應該比較正確,不用轉來轉去

val_floatA=float(input("請輸入一個浮點數 :"))
val_floatB=float(input("請輸入一個浮點數 :"))
val_floatC=float(input("請輸入一個浮點數 :"))
val_floatD=float(input("請輸入一個浮點數 :"))

print("|{:>7.2f}{:>7.2f}|".format(val_floatA,val_floatB))
print("|{:>7.2f}{:>7.2f}|".format(val_floatC,val_floatD))

print("|{:<7.2f}{:<7.2f}|".format(val_floatA,val_floatB))
print("|{:<7.2f}{:<7.2f}|".format(val_floatC,val_floatD))

輸出結果

請輸入一個浮點數 :23.12
請輸入一個浮點數 :395.3
請輸入一個浮點數 :100.4617
請輸入一個浮點數 :564.329
|  23.12 395.30|
| 100.46 564.33|
|23.12  395.30 |
|100.46 564.33 |


第二題

請使用選擇敘述撰寫一程式,讓使用者輸入一個正整數,然後判斷它是3或5的倍數,若此數值同時為3與5的倍數,顯示【x is a multiple of 3 and 5.】;如此數值皆不屬於3或5的倍數,顯示【x is not a multiple of 3 or 5.】,將使用者輸入的數值代入x。

這題算簡單,就用if 來判別即可,另外多加一個判斷式

val=int(input("請輸入一個正整數 :"))

if (val%3) ==0 and (val%5) ==0:
    print(val , "is a multiple of 3 and 5.")
elif (val%5) ==0 :
    print(val , "is a multiple of 5.")
elif (val%3) ==0 :
    print(val , "is a multiple of 3.")
else:
    print("不是3 & 5 的倍數")

輸出結果

請輸入一個正整數 :15
15 is a multiple of 3 and 5.
請輸入一個正整數 :9
9 is a multiple of 3.
請輸入一個正整數 :31
不是3 & 5 的倍數

第三題

請使用迴圈敘述撰寫一程式,讓使用者輸入兩個正整數a、b(a < b),利用迴圈計算從a開始的偶數連加到b的總和。例如:輸入a=1、b=100,則輸出結果為2550(2 + 4 + ... + 100 = 2550)。

這題要小心,因為a 有可能一開始就是偶數或是奇數,必須要先判斷出來

程式如下

a,b=map(int,input("請輸入兩個正整數:").split())
sum=0
if a%2 ==0 :
    for x in range(a,b+1,2):
        sum=sum+x
    print (sum)
else:
    for x in range(a+1,b+1,2):
        sum=sum+x
    print (sum)   

a,b=map(int,input("請輸入兩個正整數:").split())

這行表示一次輸入兩個變數的值,用空白鍵分隔
這還少了一個判斷,就是 a , b 誰大誰小,就先定義第一個數字要比第二個數字小 (a < b )

輸出結果

請輸入兩個正整數:14 1144
327714

請輸入兩個正整數:3 11
28