社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
主要讲述了以赋税计算为中心的比较复杂的配分比例算法,以及等差数列的问题。
Python编程要点
均,平也。输,送也。“均输术”就是按人口多少、路途远近、谷物贵贱推算赋税及徭役的方法。就算法而言,即是配分比例。
图19-1 问题之问
图19-2 问题之答
提示
图19-1和19-2所示由图解九章源码中的“图解均输术.py”自动绘制而成,我们可运行脚本文件,查看动态的绘制过程。
今有均输粟,甲县一万户,行道八日;乙县九千五百户,行道十日;丙县一万二千三百五十户,行道十三日;丁县一万二千二百户,行道二十日,各到输所(输所:收纳赋粟的场所)。凡四县赋当输二十五万斛(1斛=1石),用车一万乘。欲以道里远近、户数多少衰出之,问粟、车各几何?
答曰:甲县粟八万三千一百斛,车三千三百二十四乘。乙县粟六万三千一百七十五斛,车二千五百二十七乘。丙县粟六万三千一百七十五斛,车二千五百二十七乘。丁县粟四万五百五十斛,车一千六百二十二乘。
均输术曰:令县户数各如其本行道日数而一,以为衰。
令每县户数,各除以其各自行路天数,作为衰。即:
甲县 10000 ÷ 8 = 1250;
乙县 9500 ÷ 10 = 950;
丙县 12350 ÷ 13 = 950;
丁县 12200 ÷ 20 = 610;
甲县:乙县:丙县:丁县 = 125 :95 :95 :61
甲衰一百二十五,乙、丙衰各九十五,丁衰六十一,副并为法。以赋粟车数乘未并者,各自为实。实如法得一车。有分者,上下辈之(所求的车、牛、人数应为正整数,若得分数,可按四舍五入的法则配成整数 )。以二十五斛乘车数,即粟数。
# 导入模块 批注:
from common import hanzi_shu,shu_hanzi
# 获取各县户数和行道日
print("各县户数和行道日:")
xian={} xian:字典,键为县名,值为各县信息的列表
hz=input().split(";") hz:列表,包含各县汉字字符串
for s in hz:
for j,c in enumerate(s):
if c == "县":
n1=j n1:“县”在字符串中的索引位置
if c in ["户","人"]:
n2=j n2:“户”或‘人’在字符串中的索引位置
if c == "道":
n3=j n3:“道”在字符串中的索引位置
if c == "日":
n4=j n4:“日”在字符串中的索引位置
xian_name=s[:n1] xian_name:县名
hu_shu=hanzi_shu(s[n1+1:n2]) hu_shu:户数
xing_dao_ri=hanzi_shu(s[n3+1:n4]) xing_dao_ri:行道日
xian[xian_name]=[hu_shu,xing_dao_ri] 向xian字典中加入元素
# 获取所赋
fu={} fu:字典,键为赋名,值为赋信息的列表
print("当输:")
hz=input().split(',') hz:列表,包含所输赋信息
for s in hz:
fu_name=s[0] fu_name:赋名
fu_shu=s[1:len(s)-1] fu_shu:赋的数量
fu_dw=s[-1] fu_dw:赋的单位,-1表示字符串最后一个元素
fu[fu_name]=[hanzi_shu(fu_shu),fu_dw] 向fu字典中加入元素
# 列衰,副并为法
fa=0
for k in xian: 遍历字典xian (县)
# 令县户数各如其本行道日数而一,以为衰
cui=xian[k][0]//xian[k][1] cui:衰
xian[k]=cui xian字典各县的值改为衰
# 副并为法
fa=fa+cui
for k1 in xian: 遍历字典xian
cui=xian[k1]
print(k1+"县:")
for k2 in fu: 遍历字典fu
fu_name=k2
fu_shu=fu[k2][0]
fu_dw=fu[k2][1]
# 以赋粟车数乘未并者,各自为实。实如法得一。
shi=fu_shu*cui
zheng=int(shi/fa)
fz=shi%fa
fm=fa
# 有分者,上下辈之。
if fz*2 >fm:
chu=zheng+1
else:
chu=zheng
print(fu_name,shu_hanzi(chu)+fu_dw)
运行脚本,解决问题,结果如图19-3所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4PjAqoy2-1581040415004)(/api/storage/getbykey/original?key=1911160a38e57d500146)]
图19-3 均输术运行结果
上面运行过程中各字典的中间结果如下。
1.“获取各县户数和行道日”
xian = {‘甲’:[10000,8],’乙’:[9500,10],’丙’:[12350,13],’丁’:[12200,20]}
2.“获取所赋”
fu = {‘粟’:[250000,’斛’],’车’:[10000,’乘’]}
3.“列衰,副并为法”
xian = {‘甲’:1250,’乙’:950,’丙’:950,’丁’:610}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!