当前位置: 移动技术网 > IT编程>开发语言>JavaScript > How to Make Fibonacci Confusing

How to Make Fibonacci Confusing

2018年09月07日  | 移动技术网IT编程  | 我要评论
好端端的”斐波那契“是怎么变成这样的,因吹斯听,我们来回放一下。 ...

前几天同事发了这么一段代码

(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);

猜你看这段代码时,一定是这样的心情:

what the fuck


好端端的斐波那契是怎么变成这样的,因吹斯听,我们来回放一下。

从正常的写法开始:

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!

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网