diff --git a/Py3Scripts/AwesomeMath.ipynb b/Py3Scripts/AwesomeMath.ipynb index f1508a1..a7c6bb7 100644 --- a/Py3Scripts/AwesomeMath.ipynb +++ b/Py3Scripts/AwesomeMath.ipynb @@ -1 +1 @@ -{"cells":[{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[],"source":"# 百钱白鸡问题:1只公鸡5元,1只母鸡3元,3只小鸡1元,100元买100只鸡,问:公鸡母鸡小鸡各有多少?\n# 经典三元一次方程求解,设各有x,y,z只\n\n# 解法一:推断每种鸡花费依次轮询,运行时间最短,2019-7-24最优方案\n# import time\n# start = time.perf_counter_ns() # 用自带time函数统计运行时长\nfor x in range(0, 101, 5): # 公鸡花费x元在0-100范围包括100,步长为5\n for y in range(0, 101 - x, 3): # 母鸡花费y元在0到100元减去公鸡花费钱数,步长为3\n z = 100 - x - y # 小鸡花费z元为100元减去x和y\n if x / 5 + y / 3 + z * 3 == 100:\n print(\"公鸡:%d只,母鸡:%d只,小鸡:%d只\" % (x / 5, y / 3, z * 3))\n # pass\n# end = time.perf_counter_ns()\n# time1 = end - start\n# print(\"解法一花费时间:\", time1)"},{"cell_type":"code","execution_count":2,"metadata":{},"outputs":[],"source":"# 解法二:解法和解法一类似\n# 解题思路:买一只公鸡花费5元,剩余95元(注意考虑到不买公鸡的情况),再买一只母鸡花费3元剩余92元,依次轮询下去,钱数不断减\n# 少,100元不再是固定的。假设花费钱数依次为x、y、z元\nfor x in range(0, 101, 5): # 公鸡花费x元在0-100范围包括100,步长为5\n for y in range(0, 101 - x, 3): # 母鸡花费y元在0到100元减去公鸡花费钱数,步长为3\n for z in range(0, 101 - x - y):\n if x / 5 + y / 3 + z * 3 == 100 and x + y + z == 100: # 花费和鸡数都是100\n print(\"公鸡:%d只,母鸡:%d只,小鸡:%d只\" % (x / 5, y / 3, z * 3))"},{"cell_type":"code","execution_count":3,"metadata":{},"outputs":[],"source":"# 解法三:枚举法\n# 解题思路:若只买公鸡最多20只,但要买100只,固公鸡在0-20之间不包括20;若只买母鸡则在0-33之间不包括33;若只买小鸡则在0-100\n# 之间不包括100\nfor x in range(0, 20):\n for y in range(0, 33):\n z = 100 - x - y # 小鸡个数z等于100只减去公鸡x只加母鸡y只\n if 5 * x + 3 * y + z / 3 == 100: # 钱数相加等于100元\n print(\"公鸡:%d只,母鸡:%d只,小鸡:%d只\" % (x, y, z))"}],"nbformat":4,"nbformat_minor":2,"metadata":{"language_info":{"name":"python","codemirror_mode":{"name":"ipython","version":3}},"orig_nbformat":2,"file_extension":".py","mimetype":"text/x-python","name":"python","npconvert_exporter":"python","pygments_lexer":"ipython3","version":3}} \ No newline at end of file +{"cells":[{"cell_type":"code","execution_count":5,"metadata":{},"outputs":[],"source":"# 百钱白鸡问题:1只公鸡5元,1只母鸡3元,3只小鸡1元,100元买100只鸡,问:公鸡母鸡小鸡各有多少?\n# 经典三元一次方程求解,设各有x,y,z只\n\n# 解法一:推断每种鸡花费依次轮询,运行时间最短,2019-7-24最优方案\n# import time\n# start = time.perf_counter_ns() # 用自带time函数统计运行时长\nfor x in range(0, 101, 5): # 公鸡花费x元在0-100范围包括100,步长为5\n for y in range(0, 101 - x, 3): # 母鸡花费y元在0到100元减去公鸡花费钱数,步长为3\n z = 100 - x - y # 小鸡花费z元为100元减去x和y\n if x / 5 + y / 3 + z * 3 == 100:\n print(\"公鸡:%d只,母鸡:%d只,小鸡:%d只\" % (x / 5, y / 3, z * 3))\n # pass\n# end = time.perf_counter_ns()\n# time1 = end - start\n# print(\"解法一花费时间:\", time1)\n\n# 解法二:解法和解法一类似\n# 解题思路:买一只公鸡花费5元,剩余95元(注意考虑到不买公鸡的情况),再买一只母鸡花费3元剩余92元,依次轮询下去,钱数不断减\n# 少,100元不再是固定的。假设花费钱数依次为x、y、z元\nfor x in range(0, 101, 5): # 公鸡花费x元在0-100范围包括100,步长为5\n for y in range(0, 101 - x, 3): # 母鸡花费y元在0到100元减去公鸡花费钱数,步长为3\n for z in range(0, 101 - x - y):\n if x / 5 + y / 3 + z * 3 == 100 and x + y + z == 100: # 花费和鸡数都是100\n print(\"公鸡:%d只,母鸡:%d只,小鸡:%d只\" % (x / 5, y / 3, z * 3))\n\n# 解法三:枚举法\n# 解题思路:若只买公鸡最多20只,但要买100只,固公鸡在0-20之间不包括20;若只买母鸡则在0-33之间不包括33;若只买小鸡则在0-100\n# 之间不包括100\nfor x in range(0, 20):\n for y in range(0, 33):\n z = 100 - x - y # 小鸡个数z等于100只减去公鸡x只加母鸡y只\n if 5 * x + 3 * y + z / 3 == 100: # 钱数相加等于100元\n print(\"公鸡:%d只,母鸡:%d只,小鸡:%d只\" % (x, y, z))"},{"cell_type":"code","execution_count":2,"metadata":{},"outputs":[],"source":"# 经典斐波那契数列\n# 定义:https://wikimedia.org/api/rest_v1/media/math/render/svg/c374ba08c140de90c6cbb4c9b9fcd26e3f99ef56\n# 用文字来说,就是斐波那契数列由0和1开始,之后的斐波那契系数就是由之前的两数相加而得出\n\n# 方法一:使用递归\ndef fib1(n):\n if n<0:\n print(\"Incorrect input\")\n elif n==1:\n return 0 # 第一个斐波那契数是0\n elif n==2:\n return 1 # 第二斐波那契数是1\n else:\n return fib1(n-1)+fib1(n-2)\n\nprint(fib1(2))\n\n\n# 方法二:使用动态编程\nFibArray = [0, 1]\n\n\ndef fib2(n):\n if n < 0:\n print(\"Incorrect input\")\n elif n <= len(FibArray):\n return FibArray[n - 1]\n else:\n temp_fib = fib2(n - 1) + fib2(n - 2)\n FibArray.append(temp_fib)\n return temp_fib\n\n# 方法三:空间优化\ndef fibonacci(n):\n a = 0\n b = 1\n if n < 0:\n print(\"Incorrect input\")\n elif n == 0:\n return a\n elif n == 1:\n return b\n else:\n for i in range(2,n):\n c = a + b\n a = b\n b = c\n return b"},{"cell_type":"code","execution_count":3,"metadata":{},"outputs":[],"source":"# 水仙花数:水仙花数即此数字是各位立方和等于这个数本身的数。例:153 = 1**3 + 5**3 + 3**3\n# 找出1-1000之间的水仙花数\n# 分别四个数字:1,2,3,4,组成不重复的三位数。问题扩展:对于给定数字或给定范围的数字,组成不重复的n位数\n\n# 方法一:解答四个数组成不重复三位数(暂未想到更优方法)\nfor x in range(1, 5):\n for y in range(1, 5):\n for z in range(1, 5):\n if (x != y) and (x != z) and (z != y):\n print(x, y, z)"},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":"# 计算pi小数点任意位数\nfrom __future__ import division\nimport math\nfrom time import time\ntime1 = time()\nnumber = int(input('输入计算的位数:'))\nnumber1 = number + 10 # 多计算十位方式尾数取舍影响\nb = 10 ** number1\n# 求含4/5的首项\nx1 = b * 4 // 5\n# 求含1/239的首项\nx2 = b // -239\n\n# 求第一大项\nhe = x1 + x2\n# 设置下面循环的终点,即共计算n项\nnumber *= 2\n\n# 循环初值=3,末值2n,步长=2\nfor i in range(3, number, 2):\n # 求每个含1/5的项及符号\n x1 //= -25\n # 求每个含1/239的项及符号\n x2 //= -57121\n # 求两项之和\n x = (x1 + x2) // i\n # 求总和\n he += x\n\n# 求出π\npi = he * 4\n# 舍掉后十位\npi //= 10 ** 10\n\n# 输出圆周率π的值\npi_string = str(pi)\nresult = pi_string[0] + str('.') + pi_string[1:len(pi_string)]\nprint(result)\n\ntime2 = time()\n\nprint(u'耗时:' + str(time2 - time1) + 's')\n\n\n# 使用chudnovsky算法计算\n# 参考链接:https://www.craig-wood.com/nick/articles/pi-chudnovsky/\n\n\"\"\"\nPython3 program to calculate Pi using python long integers, BINARY\nsplitting and the Chudnovsky algorithm\n\n\"\"\"\n\nimport math\nfrom gmpy2 import mpz\nfrom time import time\n\ndef pi_chudnovsky_bs(digits):\n \"\"\"\n Compute int(pi * 10**digits)\n\n This is done using Chudnovsky's series with BINARY splitting\n \"\"\"\n C = 640320\n C3_OVER_24 = C**3 // 24\n def bs(a, b):\n \"\"\"\n Computes the terms for binary splitting the Chudnovsky infinite series\n\n a(a) = +/- (13591409 + 545140134*a)\n p(a) = (6*a-5)*(2*a-1)*(6*a-1)\n b(a) = 1\n q(a) = a*a*a*C3_OVER_24\n\n returns P(a,b), Q(a,b) and T(a,b)\n \"\"\"\n if b - a == 1:\n # Directly compute P(a,a+1), Q(a,a+1) and T(a,a+1)\n if a == 0:\n Pab = Qab = mpz(1)\n else:\n Pab = mpz((6*a-5)*(2*a-1)*(6*a-1))\n Qab = mpz(a*a*a*C3_OVER_24)\n Tab = Pab * (13591409 + 545140134*a) # a(a) * p(a)\n if a & 1:\n Tab = -Tab\n else:\n # Recursively compute P(a,b), Q(a,b) and T(a,b)\n # m is the midpoint of a and b\n m = (a + b) // 2\n # Recursively calculate P(a,m), Q(a,m) and T(a,m)\n Pam, Qam, Tam = bs(a, m)\n # Recursively calculate P(m,b), Q(m,b) and T(m,b)\n Pmb, Qmb, Tmb = bs(m, b)\n # Now combine\n Pab = Pam * Pmb\n Qab = Qam * Qmb\n Tab = Qmb * Tam + Pam * Tmb\n return Pab, Qab, Tab\n # how many terms to compute\n DIGITS_PER_TERM = math.log10(C3_OVER_24/6/2/6)\n N = int(digits/DIGITS_PER_TERM + 1)\n # Calclate P(0,N) and Q(0,N)\n P, Q, T = bs(0, N)\n one_squared = mpz(10)**(2*digits)\n sqrtC = (10005*one_squared).sqrt()\n return (Q*426880*sqrtC) // T\n\n# The last 5 digits or pi for various numbers of digits\ncheck_digits = {\n 100 : 70679,\n 1000 : 1989,\n 10000 : 75678,\n 100000 : 24646,\n 1000000 : 58151,\n 10000000 : 55897,\n}\n\nif __name__ == \"__main__\":\n digits = 100\n pi = pi_chudnovsky_bs(digits)\n print(pi)\n #raise SystemExit\n for log10_digits in range(1,9):\n digits = 10**log10_digits\n start =time()\n pi = pi_chudnovsky_bs(digits)\n print(\"chudnovsky_gmpy_mpz_bs: digits\",digits,\"time\",time()-start)\n if digits in check_digits:\n last_five_digits = pi % 100000\n if check_digits[digits] == last_five_digits:\n print(\"Last 5 digits %05d OK\" % last_five_digits)\n else:\n print(\"Last 5 digits %05d wrong should be %05d\" % (last_five_digits, check_digits[digits]))\n"},{"cell_type":"code","execution_count":null,"metadata":{},"outputs":[],"source":""}],"nbformat":4,"nbformat_minor":2,"metadata":{"language_info":{"name":"python","codemirror_mode":{"name":"ipython","version":3}},"orig_nbformat":2,"file_extension":".py","mimetype":"text/x-python","name":"python","npconvert_exporter":"python","pygments_lexer":"ipython3","version":3}} \ No newline at end of file