簡介
本文中的所有程式碼都會使用 Python。
在他們的 #48in24 挑戰 中,Exercism 正在探索社群如何應對各種不同的程式設計挑戰。 「Hello, World!」是 Exercism 上最基礎的練習,被認為太簡單,不值得為它製作官方影片。 但我不太確定,而且我覺得,看看這個簡單練習有哪些更有趣的解法,應該會滿好玩的!
認識「Hello, World!」
「Hello, World!」大概是世界上最著名的程式。 幾乎每個學寫程式的人都至少寫過它一次。 它的簡單與友善的訊息,往往象徵著踏入程式設計美妙世界的第一步。
在 Exercism 上,你會拿到一個名為hello的函式,它會回傳「Goodbye, Mars!」。
def hello():
return 'Goodbye, Mars!'
你的任務是修改它,讓它改為回傳「Hello, World!」。
傳統解法
首先是最簡單的解法,也是 Exercism 希望你採用的做法。 只要把字串從「Goodbye, Mars!」簡單改成「Hello, World!」,我們就能安心地回傳它了!
def hello() -> str:
return 'Hello, World'
其他解法
我要用所有我能想到的各種方法來解這個練習。
為了敘事方便,我會把這個簡單的函式稱為「機器」,這台機器唯一的工作就是回傳「Hello, World!」這個問候語。
我們來看看這會走到哪裡吧……!
串接
這台機器已經知道其中幾個字,但似乎就是沒辦法把它們串、啊、呃、嗯,串在一起。
def hello() -> str:
words = ["Hello", " world!"]
return ",".join(words)
標題
這台機器今天電力有點不足,所有字詞都缺乏能量,沒有被好好地轉成大寫。
def hello() -> str:
words = "hello, world!"
return words.title()
反轉
這台機器不知怎麼地知道這個問候語,但看起來有點……反過來了。
def hello() -> str:
sdrow = "!dlroW ,olleH"
return sdrow[::-1]
注意:Reverse String 是 #48in24 挑戰的精選練習。記得去看看用不同程式語言完成它的各種解法!
切片切塊
也許這台機器該換機油了,正常的問候訊息似乎有點混亂。
def hello() -> str:
w = "Holld, Werlo!"
return f"{w[0]}{w[8]}{w[2:4]}{w[1]}{w[5:8]}{w[-2]}{w[-4:-2]}{w[4]}{w[-1]}"
柯里化
糟糕糟糕,機器有些零件進入維修模式了。 它忘記了問候訊息,現在只能一次接受一部分訊息。
def hello(greet: str):
def world(location: str) -> str:
return f"{greet}, {location}!"
return world
hello = hello("Hello")
hello("World")
ASCII
你不小心把檸檬水灑到機器上,現在它只會顯示這些奇怪的數字,而不是訊息中平常的字元。
def hello() -> str:
ascii = [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33]
return ''.join(chr(value) for value in ascii)
字典
你看了新聞,看到一則關於有人用 S.O.S 訊號獲救的報導。 「也許這台機器也該會處理摩斯電碼!」你這麼想,但不太確定為什麼。 它唯一的工作就是回傳問候訊息……
def hello(morse) -> str:
morse_code = {
"...." : "H",
"." : "e",
".-.." : "l",
"---" : "o",
"--..--": ",",
"/" : " ",
".--" : "W",
".-." : "r",
"-.." : "d",
"-.-.--": "!"
}
return "".join(morse_code[value] for value in morse.split())
print(hello(".... . .-.. .-.. --- --..-- / .-- --- .-. .-.. -.. -.-.--"))
函式風格
由於你現在的機器容易變化又容易損壞,你決定打造一台更小、但不可變且堅不可摧的機器,來做完全相同的事。 每當原本的機器故障或出狀況時,就改為啟動這台小機器。 等等,那我們何不從現在起就只用小機器呢……
def hi() -> str:
return "Hello, World!"
def hello() -> str:
return hi()
排列
一場強烈雷雨經過,你那台可憐又倒楣的機器被閃電擊中了。 它還是能開機,但現在行為變得很怪。 用來組成問候訊息的所有字元都還在,但它們的順序亂了,加上電路板受損,機器再也沒辦法把訊息的順序排對。 偏偏你運氣就是這麼好,你先前打造的那台超級可靠又堅不可摧的小機器,其實是可以被偷走的(沒錯,它不見了!)。 於是,你決定就讓你的老夥伴用各種可能的方式,把這些字母拼湊成正確的訊息。 畢竟也才 13 個字元,而這台機器記憶體很多。應該很快就能完成……
from itertools import permutations
def hello() -> str:
chars = ['H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!']
all_permutations = permutations(chars)
for perm in all_permutations:
if ("".join(perm) == "Hello, World!"):
return ''.join(perm)
搜尋
你決定把機器更新一下,讓它能用不同語言打招呼。 但它唯一的工作就是用英文說「Hello, World!」,於是它一頭霧水,決定下載無數種說「Hello, World!」的方法,每一種的大小寫和位置都略有不同。 這讓你很困惑,不確定該選哪一個,但至少它們都按照某種順序排列。 你得告訴機器正確的說法,它才能找到那個句子,恢復正常(也許吧)。
def hello(my_fav_phrase) -> str:
combinations = [
"HELLO, WORLD!",
# many many many items later,
"hello, world!"
]
lower = 0
upper = len(combinations)
while lower <= upper:
mid = (lower + upper) // 2
mid_val = combinations[mid]
if mid_val == my_fav_phrase:
return combinations[mid]
elif mid_val < my_fav_phrase:
lower = mid + 1
else:
high = mid - 1
return "Error: Can't find {my_fav_phrase}"
hello("Hello, World!")
你弟弟從頭到尾都在旁邊看,他問你為什麼不直接把這一團亂刪掉,然後把正確的句子給機器記住就好。 你沒有回答,只是瞪了他一眼。
有格調
你決定做個實驗,調整機器,讓它根據按下哪個按鈕而有不同的行為。
你本來想讓它隨性一點,改成說「Hi」,但身為一個有格調的人,你決定永遠只用hello方法,並把另一個用膠帶貼住。
你意識到自己還真是有不少時間可以搞這些東西……
class Greeting:
location = "World"
def __init__(self) -> None:
pass
def hello(self):
return f"Hello, {self.location}!"
def hi(self):
return f"Hi, {self.location}!"
salutation = Greeting()
salutation.hello()
遞迴
不知道為什麼,你覺得如果機器延遲一下、每次都要等 10 秒才回應,會很好笑。你弟弟再次質疑這個功能背後的邏輯,因為在他看來,用這台機器的只有你一個人。
import time
def hello(n=10):
if n == 0:
return "Hello, World!"
else:
time.sleep(1)
return hello(n-1)
隨機
突然有一天,你對一次又一次相同的問候感到厭倦,於是你決定讓它最後一次向你問好,然後讓這台機器永久退休,再也不碰它。 由於這台機器陪你同甘共苦了很長一段時間,你決定讓這場「朋友」之間的最後會面交給命運安排。 你最後一次啟動它,就讓它轉吧……
import random
def hello():
chars = list("Helo,Wrld!")
greeting = ""
while (greeting != "Hello, World!"):
greeting = "".join(random.choices(chars, k=13))
return greeting
結尾
這是一趟穿梭我腦海的瘋狂之旅。 我不確定它有沒有用,但絕對很有趣。
感謝你的閱讀,祝你寫程式愉快!