韓信點兵
曾慶潭 Ching-Tang Tseng
ilikeforth@gmail.com
Hamilton, New Zealand
16 August 2026
此前貼出過之百例中的第 81 例展示過一個韓信點兵的精簡程式,該程式採用暴力計算方式,只按問題直接強行計算,算到全部合乎指定條件後,得到解答。
本文中的程式則將問題建立成表格來計算,執行對答方式輸入問題,以敘述方式給出答案。
如果不能寫出不同的見解,就不該寫這篇文章,以免浪費讀者的寶貴時間。因為這是一個古老的中國算學技術,是西元前 200 年(韓信死於西元前 196 年)左右的問題,距今約 2200 年了。
中國秦朝末年,楚漢相爭,結果漢高祖劉邦打敗項羽取得天下,建立了漢朝。那時,有所謂的漢初三傑:指的就是韓信、張良、蕭河。韓信是個軍事奇才,曾經擔任軍隊的總司令,被任命為大將軍,協助漢高祖劉邦打天下,但不幸最後卻因被懷疑意圖謀反,而被蕭河及呂后(呂雉)騙入宮中,處死於長樂宮鐘室。
中國人無人不知、無人不曉『韓信點兵』的問題,卻罕有人能熟記,解這個問題的詳細理論依據,或將其學通後加以活用,或用來解出其他所有相關與類似的問題,這種情況,經過了兩千多年,甚至於一直到今天,依然如此。
據說,這個問題還曾經被納入高中的數學教材,可以想像,數學老師教起來必然辛苦,學生也學得痛苦。我不記得我在高中學習不定方程式(Indeterminate equations)時,必須學這項主題,就算學過,也早就忘了教材中曾經教過我,該如何按邏輯嚴格演繹以求得解答的詳細步驟了,反而是單一種逐步計算的方法,我終生都記得。
本文就專門只談論這種永遠記得住的解題方法,它確實就是各種方法中的一個好方法,還可以用來實現一個永遠可以存在、放諸四海而皆準的程式,要完成這樣的程式,也必須按邏輯嚴格演繹,設計出來的程式,此後才能古今中外都派得上用場。
科學月刊中現代數學名家的『韓信點兵』文章內,批評只有『答案』與『計算技巧』的堆積,無法顯現『數學的妙趣』,我百分之百同意這樣的觀點。但是,我反對為了培養『數學的妙趣』,而刻意略去能夠直接了當解得問題答案的最簡單方法。試想,如果無限多個『韓信點兵』式的問題堆積在眼前,您該怎麼辦?當精簡的『演算技巧』,與絕對需要的『答案』,您都遲遲難以獲得時,請問,您那來的『數學妙趣』?因此,我改而另覓它途,解決『韓信點兵』問題。把思考轉向電腦程式的邏輯嚴格演繹,而不是純粹數學的邏輯嚴格演繹,完成一個對談式萬用程式,包括落定美觀的排版所耗時間,大約只花兩小時,但是,『它』今後可以永遠有用。
這篇文章的目的,並不是想否定所有有關『韓信點兵』問題的理論分析教學,相反的,我仍鼓勵大家能學通以『韓信點兵』為例而安排出來的理論分析教材內容,畢竟,它相關於其他的數學學問,適合作為人人都熟悉的問題範例。
至於想實際解出這個問題的答案時,我個人覺得,現今,應該用電腦程式來解,而且,要將程式設計成對談式的萬用程式,至少,讓這個問題今後都能如此方便的解得答案。原因在於,一方面電腦幾乎是當今人人生活上必用的工具,那麼,電腦程式解題的方法,只要能合理解得正確的答案,就該認同這個方法,沒有理由硬要排除它。另一方面,則是現行電腦的執行速度與友善的操作環境,已經發展得相當完善了,適合作為解決這種問題的工具。我將電腦程式設定成逐步計算到達十萬次以上時,就當作可以落定題目為無解,使用已經 20 幾年高齡的電腦,也不過耗時僅約一秒。為何不用電腦程式來解問題?我堅決反對拒教電腦解題技術,不教就違反時代趨勢。
台灣發行的『科學月刊』,算得上是一本優良的普及性科學雜誌,我也愛讀,雜誌內容曾經出現過許多次談論有關『韓信點兵』的討論文章。
來自四面八方的數學專家,與各大學的許多教授,都曾為『韓信點兵』問題,寫過精闢的解題方法分析文章。如果您對求解此一問題之純粹理論性的分析有興趣,可以在網上搜索出不下百篇的文章來,國際上將這種問題命名為『中國剩餘定理』(Chinese Remainder Theorem)。為了要完成本文,我做過這樣的工作,快速瀏覽這些文章後,只有一種感覺,實在不想、也根本無法記下所有的邏輯推演步驟,今生再度碰到『韓信點兵』問題時,我還是只會逐步計算,使用規律增量式的逐個試算,最後絕對能得到正確的答案。
我都已經 75 歲了,記那些解題時必須要用到的定理、定律,與專門只用於解這種問題時,才需要使用的特別符號,有必要嗎?今天記了,大概明天就忘了,何苦來哉?
為『韓信點兵』問題而公開發表過的那些高明分析文章,仔細讀完之後,對我而言,充其量也只能讓我感到各文章作者言之有理,對必須解決實際問題的最基本要求,則實在幫助不大,更遑論憑此而能衍生出更高深的知識或技術了。換句話說,那些文章該看,至於能不能因此而領悟出連貫性知識或技術?那就得看個人對此一問題的進一步修行意願了,結果絕對因人而異,而願意前行者少。
最原始的『韓信點兵』問題,節錄如下:
兵不知其數,三三數之剩二,五五數之剩三,七七數之剩二,最少兵數應該是多少?
問題可以改寫成現代人使用之數學符號表示的聯立方程式,列示如下:
X = 3 * Q(1) + 2
X = 5 * Q(2) + 3
X = 7 * Q(3) + 2
這是一個只有三個已知關係的數學聯立方程式,卻要求解四個未知變數X、Q(1)、Q(2)、Q(3)。因為還差一個已知數學關係式,所以使這種問題被歸納入不定方程式的範疇。解答必須為整數的隱含要求,是代表兵士不得為半個人,或 3.1416 個人。
為了本文隨後表示上的方便,此處刻意引用『科學月刊』中,數學專家所使用的更精簡表示符號,以 S(N|R) 來表示問題,它代表 S 以 N 除之餘 R ,S 代表這種所有數字的集合,上列三個式子因此而得以進一步簡化表示成:
S(3|2) , S(5|3) , S(7|2)
直接逐步演算的方法為:
(1) 先找出條件中最大除數的那一項條件,以此數作為整個演算的基底數字。
在上列原始問題中為 7
(2) 設定一個計數器,令其從 1 開始計數,然後算出第一個可能符合條件的數字。
在上例中為 7*1+2=9
(3) 用(2)中得到的數字,去核算並判斷是否亦符合其他條件。
在上例中, 9/3=3 餘 0,9/5=1 餘 4 ,結果與原已知條件均不符合
(4) 回到(2)中將計數器值加 1 ,繼續(3)的核算,直到滿足所有條件為止,便可得到一個首先能夠獲得的答案。
在上例中,當計數器為 3 時, 7*3+2=23,23/3=7 餘 2 , 23/5=4 餘 3,符合要求,因此, 23 就是一個首先獲得的答案。
故事書上說,漢高祖劉邦聽不懂韓信的兵數描述,轉問張良,張良卻回話說:『兵數無法算,不可數。』
這樣的回答不對,方法就像上述這麼簡單,算 3 次後就可以得到一個核心基本根據數字,數學專業術語稱作『特解』,接下來要形成『通解』時,答案就是特解加上任意一個正整數乘上所有已知條件中的除數,在上例中為:
23 + N * ( 3 * 5 * 7 ) = 23 + N * 105 其中 N = 0, 1, 2, .....
這就是全部求解『韓信點兵』問題的逐步計算法,我相信,任何人看過上述解題方法的敘述之後,都能終身記得,都能終身使用,我的程式也就是根據這麼簡單的方法設計而成的。
通常我們求解一個數學問題時,首先要確定問題的答案是否『存在』(Exist)?上例中求得的23,表示答案確實存在,它就可以被確定是問題的一個特別解答,簡稱『特解』(Particular solution)。接下來要確定問題的答案是否為『唯一』(Unique)?經過仔細研究後,我們發現這種問題的解答不是唯一的,其特解23加上所有除數相乘後再乘上任意一個正整數,也都是問題的答案,因此,我們必須將所有的解答以適當的數學式子表示出來,以形成這個問題全部的通盤解答,簡稱『通解』(General solution)。數學理論中解答的『存在』與『唯一』性質,對應到解答的『特解』與『通解』,這個『韓信點兵』問題的通解,僅只是由簡單的乘法來形成,沒有其他任何技巧,因此,本文只討論問題的特解,程式中也不計算出簡單的通解,特此聲明。
由此看來,下一次考試碰到這樣的問題時,別再依靠那些無法終身記得的分析式演繹算法了,我能確定大多數人,僅能暫時性的理解分析演繹法,如果背下方法,考完就忘了,那又何須浪費時間去背記?將這些用來理解與背記所需的時間,改用來思考解決其他的學習問題,可能比較有意義。通常,上述計數器只須計數幾次,答案就可以獲得,因為考題所給的除數都不會太大,經常是個位數,已知條件也不會太多,一般就只有二或三個,取一張計算紙,列個表,快速心算後在每一列後面做個記號,很快就會有結果,如果嫌計算冗長,影響求解其他問題,那麼,這一題留到最後才解。
平時呢?您也不必怕我這樣強調性的教您如此求解問題會害了您,就根據上述逐步演算法,我寫成了永遠都能使用的對談式萬用程式,列示於本文內,使用時,可以在電腦開機後,只操作滑鼠點選三、四次,就有一個我設計而命名為 MAIN 的指令可以直接使用。好好的使用,它就能幫助您一天內解出幾千幾百個『韓信點兵』問題。碰到子女問您同樣的問題時,就算您不懂韓信如何點兵,這個對談程式會協助您,給予您滿意的答案,讓全家人皆大歡喜,然後,您就有信心告訴子女,應該好好學 FORTH 程式語言, FORTH 能設計出所有的程式。
我原本全部使用中文設計出這個程式,完成之後,考慮本文可以供給全世界的人參考使用,於是又將一般程式部份改成了英文,如此一來,也能供給慣於使用其他程式語言者,參考後模仿設計。
我瀏覽過網路,搜索能解『韓信點兵』問題的實際可用程式,大部份都是用 C 或 Python 程式語言寫的,由於 C 不方便用來設計立即對談式(Real time interactive)程式,因此,那些程式都只能解單一個韓信 2200 年前提出來的最原始問題,我用心算都可以比發展那樣的程式還快速的得到答案,所以那些程式沒有價值。
時代不同了,現代電腦的記憶體用量與執行速度,在用來解決這種問題而必須設計程式時,已經不用強調要節省記憶體空間與程式執行效率的問題。相反的,為了讓大多數人看過程式之後,能夠一目了然,我將程式設計成不在乎多執行了一些步驟,要用到的變數宣告量,也不用斤斤計較到要強調共用而節省。程式可執行出合理範圍內的答案,韓信不會有億萬大軍,解放軍再多,也只能論及幾百萬,這是一個兼顧了實際情況的程式。
採用對談式程式語言(如 FORTH )來設計這種程式,比採用編譯式程式語言(如 C )要好,使用方便且具彈性。我的程式中雖然暫時只規劃了可以輸入最多十組已知條件,要變通時,只需修改這個設定,但當已知條件多於十個以上時,程式改成輸入數據預置於檔案程式內的方式會比較好,可以防止一鍵敲錯而滿盤皆輸必須重來的困擾。這個程式是透通的, FORTH 是必須使用模組化格式設計程式的語言,想改寫程式,簡單之至,這就是 FORTH 。
七十年前,我們唸小學高年級時,每天幾乎都要習作 50 題當年『武明算術』內的習題,我不曾不交作業,學習方面只是認真但不聰明,可是這些學習方式,影響了我的一生,這樣的學習過程,可能是決定了我能否快速設計出電腦程式來解決問題的關鍵因素,我的小學老師是內壢國民小學的范金櫻老師,能有現在的能力,該感謝我的老師。
今天,此處列示的這個有用程式,它不僅只是代表了我寫成一個實用的程式,而是代表了我設計出一套永遠都容易建立的可對談式數學計算系統,然後讓大家可以很方便的設計程式,來解決所有的數學計算問題。截至目前為止,全世界尚無人能比,而這個系統還要發展。系統並非完全由我個人隻身獨立發展而成,我善用組合能力,組合了許多名家的長處來創造出系統,也因此而令其性能傑出,也因此而令系統隨時都還能繼續發展。
我出身軍人世家,自己也是被國軍淘汰下來的職業軍人,俗話說:『好鐵不打釘,好漢不當兵』,這句俗話是錯的,全世界不是軍人的人,此前還沒有人有能力,像我這個出身為軍人的人,設計出這麼方便且能夠處理許多問題的 ABC FORTH 數學計算系統,而我卻曾經是個『兵』。軍中的同袍,也請不要妄自菲薄,平時就該努力充實自己,設法接受我的這個 ABC FORTH 數學計算系統。戰時,軍方需要快速且大量的軍事作業研究(Operation research)來提供制敵的先機,其中許多問題需要大量的數學計算。目前,全世界還找不到像 ABC FORTH 那麼方便的系統,可以立即執行,可以對談式操作,專門用來處理數學計算,能夠快速處理這種『韓信點兵』式的問題。善用這樣的系統,在技術上就可以勝過一個韓信總司令,我不會像韓信那樣,將秘笈祖傳起來,下列就列示一個祕笈。
接下來,我先以前述『科學月刊』中最佳的問題表示符號,列示十二個曾經被提出來當範例的『韓信點兵』典型問題,供作程式測試之用,接著列示我所設計的程式。最後,我將程式載入 ABC FORTH 系統,直接操作系統,求解這十二個問題,執行的結果當然都是正確的,全部顯示在畫面上。再操作滑鼠,選定執行結果所產生的整個畫面,令其反白、複製、再轉貼入此文,讓讀者能夠完完整整的看到整個結果。
如果您願意實際體會執行這個程式後,快速得到正確答案的感覺,所呈現出來的現象將會是:每當您輸入了 MAIN 指令後,就會有一個滿意的終結。不想再執行 MAIN 指令了,也可以改執行 CHECK 指令,去看一下程式內的資料內容,或者就輸入 SEE MAIN 兩個指令,看系統把我設計的程式編成甚麼模樣了?顯示出來的這些現象,係 FORTH 程式語言一旦執行起來之後,就會顯現作業系統的性能所致。這是 Win32Forth 系統的作者 Tom Zimmer ,在網路論壇上給全世界 FORTH 使用者的善意建議,我提供了全套應用實例,您請自己體會。
請注意問題(6)無解,程式執行後就顯示無解。
問題(1)就是歷史上韓信提出來的第一個問題,它再簡單,程式也要能解。
問題(9)的答案比較特別,是除數全乘起來以後再除以2,程式也毫不含糊的快速顯示正確的執行結果。
現任學校的老師,如果想要隨便出幾個題目來考學生,利用這個程式,隨便輸入一些組合條件,就能先行得到答案,這些條件,就能當作別人從未出過的考題來考學生。
學生只要肯學 FORTH ,就能利用這個程式來對付老師的刁難。
一天之內,您想解出成千上萬個這種問題的答案,怎麼沒有可能?
總而言之,這個程式是方便而萬用的。
我則能擔保,永遠都有能夠執行這個程式的系統存在世上。
●十二個典型的問題為:
(1) S(3|2) , S(5|3) , S(7|2)
(2) S(7|1) , S(8|2) , S(9|3)
(3) S(11|3) , S(12|2) , S(13|1)
(4) S(2|1) , S(5|2) , S(7|3) , S(9|4)
(5) S(5|0) , S(6|1)
(6) S(12|5) , S(18|13)
(7) S(12|5) , S(18|17)
(8) S(15|7) , S(21|13) , S(10|2)
(9) S(11|1) , S(13|2) , S(15|3) , S(17|4) , S(19|5)
(10) S(3|1) , S(5|2) , S(7|4)
(11) S(8|1) , S(7|1) , S(5|2)
(12) S(7|3) , S(11|5) , S(13|8)
●程式及執行結果列示如下: