問題:我們知道,古巴比倫人采用的六十進制。那么,如果為古巴比倫人繪制一張59x59的乘法表,該如何實現呢?通過Python實現並不復雜,但關鍵步驟有二:
- 01 - 將十進制數轉換為六十進制數
- 02 - 將六十進制數翻譯成古巴比倫人的符號數字
在實現上述關鍵步驟之前,我們先看看古巴比倫人的符號數字。

在上述符號系統中,一把小鑰匙表示1,一個魚骨頭表示10。
- 1

- 10

接下來,我們將任何一個十進制數轉換為六十進制數。
1. 將十進制數轉換為六十進制數
1 def dec2basen(n, basen=2): 2 """ Convert decimal number to base-N number """ 3 m = n 4 k = 0 5 while True: 6 cnt = m // basen 7 if cnt == 0: 8 break 9 m = cnt 10 k += 1 11 12 m = n 13 out = [] 14 i = k 15 while i >= 0: 16 x = m // (basen ** i) 17 out.append(x) 18 19 m -= x * (basen ** i) 20 i -= 1 21 22 return out 23 24 25 def dectobase60(n): 26 """ Convert decimal number to base-60 number """ 27 return dec2basen(n, 60)
2. 創建古巴比倫人的數字符號表
如果用字母B代表一個魚骨頭(10),字母K代表一把小鑰匙(1),那么我們可以通過如下函數創建古巴比倫人的數字符號表。
1 BABYLON_NS_KEY = 'K' 2 BABYLON_NS_FISH_BONE = 'B' 3 4 5 def create_ancient_babylonian_num_sym_tbl(): 6 sym_table = [] 7 for i in range(1, 60, 1): 8 n = i 9 na = n // 10 # get the number of keys while key = 1 10 nb = n % 10 # get the number of fish bones while fish bone = 10 11 sym = BABYLON_NS_FISH_BONE * na + BABYLON_NS_KEY * nb 12 sym_table.append({'b10': n, 'b60': sym}) 13 return sym_table
通過上述函數生成的數字符號表如下所示:
{'b60': 'K', 'b10': 1}
{'b60': 'KK', 'b10': 2}
{'b60': 'KKK', 'b10': 3}
{'b60': 'KKKK', 'b10': 4}
{'b60': 'KKKKK', 'b10': 5}
{'b60': 'KKKKKK', 'b10': 6}
{'b60': 'KKKKKKK', 'b10': 7}
{'b60': 'KKKKKKKK', 'b10': 8}
{'b60': 'KKKKKKKKK', 'b10': 9}
{'b60': 'B', 'b10': 10}
...<snip>.............................
{'b60': 'BBBBB', 'b10': 50}
{'b60': 'BBBBBK', 'b10': 51}
{'b60': 'BBBBBKK', 'b10': 52}
{'b60': 'BBBBBKKK', 'b10': 53}
{'b60': 'BBBBBKKKK', 'b10': 54}
{'b60': 'BBBBBKKKKK', 'b10': 55}
{'b60': 'BBBBBKKKKKK', 'b10': 56}
{'b60': 'BBBBBKKKKKKK', 'b10': 57}
{'b60': 'BBBBBKKKKKKKK', 'b10': 58}
{'b60': 'BBBBBKKKKKKKKK', 'b10': 59}
3. 將六十進制數翻譯成古巴比倫人的數字符號
由於古巴比倫人的數字系統中沒有零,於是我們用字母Z代表零(0)。
1 BABYLON_NS_ZERO = 'Z' 2 3 4 def get_sym_bydec(dec, sym_tbl): 5 for sym in sym_tbl: 6 if dec == sym['b10']: 7 return sym['b60'] 8 return BABYLON_NS_ZERO 9 10 11 def get_sym_byb60(l60n, sym_tbl): 12 out = [] 13 for dec in l60n: 14 out.append(get_sym_bydec(dec, sym_tbl)) 15 return ','.join(out)
通過上述函數,如將一個十進制數轉化成六十進制數后,翻譯成古巴比倫人的數字符號,示例如下:
0 : [0] ==> Z 1 : [1] ==> K 10 : [10] ==> B 11 : [11] ==> BK 59 : [59] ==> BBBBBKKKKKKKKK 60 : [1, 0] ==> K,Z 61 : [1, 1] ==> K,K 81 : [1, 21] ==> K,BBK 3601 : [1, 0, 1] ==> K,Z,K 3481 : [58, 1] ==> BBBBBKKKKKKKK,K
4. 構造59x59的乘法表
對每一項采用字典進行存儲,存儲結構如下:
{ "a": { "desc": "multiplicand", "b10": "TYPE is int", "s60": "TYPE is string", "l60": "TYPE is list" }, "b": { "desc": "multiplier", "b10": "TYPE is int", "s60": "TYPE is string", "l60": "TYPE is list" }, "c": { "desc": "product", "b10": "TYPE is int", "s60": "TYPE is string", "l60": "TYPE is list" } }
例如:9 * 9 = 81 被存儲為:
{ "a": { "desc": "multiplicand = a", "b10": 9, "s60": "KKKKKKKKK", "l60": [ 9 ] }, "b": { "desc": "multiplier = b", "b10": 9, "s60": "KKKKKKKKK", "l60": [ 9 ] }, "c": { "desc": "product = a x b = c", "b10": 81, "s60": "K,BBK", "l60": [ 1, 21 ] } }
基於上述存儲結構,實現代碼如下:
1 def create_mul_tbl(sym_tbl, n=59): 2 mul_tbl = [] 3 for i in range(n): 4 a = i + 1 5 col = [] 6 for j in range(n): 7 b = j + 1 8 if b < a: 9 continue 10 # 11 # MULTIPLICAND x MULTIPLIER = PRODUCT 12 # a x b = c 13 # 14 c = a * b 15 la60 = dectobase60(a) 16 lb60 = dectobase60(b) 17 lc60 = dectobase60(c) 18 d_cell = {} 19 d_cell['a'] = {} 20 d_cell['b'] = {} 21 d_cell['c'] = {} 22 d_cell['a']['desc'] = 'multiplicand = a' 23 d_cell['a']['b10'] = a 24 d_cell['a']['s60'] = get_sym_byb60(la60, sym_tbl) 25 d_cell['a']['l60'] = la60 26 d_cell['b']['desc'] = 'multiplier = b' 27 d_cell['b']['b10'] = b 28 d_cell['b']['s60'] = get_sym_byb60(lb60, sym_tbl) 29 d_cell['b']['l60'] = lb60 30 d_cell['c']['desc'] = 'product = a x b = c' 31 d_cell['c']['b10'] = c 32 d_cell['c']['s60'] = get_sym_byb60(lc60, sym_tbl) 33 d_cell['c']['l60'] = lc60 34 col.append(d_cell) 35 mul_tbl.append(col) 36 return mul_tbl
5. 純文本輸出59x59的乘法表
基於純文本輸出,很容易實現,實現的函數如下:
1 def output_text(mul_tbl, verbose=False): 2 for col in mul_tbl: 3 for row in col: 4 if verbose: 5 if len(row['c']['l60']) == 2: 6 x1 = row['c']['l60'][0] 7 x2 = row['c']['l60'][1] 8 else: 9 x1 = 0 10 x2 = row['c']['l60'][0] 11 print('#\t%2d x %2d = %d = %2d x 60 + %2d' % 12 (row['a']['b10'], row['b']['b10'], row['c']['b10'], 13 x1, x2)) 14 print('%s\tx\t%s\t= %s' % 15 (row['a']['s60'], row['b']['s60'], row['c']['s60'])) 16 print()
輸出效果如下:
K x K = K K x KK = KK K x KKK = KKK K x KKKK = KKKK K x KKKKK = KKKKK K x KKKKKK = KKKKKK K x KKKKKKK = KKKKKKK K x KKKKKKKK = KKKKKKKK K x KKKKKKKKK = KKKKKKKKK ...<snip>... BBBBBKKKKKKKK x BBBBBKKKKKKKK = BBBBBKKKKKK,KKKK BBBBBKKKKKKKK x BBBBBKKKKKKKKK = BBBBBKKKKKKK,KK BBBBBKKKKKKKKK x BBBBBKKKKKKKKK = BBBBBKKKKKKKK,K
6. 富文本輸出59x59的乘法表
為了真實再現古巴比倫人的數字符號,我們必須采用富文本輸出,這里利用MarkDown實現,因為圖片在MarkDown中很容易被呈現。
。。。未完待續。。。
