說起來已將近三十年了,那時我還隻有八歲,常常隨著我的祖父去會他的老友。有一次到一個小鹽商家去,他一見我們祖孫倆走到攤頭,一邊拉長板凳,一邊向祖父說:
——請坐,請坐,好福氣,四孫少爺這般大了。
——什麽福啊!奔波勞碌的命!
——哪裏,哪裏,四孫少爺已經上學了吧?
——不要這般叫,孩子們——今年已隨著哥哥進學校了,在屋裏淘氣得很,還是去找個管頭好。
說完,祖父微笑著撫摩我的頭,鹽老板和他說了一些古話,不知怎地,突然卻轉到了我的身上:
——在學校裏念些什麽書?
——國文、算術……我這樣回答。
——還學算嗎?好,給你算一個題,算得出,請你吃晚飯。
這使我有點兒奇怪,心裏猜不透他是叫我算乘法還是除法。我有些驚恐,怕他叫我算四則問題,我目不轉睛地看著他,他不慌不忙地說了出來:
——三個三個地數剩兩個,五個五個地數剩三個,七個七個地數也剩兩個,你算是幾個?
我一聽心裏非常高興,暗地裏還有點兒驕傲:“這樣的題目,哪個不會算!”這時我正好學完公倍數、公約數,而且不久前還算過這樣一個題目:“某數以三除之餘二,以四除之餘三,以五除之餘四,以六除之餘五,問某數最小是多少?”
我把這兩個題目看成一樣的,它們都是用幾個數去除一個數全除不盡。這第二個題的算法我記得十分清楚,所以我覺得很有把握。不但這樣,而且我覺得這位老板的題目有些不通,他隻問我一個最小的答數。當我在肚裏這樣尋思的時候,祖父便問道:
——算得出嗎?
——算得出,不隻一個答數。
我這樣回答以後,那位老板就恭維起我來了,對著祖父說:
——真好福氣!一想就想出來了,將來一定比大老爺還強。
祖父又是一陣客氣,然後對著我說:
——你說一個答數看。
我所算過的題,是先求出三,四,五,六四個數的最小公倍數“六十”,然後減去“一”得“五十九”。我於是依樣先求三、五、七三個數的最小公倍數,心裏暗想著“三五一十五,七五三十五,一百零五”。再就是要減去一個數了。我算過的題因為“以三除之餘二”是差個一(3-2=1)就除盡,所以要減去“一”。現在“三個三個地數剩兩個”正是一樣,也隻要減去“一”,所以我就從一百零五當中減去一,而立刻回答道:
——最小的一個數是一百零四,還有二百零九(104+105=209)也是。
這時,我在幼稚的心裏感到得意和快樂,我期望著老板的誇獎。豈知出乎我的意料!他說:
——一百零四,五個五個地數剩的是四個,不是三個。
這我怎麽沒想到呢?於是我想,應當從一百零五當中減去二(5-3=2),我就說:
——一百零三。
——三個三個地數隻剩一了。
我窘極了,居然遭遇到了這麽大的失敗!在我小時學數學,所遇到的窘迫,這是最大的兩次當中的一次,我覺得在人的麵前失敗,非常害羞。我記得很清楚,我一隻手扯著衣角,一隻手捏緊拳頭,臉上如火燒一般,低著頭,盡管在心裏轉念頭,把我所算過的題目都想到。但是徒然,和它相像的一個也沒有了。我後來下定決心,膽大地說:
——恐怕題目出錯了吧!
然而得到的是一個使我更加窘迫的回答:
——不錯的。
連我的祖父也這樣說。
急中生智,我居然找到了一條新路,我想三個去除剩兩個,五個去除剩三個,我可以先找三個去除剩兩個的一些數,再一個一個地拿五去除來試。這真是一條光明的路,第一個我想到的是“五”,這自然不對,用五去除並沒有剩的。接著想到的是“八”,正好用三去除剩二,用五去除剩三。我真喜出望外:
——八!
——還是不對,七個七個地數,隻剩一個。
這真叫我走投無路了!那天的晚飯雖然仍是那位老板留我們吃,但當祖父答應留在那裏的時候,我非常難過,眼巴巴地望著他,希望他能領我回家,我真是臉上熱一陣冷一陣的,哪兒有心思吃飯!我想得頭都脹了,總想不出答案。羞愧、氣悶,因而還有些惱怒,滿心充塞著這些滋味沒精打采地在夜裏跟隨祖父回家。我的祖父對我很慈愛,但督責也很嚴,他在外麵雖不曾向我說什麽,一到家裏,他就開始教訓我了:
——讀書要用心!……在別人的麵前不好誇口!……“寧在人前全不會,勿在人前會不全!”小小年紀曉得些什麽?別人問到就說不知道好了……
這時他的臉上嚴肅中還帶有幾分生氣的神情。他教訓我時,我的母親、嬸母、哥哥都在旁邊,後來他慢慢地將我的遭遇說給他們聽,我的哥哥聽他說完了題目便脫口而出:
——二十三。
我非常不服氣:
——別人告訴過你的!
——還這樣不上進。
祖父真生氣了。
從那夜起,一直兩三天,我見到祖父就怕,我任何時候都在想這個題的算法,弄得吃、玩、睡都惝怳。最終還是我的哥哥將算這個題目的秘訣告訴了我,而且說,這叫“韓信點兵”。雖然我對這道題十分懊喪,卻慢慢地把它拋到了腦後。
現在想起來,那次遭遇以及祖父所給我的教訓實在是我的年齡不應當承受的。不過這樣的硬教育,對於我也有很大的功勞,我對於數學能有較濃厚的興趣,一半固然由於別人所給的積極的鼓勵;而一半也由於這些我所承受不起的遭遇和教訓。數學有時會叫人頭痛,然而經過一次頭痛,總有一次進步。這次的遭遇,對於本問題,我自己雖是一無所得,但對於思索問題的途徑,確實得到了不少啟示。在當時,有些自以為有了理解的,雖也不免不切實際或錯誤,但畢竟增長了一些趣味和能力。因此我願以十二分的誠意,將這段經過敘述出來,以慰勉一部分和我有類似遭遇的讀者。
現在我們言歸正傳。
所謂“韓信點兵”,指的是那位鹽老板給我出的題目的算法。“韓信點兵”這個名詞雖是到了明時程大位的《算法統宗》才見到的。但這個問題在中國數學史上很有來曆,到了賣鹽老板都知道,也可以當得起“婦孺皆知”的榮譽了。
這題目最早見於《孫子算經》,《孫子算經》是什麽時候什麽人所作的書,現在雖然難以考證,大約是二千多年前的作品確實是不容懷疑的。在《孫子算經》上,這題目原是這樣的:“今有物不知數,三三數之,剩二;五五數之,剩三;七七數之,剩二,問物幾何?”
在原書中本歸在《大衍求一術》中,到了宋時,周密的書中卻有《鬼穀算》和《隔牆算》的名目,而楊輝又稱之為“剪管術”,在那時便有秦王暗點兵的俗名,大約韓信就是從秦王變來的,至於“明點”“暗點”本沒有多大關係。
原書上,跟著題目便有下麵的一段:
“答曰二十三。”
“術曰:三三數之剩二,置一百四十;五五數之剩三,置六十三;七七數之剩二,置三十。並之,得二百三十三,以二百一十減之,即得。”
“凡三三數之剩一,則置七十;五五數之剩一,則置二十一;七七數之剩一,則置一十五;一百六以上,以一百五減之,即得。”
後一小段可以說是這類題的基本算法,而前一小段是本問題的解答,用現在的式子寫出來便是:
照前麵的說法,自然是士大夫氣很重,也可以說是講義體,一般人當然很難明白,但到了周密的書中便有了詩歌形式的說明,那詩道:
“三歲孩兒七十稀,五留廿一事尤奇。
七度上元重相會,寒食清明便可知。”
這詩雖然容易記誦,但意義不明,而且說得也欠周到。到了程大位,它就改了麵目:
“三人同行七十稀,五樹梅花廿一枝。
七子團圓月正半,除百零五便得知。”
這詩流傳得非常廣,所以如賣鹽老板之流也都知道,而我的哥哥所告訴我的秘訣就是它。
是的,知道了它,這類的題目便可以機械地算了,將三除所得的餘數去乘七十,五除所得的餘數去乘二十一,七除所得的餘數去乘十五,再把這三項乘積相加。如所得的和比一百零五小,那便是所求的答數;不然,則減去一百零五的倍數,而得出比一百零五小的數來——這裏所要求的隻是一個最小的答案——例如三三數之剩一,五五數之剩四,七七數之剩三,那麽,運算的步驟便是:
若單隻就實用或遊戲說,熟記這秘訣已夠用了。至於它是從哪兒來的,一般人哪兒管這麽多?但就數學的立場來說,這種知其然而不知其所以然的態度卻沒有多大價值,即使熟記這秘訣,所能應付的問題不過一百零五個,因為隻限於三三、五五、七七三種數法。我們要默記這一百零五個答數並不是不可能,然而如果真的熟記這一百零五個答數,那就無意味了。(見附注)
所以我們第一要問,為什麽這樣就是對的?
要說明其中的理由,我們先記起算術裏麵關於倍數的兩個定理:
(一)某數的倍數的倍數,還是某數的倍數——這正如我的哥哥的哥哥還是我的哥哥一般。
(二)某數的若幹倍數的和,還是某數的倍數——這正如我的幾個哥哥坐在一起,他們仍然是我的哥哥一般。
依照這兩個定理來檢討上麵的算法,設R3表示用三除所得的餘數,R5和R7相應地表示用五除和用七除所得的餘數,那麽:
(一)七十是五和七的倍數,而是三的倍數多一,所以用R3去乘仍是五和七的倍數,而是三的倍數多R3。
(二)二十一是七和三的倍數,而是五的倍數多一,所以用R5去乘仍是七和三的倍數,而是五的倍數多R5。
(三)十五是三和五的倍數,而是七的倍數多一,所以用R7去乘仍是三和五的倍數,而是七的倍數多R7。
(四)所以這三項相加,就三說,是70×R3+21×R5+15×R7=3的倍數+R3+3的倍數+3的倍數=3的倍數+R3。
若用三去除所得的餘數正是R3。就五說,是70×R3+21×R5+15×R7=5的倍數+R5+5的倍數+5的倍數=5的倍數+R5。
若用五去除所得的餘數正是R5。就七說,是70×R3+21×R5+15×R7=7的倍數+R7+7的倍數+7的倍數=7倍數+R7。
若用七去除所得的餘數正是R7。
這就可以證明我們如法炮製出來的數是合題的。至於在比一百零五大的時候,要減去它的倍數,使得數小於一百零五,這是因為適合於題目的答數本來是無窮的,隻得取最小的一個數代表的緣故。一百零五本是三、五、七的最小公倍數,在這最小的答數上加入它的倍數,這和除得的餘數無關。
經過這樣的證明,我們可以承認上麵的算法是對的。但這還不夠,我們還要問,那七十、二十一和十五三個數含有怎樣的性質?
七十是五和七的公倍數,而二十一是七和三的最小公倍數,十五是三和五的最小公倍數,為什麽兩個是最小公倍數而它一個卻隻是公倍數呢?
這個問題並不難回答,因為二十一用五除,十五用七除都恰好剩一,而五和七的最小公倍數“三十五”用三除剩的卻是二,七十用三除才剩一。所以這個解法的要點,是要求出三個數來,每一個都是三個除數中的兩個的公倍數——最小公倍數是碰巧的——而同時是它一個除數的倍數多一。這樣,就到了第三步,我們要問,合於這種條件的數怎麽求出來呢?這裏且將清時黃中憲所編的《求一術通解》裏的方法摘抄在下麵,我們來認識認識中國數學書的麵目,也是一件趣事。
“三位泛母都是數根,不可拆,即為定母。連乘,得105為衍母。以一行三除之,得三十五為一行衍數;以二行定母五除之,得二十一為二行衍數;以三行定母七除之,得十五為三行衍數。”
這裏所謂泛母,用不到解釋,便可明白,析母就是將泛母分成質因數。至於定母,便是各泛母所單獨含有的質因數的積。若是有一個質因數是兩個以上的泛母所共有的,那麽隻是含這個質因數的個數最多的泛母用它;若是兩個泛母所含這質因數的個數相同,那麽隨便哪一個泛母用它都可以。注意後麵的另一個例子——衍母是各定母的連乘積,也就是各泛母的最小公倍數,衍數是用定母除衍母所得的商。
得了定母和衍數,就可以求乘率,所謂乘率便是乘了衍數所得的積恰等於泛母的倍數多一的數,而這個乘積稱為用數。求乘率的方法,在《求一術通解》裏麵是這樣說的:“列定母於右行,列衍數於左行(左角上預寄一數),輾轉累減,至衍數餘一為止,視左角上寄數為乘率。
“按兩數相減,必以少數為法(法是減數),多數為實(實是被減數)。其法上無寄數者,不論減若幹次,減餘數上仍以一為寄數(1)。其實上無寄數者,減作數上,以所減次數為寄數(2)。其法實上俱有寄數者,視累減若幹次,以法上寄數亦累加若幹次於實上寄數中(3),即得減餘數上之寄數矣。”
照這個法則,我們來求所要的各乘率。為了容易明白,我將原式的中國數碼改成了阿拉伯數字:
所以乘率是2。
所以乘率是1。
所以乘率是1。
依原書所說,是用累減法,但累減便是除,為什麽不老老實實地說除,而要說是累減呢?是因為最後衍數這一行必要保留一個餘數一——所以即使除得盡也不許除盡。因此說除不如說累減更好。但在此說明,還是用除好些。我們就用除法來檢查這個計算法。如第一式,衍數35左角上的1,就是所謂預寄的一數,表示用一個衍數的意思。因為定母3比衍數35小,用3(法)去除35(實)得11剩2。照(1)法上無寄數,仍以1為餘數2的寄數,所以2的左角上寫1。接著以2(法)除3(實)得1(商)剩1。照(2)實上無寄數,以所減次數(即商數)為餘數的寄數,所以1的右角上還是1。再用這1(法)去除2(實)本來是除得盡的,但應當保留餘數1,因此隻能商1而剩1。照(3)法實都有寄數,應當以商數1乘法數1的寄數1,加上實數2的寄數1得2,為餘數1的寄數,而它便是乘率。
第一次的餘數2=35-3×11
第二次的餘數1=3-2×1=3-第一次的餘數×1=3-1-(35-3×11)×1
第三次的餘數1=2-1×1
上式中“·”表示所求得的乘率,黑體字表示每次的寄數。你看這求法多麽巧妙!現在用代數的方法證明如下:設A為定母,B為衍母,a0a1a2……an為各次的寄數,r0r1r2……rn為各次的餘數,而rn等於1,依上麵的式子寫出來便是:
有了乘率,將它去乘衍數就得用數,上麵已經證明了,所以在本例題中,三、五和七的用數相應地便是七十(35×2)、二十一(21×1)和十五(15×1)。
楊輝的“剪管術”中,同樣的題目有好幾個,試取兩個照樣演算於下。
(a)七數剩一,八數剩二,九數剩三,問本數是多少?
(一)求衍數(二)求乘率所以乘率是4。所以乘率是7。
所以乘率是5。
(三)求用數,就是將相應的乘率去乘衍數,所以七、八、九的用數相應地為二百八十八(72×4)、四百四十一(63×7)和二百八十(56×5)。
(四)求本數,就是將各除數所除得的剩餘相應地乘各用數,而將這三個乘積加起來。倘若所得的和比七、八、九的最小公倍數504大,就將504的倍數減去,也就是用這最小公倍數除所得的和而求餘數。
因而288×1+441×2+280×3=288+882+840=2010
2010÷504=3餘498
所以四百九十八是本數。
(b)二數餘一,五數餘二,七數餘三,九數餘四,求原數是多少?
(一)求衍數
(二)求乘率所以乘率是1。所以乘率是6。
所以乘率是1。所以乘率是4。(三)求用數
2 的……315×1=315,5 的……126×1=126,7 的……90×6=540,9的……70×4=280。(四)求本數
315×1+126×2+540×3+280×4=315+252+1620+1120=3307 3307÷630=5……157
所以原數是一百五十七。
再由《求一術通解》上取一個較複雜的例子,就更可以看明白這類題的算法了。
“今有數不知總:以五累減之,無剩;以七百一十五累減之,剩一十;以二百四十七累減之,剩一百四十;以三百九十一累減之,剩二百四十五;以一百八十七累減之,剩一百零九,求總數是多少?”
“答:10020。”(一)求衍數
(二)求乘率
所以乘率是18。
所以乘率是139。
所以乘率是43。
(三)求用數
715的……96577×18=1738386
247的……21505×139=2989195
391的……13585×43=584155
(四)求總數
1738386×10+2989195×140+584155×245=17383860+418487300+143117974=578989135
578989135÷5311735=109……10020
這個計算所要注意的就是“廢位”,第一行的析母5,第二行也有,第二行已用了(數旁記黑點就是表示采用的意思),所以第一行可廢去。第五行的11和17,一個已用在第二行,一個已用在第四行,所以這一行也廢去。前麵已經說過兩個泛母若有相同的質因數而且所含的個數相同,無論哪個泛母采用都可以,因此上麵求衍數的方法隻是其中一種。在《求一術通解》裏,就附有左列每種采用法的表,比較起來這一種實在是最簡單的了。(表中的○表示廢位。)
由這幾個例子,可以看出“韓信點兵”不限於三三、五五、七七地數。在中國的舊數學上,《大衍求一術》還有不少應用,不過在這篇短文裏卻講不到了。
到了這一步,我們可以問:“‘韓信點兵’這類問題在西洋數學中怎樣解決呢?”
要回答這個問題,你先要記起代數中聯立方程式的解法來。不,首先要記起一般聯立方程式所應具備的必要條件。那是這樣的,方程式的個數應當和它們所含未知數的個數相等。所以二元的要有兩個方程式,三元的要有三個,倘使方程式的個數比它們所含未知數的個數少,那就不能得出一定的解答,因此我們稱它為無定方程式(Indeterminations of a system of equation)。
兩個未知數而隻有一個方程式,例如,
5x+10y=20.
我們若將y當作已知數看,依照解方程式的順序來解便可,而且也隻能得出下麵的式子:
x=4-2y.
在這個式子當中任意用一個數去代y,x都有一個相應的數值,如:
y的數值既然可以任意定,所以這方程式的根便是無定的。
又三個未知數,隻有兩個方程式,比如:
依照解聯立方程式的法則,從這兩個方程式中可以隨意先消去一個未知數。若要消去z,就用3去乘(2),再和(1)相加,便得:
7x-14y=14
再移含有y的項到右邊,並且全體用7去除,就得:
x=2+y
照前例同樣的理由,這方程式中y的值可以任意選用,所以是無定的,而x的值也就無定了,x和y的值都不一定,z的值跟著更是無定,如:
…………
就這樣推下去,聯立方程式的個數隻要比它們所含的未知數少,就得不出一定的解答來。
這樣說起來,不定方程式係不是一點兒用場都沒有了嗎?這個疑問自然是應當有的,不過用場的有無實在難說。和尚撿到常州梳子自然沒用,但若是江北大姐撿到,豈不喜出望外?仔細考察起來,不定方程式係雖然沒有一定的解答,但它將所含的未知數間的關係加上了限製。即如第一個例子,x和y的數值雖然無定,但若y等於0,x就隻能等於4;若y等於1,x就隻能等於2。再就第二個例子說,也有同樣的情形。這種關係倘若再得到別的條件來補充,那麽,解答就不是漫無限製了,本來一個方程式也不過表示幾個未知數在某種情形所具有的關係,也就隻是一個條件。
我們就用“韓信點兵”的問題來做例吧。
設三三數所數的次數為x,五五數所數的次數為y,七七數所數的次數為z,而原數為N,則:
N=3x+2=5y+3=7z+2.
這有三個未知數隻有兩個方程式,但我們應當注意x、y、z都必須是正整數,這便是一個附帶的條件,
因為x和y是正整數,所以2y+1/3雖是一個分數的形式,也必須是整數,設它是α,那麽:
因為x和y都是整數,所以α-1/2也必須是整數,設它是β,則
現在γ既是整數,而且不能是負的。因為它若是負的,N也便是負的,對於題目來說便沒有意義了,所以γ至少是1,而
N=105-82=23
自然γ可以是2、3、4、5、6……而N隨著便是128、233、338、443、548……N的值雖無窮卻有一個限製。
既說到代數的無定方程式,無妨順著再說一點。
(a)解方程式3x+4y=22,x和y的值限於正整數,先將含y的項移到右邊,則得
因為x和y都是正整數,而7本來是整數,所以1-y/3也應當是整數,設它等於α,則
由(1)y既是正整數,α也是整數,所以α或是等於零或是負的,絕不能是正的。
由(2)x既是正整數,α也是整數,所以α應當是正的或是等於零,最小隻能等於負1。
合看這兩個條件,α隻能等於零或負1,而
(b)解方程式5x-14y=11,x和y的值限於正整數。
因為x和y以及2都是整數,所以5也應當是整數,但這裏和前一個例不同,不好直接設它等於α,因為若1+4/y=α,則 1+4y=5α,y=5α-1/4仍是一個分數的形式。要避去這個困難,必要的條件是使原來的分數的分子中y的係數為1。幸好這是可能的,不是嗎?整數的倍數仍然是整數,我們無妨用一個適當的數去乘這分數,就是乘它的分子。所謂適當,就是乘了以後,y的係數恰等於分母的倍數多1。這好像又要用到了前麵所說的求乘率的方法了,實際還可以不必這麽大動幹戈。乘數總比分母小,由觀察便可知道了。在本例中,則可用4去乘,便得
而4+y/5應當是整數,設它等於α,則
這裏和前例也有點兒不同,由(1)和(2)看來,α隻要是正整數就可以,不必再有什麽限製,所以
這樣的解答是無窮的。
將中國的老方法和現在我們所學的新方法比較一下,究竟哪一種好些,這雖很難說,但由此可以知道,一個問題的解法絕不隻是一種。當學習數學的時候,能夠注意別人的算法以及自己另辟蹊徑去走都是有興味而且有益處的。中學的“求一術”不但在中國數學史上占著很重要的地位,若能發揚光大,正有不少問題可以研究。
[附注]一個數用三去除,有三種情形:一是剩0(就是除盡);二是剩1;三是剩2。同樣地,用五去除有五種情形:剩0、1、2、3、4;用七去除有七種情形:剩0、1、2、3、4、5、6。從三除的三種情形中任取一種,和五除的五種情形中的任一種,以及七除的七種情形中的任一種配合,都能成一個“韓信點兵”的題目,所以總共有3×5×7=105個題。而這105個題的最小答數,恰是從0到104。這105個數中,把它們排列起來可以得出下麵的表:這個表的構造是這樣的:
(1)R3的一行的0、1、2表示三個三個地數的餘數。
(2)R7的一行的0、1、2、3、4、5、6表示七個七個地數的餘數。
(3)R5的一排的0、1、2、3、4表示五個五個地數的餘數。
(4)中間的數便是105個相當的答數。
所以如說三數剩二,五數剩三,七數剩二,答數就是二十三。如說三數剩一,五數剩二,七數剩四,答數便是六十七。
表中各數的排列,仔細觀察,也很有趣:
(1)就三大橫排說,同行同小排的數次第加70——超過105,則減去它——正是泛母三的用數。
(2)就每個小橫排說,次第加21——超過105,則減去它——正是泛母五的用數。
(3)就每大橫排中的各行說,次第加15——超過105,則減去它——正是泛母七的用數。
這個理由自然是略加思索就會明白的。