题目要求
This time we want to write calculations using functions and get the results. Let's have a look at some examples:
seven(times(five())); // must return 35
four(plus(nine())); // must return 13
eight(minus(three())); // must return 5
six(dividedBy(two())); // must return 3
Requirements:
There must be a function for each number from 0 ("zero") to 9 ("nine")
There must be a function for each of the following mathematical operations: plus, minus, times, dividedBy (divided_by in Ruby and Python)
Each calculation consist of exactly one operation and two numbers
The most outer function represents the left operand, the most inner function represents the right operand
Division should be integer division. For example, this should return 2, not 2.666666...:
eight(dividedBy(three()));
解题思路
根据题目,题目要求通过运行函数的方式来实现10以内的加减运算。如要执行3*5
。那么对应的调用函数为
three(times(five()))
其运行结果应该为15
。
通过初步的观察,我们可以得到两个信息。
- 数字函数(这里我们将three()等函数称作数字函数)可能有参数,也可能无参数。
- 运算函数(这里我们将plus()、times()等函数称作运算函数)必有参数。
在上述例子中,three(times(five()))
five没有参数传递。而three有参数,且参数为操作函数times执行结果。而times函数存在参数,且参数为five函数的操作结果。因此我们可以大概的将我们的函数写成下述形式:
//数字函数
function three(fn) {
if (fn != undefined) {
//code...
}
else {
//code...
}
}
//操作函数
function times(fn) {
//code...
return //something...
}
再仔细观察题目中给的函数执行情况,其顺序如下:
- 先执行five函数,并将five函数执行结果作为一个参数传递给times函数。
- times函数使用five函数的执行结果作为参数运行,运行完成之后将执行结果作为参数给three函数。
- three函数使用times函数执行结果作为参数进行运行,最后将结果输出。
可以观察到,函数是由内往外执行,并且内层函数都会将执行结果返回给外层函数做运算。接下来,从内往外的来分析下这道题:
首先我们看five函数,他应该要做什么?在这里,它似乎不需要做过多的工作,它只要将当前函数对应的值(如three对应3)作为返回值交给times函数使用即可。因此我们可以得到数字函数中,当函数无参数时。只要直接返回其对应值即可。如下:
function five(fn) {
if (fn != undefined) {
//code...
}
else {
return 5;
}
}
然后接下来,我们来到times函数,这里的times函数应该做什么工作呢?按照平常的想法,这里应该进行对应的四则运算,但是四则运算需要两个操作数。而在上一步中,我们已经将five函数的执行结果5
作为参数给了times函数。此时它应形如:
function times(5){
//code...
return //something...
}
可见此时我们只有一边的操作数,另一个操作数还在外层。我们无法对其进行调用,那么要如何使得两个操作数都能得到以便四则运算的正常运行呢?
没错!就是闭包,根据闭包的定义,如果我们在times函数中声明一个函数,函数内让其进行乘的操作,且右操作数为five的执行结果,即参数。然后将该函数返回,当函数返回后将会进入最外层的three函数,此时因为times的返回值是一个函数,而这个函数又作为参数传递给了three,因此在three函数中。我们将three函数的对应值再作为参数传给times函数返回的函数,再执行该函数,这样就可得到我们想要的结果。
所以我们可以写出times的函数应当如下:
function times(fn){
//此处的y是给外层函数传参使用的
return function(y){y*fn}
}
而three函数也变得明了起来。只要想times函数传递对应值并将函数执行结果返回即可。 代码如下:
function three(fn){
if(fn != undefined) return fn(3)
else //...
}
three函数和five函数相结合,我们便得到了数字函数通用的式子
//这里将对应的num和numName替换即可,如numName为three,则后面的num就替换成3
fnction numName(fn){
fn != undefined?fn(num):num
}
而操作函数形如下:
//同上,这里的opName和op也进行相应替换,如opName为plus则后面的式子为 y + fn
function opName(fn){
return function(y){y op fn}
}
到这里,这个问题基本解决了。但是要注意下,题目中要求除法要返回整型,所以在除法的返回值中,添加一个parseInt
进行转换即可。