관리 메뉴

밤색모자이크의 개발이야기

Project Euler Problem 17 : 1부터 1000까지 영어로 썼을 때 사용된 글자의 개수는? 본문

Algorithm/Project Euler

Project Euler Problem 17 : 1부터 1000까지 영어로 썼을 때 사용된 글자의 개수는?

밤색모자이크 2017. 6. 19. 10:54


Project Euler 문제를 해답을 포스팅합니다.

※ 주의 : 최적화는 할 수 있는 만큼했습니다. 따라서 속도면에서는 많이 부족합니다.

           문제를 푸는데 목표를 두었고 또한 TDD를 최대한 활용하였습니다.

           몇가지 문제의 경우 TDD를 안한 경우도 있습니다.

           혹시, 최적화 또는 속도 증가에 대한 부분을 지적해주실 분은 너무나도 감사합니다.



Project Euler Problem 17


1부터 5까지의 숫자를 영어로 쓰면 one, two, three, four, five 이고,
각 단어의 길이를 더하면 3 + 3 + 5 + 4 + 4 = 19 이므로 사용된 글자는 모두 19개입니다.

1부터 1,000까지 영어로 썼을 때는 모두 몇 개의 글자를 사용해야 할까요?

참고: 빈 칸이나 하이픈('-')은 셈에서 제외하며, 단어 사이의 and 는 셈에 넣습니다.
  예를 들어 342를 영어로 쓰면 three hundred and forty-two 가 되어서 23 글자,
  115 = one hundred and fifteen 의 경우에는 20 글자가 됩니다.




여기서 주의할 점은 hunderd 앞에는 100이면 one 붙습니다.

마찬가지로, thousand도 앞에 one 붙습니다. 이거 못찾아서 1시간 헤맸네요.

제가 푼 방법은 String으로 변환하여 길이 체크하였습니다. 숫자별로 함수 구현해놨는데

결국에는 convert 하나 쓰고 말았네요. TDD 좀더 공부해야겠습니다.




Source Code


TestClass Code

public class TestClass { 

    @Test 
    public void numberToString_convertTest() {
        int testNum = 342;
        int testNum2 = 1000;
        NumberToString nts = new NumberToString(); 
         
        assertEquals("threehundredandfortytwo", nts.convert(testNum)); 
        assertEquals("onehundred", nts.convert(100)); 
    } 
     
    @Test 
    public void numberToString_20to90Test() {
        NumberToString nts = new NumberToString(); 
         
        int testNum1 = 20;
         
        testNum1 /= 10; 
        assertEquals(nts.string_20to90[2], nts.convert_20to90(testNum1));
    } 
     
    @Test 
    public void numberToString_1to19Test() {
        NumberToString nts = new NumberToString(); 
         
        int testNum1 = 5;
        int testNum2 = 19;

        assertEquals("five", nts.convert_1to19(testNum1)); 
        assertEquals(nts.string_1to19[19], nts.convert_1to19(testNum2));
    } 
}

Main Class Code

public class Main { 
    public static void main(String [] args) {
        NumberToString nts = new NumberToString(); 
         
        int result = 0; 
        for(int i=1; i<=1000; i++) { 
            String str = nts.convert(i); 
            result += str.length(); 
        } 
         
        System.out.println(result); 
    } 
}


NumberToString Class Code
public class NumberToString {
     
    public static String [] string_1to19 =
        { "", "one",         "two",             "three",         "four",         "five" 
            , "six",         "seven",         "eight",         "nine",         "ten" 
            , "eleven",     "twelve",         "thirteen",     "fourteen",     "fifteen" 
            , "sixteen",     "seventeen",     "eighteen",     "nineteen" 
        }; 
     
    public static String [] string_20to90 = 
        { "", "" 
            , "twenty",     "thirty",         "forty",         "fifty" 
            , "sixty",         "seventy",         "eighty",         "ninety" 
        }; 
     
    public static String hundred = "hundred"; 
    public static String thousand = "thousand"; 
     
    public String convert_1to19(int number) {
        return string_1to19[number]; 
    } 

    public String convert_20to90(int testNum1) {
        return string_20to90[testNum1]; 
    } 

    public String convert(int number) {
        String result = ""; 
         
        int hundredNum = number/100;
        int teenNum = number%100; 
         
        if(number == 1000) { 
            return result += "one" + thousand; 
        } 
         
        if(hundredNum != 0) { 
            result += string_1to19[hundredNum] + hundred; 
            if(teenNum != 0) result += "and"; 
        } 
         
        if( teenNum >= 1 && teenNum < 20) {
            result += string_1to19[teenNum]; 
        } 
        else { 
            int teen = teenNum/10;
            int oneNumber = teenNum%10; 
             
            result += string_20to90[teen] + string_1to19[oneNumber]; 
        } 
         
        return result; 
    } 
}


Comments