How to Make Fibonacci Confusing
程序员文章站
2023-08-18 09:43:20
好端端的”斐波那契“是怎么变成这样的,因吹斯听,我们来回放一下。 ......
前几天同事发了这么一段代码
(fn => (f => f(f))(f => fn(n => f(f)(n))) )(g => n => [1, 2].indexof(n) > -1 ? 1 : g(n - 1) + g(n - 2) )(10);
猜你看这段代码时,一定是这样的心情:
好端端的斐波那契
是怎么变成这样的,因吹斯听,我们来回放一下。
从正常的写法开始:
const fib = n => [1, 2].indexof(n) >= 0 ? 1 : fib(n - 1) + fib(n - 2);
为了让上面看起来不像递归,改写一下。
把递归调用改成调用参数g
。
const wrappedfib = g => n => [1, 2].indexof(n) >= 0 ? 1 : g(n - 1) + g(n - 2);
不管g
传什么,例如就传null
,1,2两项我都可以计算了,因为压根和g
无关。
wrappedfib(null)(1); wrappedfib(null)(2);
如果要计算第3项,那我的g
就可以是wrappedfib(null)
。
let g = wrappedfib(null); wrappedfib(g)(3);
同理,第4项
let g = wrappedfib(wrappedfib(null)); wrappedfib(g)(4);
第5项......第n项我就不列了
看起来需要构造一个g
,他由无限层的wrappedfib
组成。
递归的思想
const g = n => wrappedfib(g)(n);
运行一下试试吧
const wrappedfib = g => n => [1, 2].indexof(n) >= 0 ? 1 : g(n - 1) + g(n - 2); const g = n => wrappedfib(g)(n); console.log(wrappedfib(g)(10));
题外话
g
本身就是由无限层wrappedfib
组成的
所以wrappedfib(g)
和g
是等价的
因此,也可以直接调console.log(g(10));
const g = n => wrappedfib(g)(n);
又看到了明显的递归对不对,试着把它藏起来,思想跟开始的wrappedfib
函数一样,通过参数传进来,这段要花点时间理解。
const g = (f => n => wrappedfib(f(f))(n))(f => n => wrappedfib(f(f))(n));
方法本身和方法传参是一样的,换个写法
const g = (f => f(f))(f => n => wrappedfib(f(f))(n));
能到这里,我们和最终的代码已经很接近了,把g
中的wrappedfib
去掉,通过参数fn
传进来。
const gwaitforwrappedfib = fn => (f => f(f))(f => n => fn(f(f))(n)); const g = gwaitforwrappedfib(wrappedfib);
好了,去掉const
常量的定义,全部连起来吧
(fn => (f => f(f))(f => fn(n => f(f)(n))) )(g => n => [1, 2].indexof(n) > -1 ? 1 : g(n - 1) + g(n - 2) )(10);
拆解这段代码挺烧脑,膜拜一下代码的作者。
虽然想不出有什么用,但是很有趣,有趣就值得研究:d
code for fun!
上一篇: js坚持不懈之16:使用js向HTML元素分配事件
下一篇: 动物里的音乐冷幽默
推荐阅读
-
How to Make Fibonacci Confusing
-
[Guide] How to make a Wow bot for complete newbs!
-
[Guide] How to make a Wow bot for complete newbs!
-
2.3 How make Processes a Makefile(make如何处理makefile文件)
-
[翻译]C# BAD PRACTICES: Learn how to make a good code by bad example---C#:如何将坏的代码重新编译为好的代码
-
How to Make Fibonacci Confusing
-
How to make your ComboBox more wider enough
-
[翻译]C# BAD PRACTICES: Learn how to make a good code by bad example---C#:如何将坏的代码重新编译为好的代码