첫 프로젝트 오일러 포스팅입니다.
(사실 4번까지 풀었지만 올리기 귀찮음으로 인하여 미루다가 이제서야 올립니다..)
문제는 아래와 같습니다.
10보다 작은 자연수 중에서 3 또는 5의 배수는 3, 5, 6, 9 이고, 이것을 모두 더하면 23입니다.
1000보다 작은 자연수 중에서 3 또는 5의 배수를 모두 더하면 얼마일까요?
※ 이 문제에서 1000보다 작은 자연수라는 조건에는 1000도 포함입니다.
코드를 작성함에 있어서 가장 기본적인 원칙은 아래와 같습니다.
public class MultipleOf3And5 {public int getSumOf(int inputNumber) {int result = 0;for(int number=1;number<=inputNumber;number++){if(number%3 == 0 || number %5 == 0){result += number;}}return result;}}
TDD 규칙 1. TDD는 테스트를 먼저 만드는 것으로부터 시작합니다. (Test First)
가장 간단한 정답을 하드코딩으로 통과시킨다. (1 이하의 수에서 3과 5의 배수의 합은 0.)
해당 테스트를 하드코딩으로 통과시킵니다.
Step 2. 그 다음으로 간단한 테스트는 무엇일까? 3으로 해봅니다.
3 또한 하드코딩으로 통과시킵니다.
여기서부터는 테스트 작성 단계는 생략하고 문제 풀이 과정만 올리겠습니다.
5 이하의 자연수에서 3과 5의 배수의 합은 3 + 5 = 8입니다.
역시나 우선 하드코딩!
자, 이제 리팩토링을 할 단계입니다.
하드코딩 된 결과값 사이에서 규칙을 찾아내고, 중복을 제거하고, 일반화를 하는 과정이죠.
8은 사실 3과 5를 더한 결과값입니다.
return 값을 result라는 그릇에 담도록 하죠.
아래와 같은 형태로 바꿔보았습니다.
형태를 계속 바꿔주는 것은 최대한 중복되는 형태로 만들어서 일반화시키기 위함입니다.
무슨 말인지 잘 이해가 안가시는 분도 다다음 단계까지 따라오세요 :)
이제부터 일반화의 시작점입니다.
이전 단계에는 드러나지 않았지만 사실 아래와 같은 원리가 숨겨져 있습니다. (눈에 보이지 않는 규칙을 찾아내기)
다른 곳에도 이렇듯 보이지 않는 규칙이 적용되지요.
이쯤에서 프로그래밍을 해보신 분들은 뭔가 보이지 않나요~?
아래와 같이 반복문을 써서 코드의 양을 줄이고 일반화시킬 수 있습니다. (하드코딩의 일반화)
이 코드는 아래와 같이 조금 더 깔끔하게 쓸 수 있겠군요 (리팩토링)
i라는 의미없는 이름보다는 number로 바꾸어 보았습니다. (리팩토링)
자, 이렇게 5라는 입력값이 들어왔을때 일반화된 솔루션을 도출해 낼 수 있게 되었습니다.
그렇다면 하드코딩되어 있는 4와 3에도 이 솔루션을 적용해 볼 수 있을까요?
아래와 같이 4와 5에도 동일한 솔루션을 이용하여 문제를 해결할 수 있습니다.
(테스트 코드가 존재하기 때문에 이것을 바로 알 수 있습니다.)
3, 4, 5 모든 if문에서 동일한 방법을 이용하여 문제를 해결하고 있습니다.
이것을 하나로 묶어주면 아래와 같이 진정으로 일반화된 솔루션 (Generalized Solution)이 완성되었습니다.
그럼 이 솔루션이 1000 이하의 3과 5의 배수의 합을 구하는 문제를 풀 수 있을까요?
음..오랜만에 글을 써서 마무리 짓는것이 상당히 어색하네요.
TDD에 관하여 너무 짧게 설명한 것 같아서 약간만 보충을 하겠습니다.
TDD는 아래와 같은 3 Steps로 이루어집니다.
1. 실패하는 테스트 코드를 먼저 작성한다. (가장 단순한 케이스로)
2. 하드코딩을 이용하여 가장 간단하게 통과시킨다.
3. 리팩토링을 한다.
의심의 여지 없이 TDD에서는 3. 리팩토링이 핵심이라고 생각하는데 글로 짧게 설명하기는 꽤 어렵습니다.
(위의 간단한 3단계 Step에 대해서만도 십수권의 책이 나올 정도니까요.)
TDD를 하다 보면 자주 나오는 패턴은 눈에 보이지 않는 규칙들을 발견하고, 중복을 인위적으로 생성한 다음 리팩토링을 한다는 것 정도입니다.
저도 계속 배우고 적용하는 단계이니 뭔가 깨닫는 것이 있다면 포스팅에 함께 올리도록 할게요.
이 문제는 사실 쉬운 편에 속해서 굳이 TDD와 같은 개발 기법을 사용할 필요가 없을 수도 있지만
쉬운 문제부터 TDD를 적용해서 풀어본다면 나중에 어려운 문제가 나오더라도 TDD를 적용하여 익숙하게 풀 수 있을 거에요.
이상으로 첫 프로젝트 오일러 문제 풀이 포스팅을 마치도록 하겠습니다 :)
새로운 프로그래밍 언어로 어떤 것을 배울까.. (0) | 2015.12.23 |
---|---|
[프로젝트 오일러] 피보나치 수열에서 4백만 이하이면서 짝수인 항의 합 (0) | 2015.12.18 |
프로젝트 오일러 시작 (0) | 2015.12.14 |
jsp compile 관련 500 오류 (1) | 2015.12.07 |
레거시 코드 리팩토링은 무엇이며 왜 필요할까 (1) | 2015.12.06 |
댓글 영역