프로그래밍/함수형 프로그래밍

[함수형 프로그래밍 연습하기] 프로그래머스 Level1 - 약수의 개수와 덧셈

mhko411 2021. 8. 5. 08:51
728x90

함수형 프로그래밍으로 프로그래머스 문제 풀면서 함수형 프로그램을 이해하고 연습하기

처음에는 코드가 이상할 수도 있지만 공부를 하면서 점점 좋은 코드로 다듬기


https://programmers.co.kr/learn/courses/30/lessons/77884

 

코딩테스트 연습 - 약수의 개수와 덧셈

두 정수 left와 right가 매개변수로 주어집니다. left부터 right까지의 모든 수들 중에서, 약수의 개수가 짝수인 수는 더하고, 약수의 개수가 홀수인 수는 뺀 수를 return 하도록 solution 함수를 완성해주

programmers.co.kr


이번 문제를 풀 때는 역할 별로 함수를 구분하는 것에 신경을 썼다. 약수인지 판단하는 함수, 홀수인지 짝수인지 판단하는 함수, 약수의 개수를 구하는 함수, 조건에 따라 더하거나 빼는 함수를 구현하였다.

 

구현

- 먼저 코드가 시작되는 solution 함수이다. 

- 숫자의 범위가 left, right로 주어지고 해당 범위를 탐색하면서 약수의 개수가 짝수일 때 더하고, 홀수일 때는 빼야한다.

- 따라서 left와 right 사이를 탐색하면서 counterFactor 함수에 숫자를 전달하여 약수의 개수를 판단한다.

- 이후 약수의 개수를 isOdd 함수에 전달하여 홀수인지 검사하고

- 홀수일 때는 acc 함수에 두 개의 숫자를 빼도록하고 짝수일 때는 두 개의 숫자를 더하도록한다.

function solution(left, right) {
  let answer = 0;
  for (let i = left; i <= right; i++) {
    answer = isOdd(countFactor(i))
      ? acc((a, b) => a - b, answer, i)
      : acc((a, b) => a + b, answer, i);
  }
  return answer;
}

- countFactor 함수에서는 약수의 개수를 구하며

- 이 과정에서 약수인지 판단하는 함수에 전달하고 true 값을 반환한다면 count를 증가시킨다.

function countFactor(number) {
  let count = 0;
  for (let i = 1; i <= number; i++) {
    if (isFactor(number, i)) ++count;
  }
  return count;
}

function isFactor(a, b) {
  if (a % b) return false;
  return true;
}

- 위에서 구한 약수의 개수를 isOdd를 통해 홀수인지 짝수인지 판별하도록 한다.

function isOdd(number) {
  if (number % 2) return true;
  return false;
}

- 아래의 함수는 두 개의 수인 sum과 n을 입력받아 f를 실행하여 결과를 반환하는 것이다.

- 홀수일 때는 f에 두 개의 수를 빼는 함수가 오고, 짝수일 때는 f에 두 개의 수를 더하는 함수가 오도록한다.

function acc(f, sum, n) {
  return f(sum, n);
}

전체 코드

function isOdd(number) {
  if (number % 2) return true;
  return false;
}

function countFactor(number) {
  let count = 0;
  for (let i = 1; i <= number; i++) {
    if (isFactor(number, i)) ++count;
  }
  return count;
}

function isFactor(a, b) {
  if (a % b) return false;
  return true;
}

function acc(f, sum, n) {
  return f(sum, n);
}

function solution(left, right) {
  let answer = 0;
  for (let i = left; i <= right; i++) {
    answer = isOdd(countFactor(i))
      ? acc((a, b) => a - b, answer, i)
      : acc((a, b) => a + b, answer, i);
  }
  return answer;
}