• [Python学习笔记012] 古巴比伦人的乘法表


    问题:我们知道,古巴比伦人采用的六十进制。那么,如果为古巴比伦人绘制一张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中很容易被呈现。

    。。。未完待续。。。

  • 相关阅读:
    CountDownLatch demo演示裁判和选手赛跑
    @Async异步方法对异常的处理,从内层向外层抛出机制
    python3读csv文件,出现UnicodeDecodeError: 'utf8' codec can't decode byte 0xd0 in position 0: invalid con
    Python3 dict和str互转
    python批量读取excel csv文件插入mysql数据库
    dotnet 6 精细控制 HttpClient 网络请求超时
    读书笔记 为什么要有R5G6B5颜色格式
    dotnet 6 推荐一个可代替 .NET Remoting 的 IPC 库
    dotnet 6 通过 DOTNET_ROOT 让调起的应用的进程拿到共享的运行时文件夹
    记 Win8.1 某应用渲染抛出 OutOfMemoryException 异常及修复方法
  • 原文地址:https://www.cnblogs.com/idorax/p/15869464.html
Copyright © 2020-2023  润新知