[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[原创代码] 无忧公主项数定律

本帖最后由 happy886rr 于 2016-4-10 21:13 编辑

  关注无忧公主微信号之后,看到许多奇妙问题。有几个都是关于斐波那契数列的。这个数列到底有多奇妙?百度一下才知道:斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89...,即后一项等于之前两项之和。也没感觉有多奇妙,就是个普通加法,而且它的定义很怪,第0项是0,第1项是第一个1。

  但是无忧公主说了斐波那契数列第 12 项为 144,是第一个包含 3 个数字的斐波那契数。那第一个包含 1000 个数字的斐波那契数,它的项数是几?我们不妨把它叫做无忧公主项数。还是编程挑战题,限于自己只会批处理,bat模拟大数又太累,字符串也不能超过1024个,无奈跑到python自学网充了下电。

  Cool!,原来python这么好用啊!一个len就能表示字符串位数,这下有解了。斐波那契数我只要一个劲的加,每次判断它的位数是不是等于1000,答案不就出来了。于是按照批处理的思路写了一个python,不管它语法规范不规范了,自己也不晓得。
  1. # Python 解无忧公主的编程挑战004:第一个1000位的斐波那契数的项数是
  2. F1=0;F2=1;n=1;l=1
  3. while l<1000:
  4. Fn=F1+F2;F1=F2;F2=Fn;n+=1
  5. l=len(str(Fn))
  6. print(n)
  7. # 偶然发现使用 while F2<10**999: 来中断循环用时最省.
复制代码
  运行结果是4782,到底对不对,于是又拼了一个python用来打印斐波那契数列和它的项数、位数。
  1. # 斐波那契数项数与位数打印
  2. print("斐波那契数Fn  项数n  位数")
  3. F1=0;F2=1;n=1
  4. while n<1000:
  5. Fn=F1+F2;F1=F2;F2=Fn;n+=1
  6. print(Fn,"(",n,",",len(str(Fn)),")")
复制代码
  把结果保存到了txt,当我打开txt,Cool!,这些数字末端堆积的形状怎么看怎么像一条斜线。形状这么规则,不由得一惊。数字末端的位置不就是数字的长度吗,行号不就是项数吗。形状像条斜线,难不成是线性关系,无奈不会python绘图线性拟合,拿批处理线性拟合了一下,得到了一个近似关系:无忧公主项数=4.78*位数-2.39

  只是近似线性关系,用这个近似公式每次求出来的结果和正确值比对不是差1就是差0,看来用数学无法描述它的准确关系。百度到python中int就可以取整,恍然大悟,用int就可以把小数部分引起的扰动过滤掉,这样就不会老是差1或不差。思路来了,最终用python结合特征根将这个线性扰动拟合描述出来了,发现网上没有任何资料介绍过这个奇妙关系。干脆起个名算了就叫 ”斐波那契-无忧公主项数定律“吧。

  第一个L位的斐波那契数的项数N是:
  1. # 斐波那契-无忧公主项数定律
  2. N=int((L-1+0.5*math.log10(5))/math.log10((1+5**0.5)/2))+1
  3. # 斐波那契位数估值式
  4. L=int((N*math.log10((1+5**0.5)/2))-math.log10(5**0.5))+1
复制代码
  这下就跳过了不断的加加+...,就有了最优解法,几乎不需时间。
  1. # 线性拟合一行流
  2. import math;L=1000;N=int((L-1+0.5*math.log10(5))/math.log10((1+5**0.5)/2)+1);print(N)
复制代码
2

评分人数

本帖最后由 codegay 于 2016-4-10 00:32 编辑

这个题是欧拉计划,第25题。
注册后可以提交答案。

https://projecteuler.net/problem=25

python代码风格指南:pep8 中文翻译
http://my.oschina.net/u/1433482/blog/464444?p=1
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

回复 2# codegay
难道是无忧公主剽窃了欧拉计划的题目,我还以为是无忧公主出的题目。不过python确实太好用,感觉批处理智能化太低。

TOP

XD

TOP

回复 3# happy886rr

-_-!她的题目来源应该是某些书上,
她好像有参加算法赛,应该也有算法赛的题目。

除了欧拉计划这类网站,还有一类是编程考试或者程序算法类的练习网站。

不过她的解题思路视频或者语音都是自己录的。
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

回复 5# codegay
听声音像是个小女孩,不知是不是女孩,还是幕后有个团队在运作。

TOP

回复 6# happy886rr


    是小学生。大量的视频和录音都是她一个人。
而且英语很好.

教育条件很好,智商也很高。
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

  1. #=
  2. julia解欧拉计划025 1000-digit Fibonacci number.jl
  3. 2016年4月9日 15:33:05 codegay
  4. 两个方法解法一样,一个是比较字符数量,一个是比较数字大小。
  5. =#
  6. counter=1
  7. a=big(0)
  8. b=big(1)
  9. while length(string(b))<1000
  10.     a,b=b,a+b
  11.     counter=counter+1
  12. end
  13. println(counter)
  14. #=
  15. 4782
  16. [Finished in 3.7s]
  17. =#
  18. function ff2()
  19.     f1=big(0)
  20.     f2=big(1)
  21.     counter=1
  22.     while f2<big(10)^999
  23.         f1,f2=f2,f1+f2
  24.         counter+=1
  25.     end
  26.     println(counter)
  27. end
  28. @time ff2()
  29. #=
  30. 4782
  31.   0.050925 seconds (90.95 k allocations: 4.712 MB, 54.44% gc time)
  32. [Finished in 4.4s]
  33. =#
复制代码
1

评分人数

去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

回复 8# codegay
批处理花了3分钟才算出来。进行了5000次数百位大数加法。
  1. REM 解无忧公主的编程挑战004:第一个1000位的斐波那契数的项数是
  2. @echo off&setlocal enabledelayedexpansion
  3. set "Fa[1]=00000001"
  4. set "Fb[1]=00000001"
  5. for /l %%i in (2 1 125) do (
  6. set "Fa[%%i]=00000000"
  7. set "Fb[%%i]=00000000"
  8. )
  9. for /l %%n in (3 1 5000) do (
  10. set add=0
  11. for /l %%i in (1 1 125) do (
  12. set/a Fn[%%i]=1!Fa[%%i]!+1!Fb[%%i]!
  13. set/a tmp=Fn[%%i]+add
  14. set Fa[%%i]=!Fb[%%i]!
  15. set Fb[%%i]=!tmp:~1!
  16. if !tmp! geq 300000000 (set add=1) else (set add=0)
  17. )
  18. if not "!Fb[125]:~0,1!"=="0" (set/p =%%n&exit)
  19. )
复制代码
1

评分人数

TOP

回复 9# happy886rr


    你们能拿批处理做大数运算的都太强。
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

本帖最后由 CrLf 于 2016-4-10 12:52 编辑

回复 9# happy886rr


咳咳咳...还有更快的批处理吗?
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a len=9,n[0]=1,n[1]=2
  3. for /l %%n in (4 1 5000) do (
  4. set /a n[0]=n[1],n[1]+=!n[0]!
  5. if !n[1]! gtr 999999999 (
  6. set /a len+=1,n[0]/=10,n[1]/=10
  7. if !len!==1000 (set/p =%%n&exit)
  8. )
  9. )
复制代码
怪异代码风采大赛参赛作品:
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a len=9,n[0]=1,n[1]=2
  3. (for /l %%n in (4 1 5000) do (
  4. set /a "n[0]=n[1],n[1]+=!n[0]!,1/^!((n[1]=last+n[0])/1000000000)"||(
  5. set /a "1/(1000-(len+=1)),n[0]/=10,n[1]/=10"||set/p =%%n&&exit
  6. )
  7. ))2>nul
复制代码
参赛作品2:
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a len=9,n[0]=1,n[1]=2
  3. (for /l %%n in (4 1 5000) do (
  4. set /a "n[0]=n[1],n[1]+=!n[0]!,1/((n[1]=last+n[0])/1000000000),len+=1,n[0]/=10,n[1]/=10"&&(
  5. if !len!==1000 set/p =%%n&&exit
  6. )
  7. ))2>nul
复制代码
2

评分人数

TOP

回复 11# CrLf
斐波那契数列中的本福特定律:
    以1为首位数字的数的出现机率约为总数的三成,接近期望值1/9的3倍。推广来说,越大的数,以它为首几位的数出现的就越低。
大师眼力非凡,一下就看到了捷径。这个方法应该是最佳方案,无需安装语言。速度居然还超过了python好几倍。

TOP

本帖最后由 CrLf 于 2016-4-10 14:08 编辑

回复 12# happy886rr


    本福特定律是顶楼方案,我这是只对头部相加,避开大数运算

TOP

本帖最后由 happy886rr 于 2016-4-10 14:35 编辑

回复 13# CrLf
大师这是用的失传已久的抛出错误。顶楼方案不是本福特,用的线性拟合。外加特征根推导出是黄金分割律的对数式。
您的只加头部基于的原理正好是本福特定律。因为开头的数字是5到9的可能性小。

TOP

不明觉厉
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

返回列表