Codewars 문제풀기 (05/26)

Roman Numerals Encoder

  • int를 입력으로 받는다.

  • 입력받은 정수를 로마표기법으로 리턴한다.

    conversion.solution(1990) 👉 MCMXC
    conversion.solution(2008) 👉 MMVIII
    conversion.solution(1666) 👉 MDCLXVI
    

1. Test와 리팩토링

  • 테스트 1 - 입력이 1,2,3일때 I,II,III를 리턴한다.

  • 테스트 2 - 입력이 4일때 IV를 리턴한다.

  • 테스트 3 - 입력이 5,6,7,8일때 V,VI,VII,VIII를 리턴한다.

  • 테스트 4 - 입력이 1666일때 MDCLXVI를 리턴한다.

    • 테스트 코드
    • 실제 코드
      • 1000, 900, 500, 400 … 모든 로마표기법에 대한 if문을 만들었다. 문제의 모든 테스트도 통과는 했는데 코드가 좀 더럽다. if/else if문을 사용하는게 별로 안좋다고 “클린 코드”에서 배웠다.
    • 리팩토링
      • TreeMap을 이용했다. TreeMap은 Key들을 정렬해서 저장하는데, 문제는 오름차순 정렬이기 때문에 map.keySet()으로 key들을 불러올때 작은 Key값부터 불러온다. 그렇게되면 1000 = M이 아니라 1000 = IIII….이 될것이다. 그래서 내림차순 정렬을 위해 생성자에서 Comparator.reverseOrder()를 이용해서 내림차순으로 Key값들을 정렬했다.
      • 반복문을 통해 Key들을 불러오고 불러온 Key값보다 입력 n이 더 크면 key에 대한 로마 표기법 value를 result에 붙여준다.
      • 코드는 확실히 짧아졌다. 그런데 2중for문을 사용해서 처음 코드보다 느린거 같다. 어느게 더 좋다고 할 수 있을까?? 잘 모르겠다..

2. 답 비교, 느낀점

Best Practice 가장 많이 받은 코드

public class Conversion {

    public String solution(int number) {
        String romanNumbers[] = {"M", "CMXC", "CM", "D", "CDXC", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
        int arab[] = {1000, 990, 900, 500, 490, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
        StringBuilder result = new StringBuilder();
        int i = 0;
        while (number > 0 || arab.length == (i - 1)) {
            while ((number - arab[i]) >= 0) {
                number -= arab[i];
                result.append(romanNumbers[i]);
            }
            i++;
        }
        return result.toString();
    }
}
  • Map을 배열로 표현한것 외에는 2중 반복문을 사용한것은 같다. best practice가 이거인걸 보면 리팩토링한 코드가 더 좋은 코드가 맞는거라고 생각해도 되겠…..지?
  • 다른 코드들을 봐도 if / else if문을 사용한 코드는 없었다.

댓글남기기