Calculating with functions

Calculating with functions

This time we want to write calculations using functions and get the results. Let's have a look at some examples:

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 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 Divison should be integer division, e.g eight(dividedBy(three()))/eight(divided_by(three)) should return 2, not 2.666666...

0 ~ 9 까지 각각의 숫자와 산술 연산자로 각각의 함수를 만들어 기본적인 연산을 함수만으로 할 수 있도록 구현하는 문제입니다.

처음에 문제에서 제시한 아래의 requirement를 제대로 읽지 않고, 예제 코드만 보고 문제를 이해하느라고 고민을 많이 했습니다. 문제를 제대로 읽읍시다!

The most outer function represents the left operand, the most inner function represents the right operand

나의 풀이 : - 위와 같이 가장 안쪽의 함수가 가장 오른쪽의 피연산자를, 바깥쪽의 함수가 가장 왼쪽의 피연산자를 의미합니다. - 각각의 함수는 return 값이 있어야 합니다. - 각각의 숫자 함수는 인수를 전달받은 경우 인수의 왼쪽에 자신의 숫자를 추가한 후, 계산된 수를 반환합니다. - 숫자를 전달받지 않은 경우, 자신의 숫자를 반환합니다. - 산술연산자 함수는 인수로 전달받은 숫자(string)의 왼쪽에 자신의 산술연산자를 추가한 후 반환합니다.

function zero(numStr) {
  return !numStr ? 0 : parseInt(eval(0 + numStr));
}
function one(numStr) {
  return !numStr ? 1 : parseInt(eval(1 + numStr));
}
function two(numStr) {
  return !numStr ? 2 : parseInt(eval(2 + numStr));
}
function three(numStr) {
  return !numStr ? 3 : parseInt(eval(3 + numStr));
}
function four(numStr) {
  return !numStr ? 4 : parseInt(eval(4 + numStr));
}
function five(numStr) {
  return !numStr ? 5 : parseInt(eval(5 + numStr));
}
function six(numStr) {
  return !numStr ? 6 : parseInt(eval(6 + numStr));
}
function seven(numStr) {
  return !numStr ? 7 : parseInt(eval(7 + numStr));
}
function eight(numStr) {
  return !numStr ? 8 : parseInt(eval(8 + numStr));
}
function nine(numStr) {
  return !numStr ? 9 : parseInt(eval(9 + numStr));
}

function plus(numStr) {
  return '+' + numStr;
}
function minus(numStr) {
  return '-' + numStr;
}
function times(numStr) {
  return '*' + numStr;
}
function dividedBy(numStr) {
  return '/' + numStr;
}

문제 풀이 완료 후 eval을 사용한 것이 찜찜해 추천이 높은 풀이를 본 순간 제 코드가 오징어처럼 느껴졌습니다. 가장 많은 추천을 받은 코드를 참고 차 가져와 봤습니다.

저의 연산자 함수의 반환 값이 인수로 넘겨받은 숫자에 연산자가 추가된 'string'인 데 반해, 아래의 코드는 연산자와 인수를 저장함 '함수'를 return 합니다. 문제가 calculating with functions 인걸 고려하면 아래와 같이 함수를 사용한 풀이가 문제 제작한 분의 의도인 것 같습니다.

var n = function(digit) {
  return function(op) {
    return op ? op(digit) : digit;
  };
};

var zero = n(0);
var one = n(1);
var two = n(2);
var three = n(3);
var four = n(4);
var five = n(5);
var six = n(6);
var seven = n(7);
var eight = n(8);
var nine = n(9);

function plus(r) {
  return function(l) {
    return l + r;
  };
}
function minus(r) {
  return function(l) {
    return l - r;
  };
}
function times(r) {
  return function(l) {
    return l * r;
  };
}
function dividedBy(r) {
  return function(l) {
    return l / r;
  };
}

number 함수 코드를 읽어보면, 0 ~ 9 까지의 변수에, n 함수를 호출해 반환받은 함수가 담겨있습니다. 그래서 각각의 숫자 함수 (zero, one..)을 호출했을 때, 인자가 없으면 상응하는 숫자를 return합니다. 인자(위의 경우 함수)가 있는 경우 전달받은 함수에 숫자를 전달하고 callback을 호출합니다.

연산자 함수 연산자 함수를 호출하면 인자로 전달받은 숫자를, 연산자 함수가 return한 함수의 r의 값으로 저장합니다.

연산자 함수가 return 한 함수 호출(callback) 연산자 함수가 return 한 함수가 number함수의 인자로 전달됩니다. 이때 number함수의 숫자가 return된 함수, 즉 number 함수에 인자로 전달된 함수에 또다시 인자로 전달된 후 'l'이 이 숫자가 되고 함수가 실행됩니다. 최종적으로 'l' 연산자 'r'의 결과값이 숫자로 반환됩니다.

코드만 보면 단순해 보이는데, 이러한 코드에 익숙해지고 제 머리로도 이러한 코드를 쓸 수 있도록 더 열심히 공부해야겠습니다.