const getPrime = primeMachine(10)
getPrime() // 11
getPrime() // 13
getPrime() // 17
getPrime() // 19
위 함수가 동작될 수 있도록 primeMachine 함수를 제작해라.
getPrime이 처음 실행되면 입력한 수의 다음 소수가 실행되고,
getPrime이 재차 실행될때마다 출력된 수의 다음 소수가 실행된다.
문제를 단계별로 나누어 풀어보자.
1. 구조
- primeMachine을 getPrime에 할당해야하며
- getPrime을 실행할 때마다 인수로 받은 수의 다음 솟수가 출력된다.
따라서 구조는 아래와 같이 될 것이다.
const PrimeMachine = (start) => {
return () => {}
}
2. 소수의 특성을 파악
소수는
- 1보다 큰 값이며,
- 1과 자기자신으로만 나눠 떨어지는 수이다.
3. 어떤 함수를 구현할건가
getPrime이 호출될때마다 다음 번 소수가 출력이 되어야 한다.
함수를 직접 리턴해버리면 모든 함수의 동작이 끝나게된다.
따라서 소수를 찾는 함수를 따로 만들고
그 소수를 찾는 함수의 값을 리턴값으로 받아서
그 값을 리턴해야 한다.
이는 소수를 찾는 함수의 값을 리턴해야 한다는 의미가 된다.
즉, 아래와 같은 구조가 되어야 한다.
const PrimeMachine = (start) => {
return () => {
const result = getPrime
return result
}
}
4. 대략적인 구현
getPrime이 클로저에 의해 계속 동작되기 위해서는
직접적인 값을 리턴해서는 안된다.
다른 함수에서 값만 가져오는 형태로 함수를 구현해야 한다.
즉 getPrime도 다른 함수의 리턴값을 활용해야 한다.
const primeMachine = (start) => {
if (start < 2) {
start = 1
}
if (isPrime(start)) {
start += 1
}
return () => {
const result = getPrime(start)
start = result + 1
return result
}
}
- start가 2보다 작은 수의 경우에는 1로 바꾸어서 소수를 식별하는 함수에 넘긴다.
- isPrime 함수는 해당 수가 소수인지 아닌지 판단하여 소수일 경우 start값에 +1을 추가하여
return으로 넘긴다. - return에서는 받은 값을 가지고 getPrime(start)를 첫번째로 실행한다.
- 해당 수가 소수일 경우, 소수를 return하여 result에 저장한다.
- 다음 start는 result에 +1이 된 상태로 준비하고
- result를 return한다.
5. 최종
const isPrime = (num, i = 2) => {
if(num < 2) return false
if(num === i) return true
if(num % i === 0) return false
return isPrime(num, i + 1)
}
const getPrime = (start) => {
if(isPrime(start)) {
return start
}
return getPrime(start + 1)
}
const primeMachine = (start) => {
if (start < 2) start = 1
if (isPrime(start)) start = start + 1
return () => {
const result = getPrime(start)
start = result + 1
return result
}
}
isPrime = 소수를 구하는 함수
getPrime = 다음 소수를 구하는 함수
primeMachine = 이 함수를 할당받은 함수가 호출될때마다 다음 소수를 리턴하는 함수
테스트케이스
describe('소수값 저장', () => {
it('음수값을 넣었을 때', () => {
const start = -2
const getPrime1 = fn.primeMachine(start)
expect(getPrime1()).toEqual(2)
expect(getPrime1()).toEqual(3)
})
it('소수를 넣었을 때', () => {
const start = 5
const getPrime2 = fn.primeMachine(start)
expect(getPrime2()).toEqual(7)
expect(getPrime2()).toEqual(11)
})
it('합성수를 넣었을 때', () => {
const start = 6
const getPrime3 = fn.primeMachine(start)
expect(getPrime3()).toEqual(7)
expect(getPrime3()).toEqual(11)
})
})
일단 답을 외워버린 것 같은 생각이 든다.
그럼에도 불구하고 얻은 지식.
1. 클로저를 사용하기 위해서 함수를 여러 개 사용할 수도 있다.
2. 문제를 잘게 쪼개서 생각해라.
3. 함수를 생각보다 유연하게 생각해야 한다.
'Javascript' 카테고리의 다른 글
house of primes (소수 입력) (0) | 2022.08.06 |
---|---|
Closure UI (덧셈 Closure 활용) (0) | 2022.08.05 |
소수(Prime number) 구하기 및 jest를 이용한 테스트 케이스 작성 (0) | 2022.08.04 |
입력한 숫자 만큼 문자열 뒤쪽 출력하기 (0) | 2022.08.02 |
(자바스크립트) 문자열 (0) | 2022.08.02 |