編碼也快樂:兩隻水壺Scheme程式
編碼任務
假設有一個池塘,裡面有無窮多的水。現有2個空水壺,容積分別為5升和6升。如何只用這2個水壺從池塘裡取得3升的水(最後,這三升水,在其中一個壺裡)。
分析
顯然,水壺的容積必須為正數,目標水量必須非負,且不能超過容量大的那個水壺的容積。如果目標水量及兩個水壺的容積分別用 t、a、b 來表示,則必須有 a > 0, b > 0, 0 ≤ t ≤ max(a, b)。另外,t、a、b 三個量必須可公度,它們可以是有理數。如果都乘以分母的最小公倍數,即可化為整數。因此,我們僅需考慮 t、a、b 都是整數的情形。
令 d 是 a 和 b 的最大公約數。由於 a 和 b 都是 d 的倍數,如果 t 不是 d 的倍數,把 d 升水考慮為 1 份水,可知原題無解。另一方面,數論中有一個定理1,方程 ax + by = t 有整數解 x, y,當且僅當 t 是 d 的倍數。因此,如果 t 是 d 的倍數,按照歐幾里得演算法的步驟,原題可解。
- 參見“最大公約數與歐幾里得演算法”中的定理25。
Scheme
Lisp 是第一個函式式程式設計語言,已經使用了半個世紀。在現存的活語言裡,只有 Fortran 比它的壽命更長些。這兩種語言都支援著一些重要領域中的程式設計需要,Fortran 用於科學與工程計算,Lisp 用於人工智慧。這兩個領域現在仍然很重要,它們的程式設計師都如此傾心於這兩種語言,因此,Lisp 和 Fortran 都還可能繼續生存至少半個世紀。
Scheme 是 Lisp 兩種主要的方言之一(另一種為 Common Lisp)。它的精簡性與優雅的語法廣受電腦科學教育者以及語言設計學者的歡迎,並經常被用於基礎電腦科學教育上。麻省理工學院與其他院校曾利用 Scheme 教授入門課程,著名的入門教材《計算機程式的構造和解釋》(SICP,或稱“魔法書”)就是利用 Scheme 來解釋程式設計。
我這裡用的是 MIT/GNU Scheme,可到官網 http://www.gnu.org/software/mit-scheme 下載 GNU/Linux、OS X 和 Windows 等平臺的安裝包。
兩隻水壺程式
言歸正傳,解釋一下我的 Scheme 程式:
主函式 pot 的三個引數 t a b 分別是目標水量及兩個壺的容積。
函式 solve 用於解題,引數 p q 是兩個壺的當前水量。
(巢狀函式 x,計算從 A 壺最多能往 B 壺倒多少水)
函式 solve 首先列印當前水量;
如果當前水量等於目標水量,成功;
否則,如果 A 壺空,則裝滿它;
否則,如果 B 壺滿,則清空它;
否則,儘可能地從 A 壺往 B 壺倒水;
遞迴地呼叫以上步驟即可完成解題。
主函式 pot 首先判斷輸入的引數 t a b 是否超出允許範圍;
接著根據目標水量是不是兩個壺的容積的最大公約數的倍數判斷是否有解;
現在可以置兩個壺的初始水量為零,呼叫函式 solve 0 0 開始解題。
(define (pot t a b)
(define (solve p q)
(define x (min p (- b q)))
(display " -> ") (display p) (display " ") (display q) (newline)
(cond ((or (= p t) (= q t)) (display "------- OK! ------"))
((= p 0) (display "Fill A full") (solve a q))
((= q b) (display "Empty pot B") (solve p 0))
(else (display "Pour A to B") (solve (- p x) (+ q x)))))
(cond ((or(< a 1)(< b 1)(< t 0)(> t (max a b))) (display "Arg out of range"))
((not (= (remainder t (gcd a b)) 0)) (display "No solve!"))
(else (display "Start with ") (solve 0 0))))
以目標水量 3,兩個壺的容積分別為 5 和 6 為引數呼叫 pot 的結果如下:
(pot 3 5 6)
Start with -> 0 0
Fill A full -> 5 0
Pour A to B -> 0 5
Fill A full -> 5 5
Pour A to B -> 4 6
Empty pot B -> 4 0
Pour A to B -> 0 4
Fill A full -> 5 4
Pour A to B -> 3 6
------- OK! ------
美國人的火箭發射系統
上世紀七十年代,前蘇聯情報機構克格勃對美國太空技術軟體發生了濃厚的興趣,派遣了各種各樣的間諜蒐集任何可能的相關資訊。
一天下午,一個間諜氣喘吁吁的回到總部,手裡拿著一張紙,興奮的對著他的上司叫喊,“同志!同志!美國人的火箭發射系統是用 Lisp 語言編寫的!”
長官很疑惑:“你怎麼知道的?”
“我闖進了他們的研究室,從他們的電傳機上偷了一張紙!這上面不是整個程式,只是最後一頁,記錄了程式的結束部分!你自己看!!!”
長官看著這張紙笑了:
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
傾情推薦
相關文章
- 編碼也快樂:兩隻水壺F#程式
- 編碼也快樂:兩隻水壺C#程式C#
- 程式設計也快樂: 兩隻水壺 C程式碼 搜尋版程式設計C程式
- 編碼也快樂:兩水壺的故事之JS程式JS
- 兩隻水壺 c++版C++
- 編碼也快樂:取得3升水C#版C#
- 編碼也快樂活動:撲克牌排序排序
- 編碼也快樂!撲克牌排序JAVA排序Java
- 編碼也快樂:撲克牌排序 - Python排序Python
- 編碼也快樂活動:撲克牌排序(JavaScript)排序JavaScript
- 撲克牌排序(JS版) 編碼也快樂!排序JS
- 程式設計也快樂第3期SQL程式碼程式設計SQL
- 買這家公司的遊戲,還不如買兩瓶快樂水?遊戲
- Tita智慧濾水壺:全家健康飲水靠它就夠了
- 程式設計也快樂第三期解答(四)程式設計
- 程式設計也快樂第三期解答(三)程式設計
- 程式設計也快樂第三期解答(二)程式設計
- 程式設計也快樂第三期解答(一)程式設計
- scheme跳轉特殊字元編碼問題Scheme字元
- 編碼也快樂活動歡樂第二季 - 火熱滾燙的HTML5和CSS3大餐...HTMLCSSS3
- 不再做夢,快樂程式碼到此為止!
- 編譯和分發 Chez Scheme 應用程式編譯Scheme
- 程式設計師快樂器之JAVA程式碼生成工具程式設計師Java
- 程式設計師節快樂程式設計師
- (程式碼生成)JS寫的程式碼生成器-編碼也可以這麼爽..JS
- 米家新電水壺釋出:標準米家風格定價99元
- 小米米家恆溫電水壺釋出:199元帶回家
- 《快樂碼農》第7期 嘗試在帳篷中寫程式碼
- NEON彙編比純C程式碼快17倍!C程式
- 22種程式語言新年快樂
- 使用Google Guava快樂程式設計GoGuava程式設計
- 程式猿1024節快樂
- 程式設計師的快樂生活程式設計師
- 快樂指南:程式設計師版程式設計師
- 《快樂碼農》第5期 大話程式設計師面試程式設計師面試
- 通達信兩隻喜鵲指標公式原始碼副圖指標公式原始碼
- 程式設計師快樂撩妹秀技術兩不誤(行政財務拆分篇)程式設計師
- 快樂數