CodeWars 쉰 번째 문제

Updated:

Roman Numerals Encoder

public static String solution(int n) {
    String s = "";

    while (n >= 1000) {
        s += "M";
        n -= 1000;
    }
    while (n >= 900) {
        s += "CM";
        n -= 900;
    }
    while (n >= 500) {
        s += "D";
        n -= 500;
    }
    while (n >= 400) {
        s += "CD";
        n -= 400;
    }
    while (n >= 100) {
        s += "C";
        n -= 100;
    }
    while (n >= 90) {
        s += "XC";
        n -= 90;
    }
    while (n >= 50) {
        s += "L";
        n -= 50;
    }
    while (n >= 40) {
        s += "XL";
        n -= 40;
    }
    while (n >= 10) {
        s += "X";
        n -= 10;
    }
    while (n >= 9) {
        s += "IX";
        n -= 9;
    }
    while (n >= 5) {
        s += "V";
        n -= 5;
    }
    while (n >= 4) {
        s += "IV";
        n -= 4;
    }
    while (n >= 1) {
        s += "I";
        n -= 1;
    }
    return s;
}
  • 이번 문제는 알고리즘은 쉬웠는데 로마숫자를 표현(?)하기가 까다로웠다. 알고리즘이 까다롭다는 얘기인가?
  • 내 코드의 경우 while문이 반복이 되었다. 이 경우 s와 n을 포함한 객체로 빼내어서 while에 대한 메소드로 리펙토링 해도 괜찮을 듯 싶었으나 그냥 내비 두었다.
  • Best 코드의 경우 여러가지가 있었다. 하지만 내가 보기에 가장 괜찮았던 best 코드는 다음과 같았다.
public String solution(int n) {
    final String[] digit = {"", "I", "II", "III", "IV", "V", "VI", "VII","VIII", "IX"};
    final String[] ten = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX","LXXX", "XC"};
    final String[] hundred = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC","DCCC", "CM"};
    final String[] thousand = {"", "M", "MM", "MMM"};

    return thousand[n/1000] + hundred[n%1000/100] + ten[n%100/10] + digit[n%10];
}
  • 다른 코드들의 경우 for 을 두 번 쓰거나 수식이 많아서 한 번에 보기 힘들었다.
  • 허나 위의 best 코드의 경우 경우의 수가 정해져 있기 때문에 각 자리숫자(1000, 100) 등으로 나누어 나온 수에 맞는 final에서 찾아 그대로 반환하는 쉬운 알고리즘으로 되어 있다.
  • 어차피 다른 코드의 경우에는 4(or 40, 400) 와 9(90, 900)에 대한 숫자 처리로 코드가 늘어질 수 밖에 없었다. 코드 확장성을 배제할 경우에는 위가 최고인듯 하다.