Code Kata Day 6

SYhwang·2023년 1월 30일
0

코드카타

목록 보기
6/10

문제

로마자에서 숫자로 바꾸기

1~3999 사이의 로마자 s를 인자로 주면 그에 해당하는 숫자를 반환해주세요.
로마 숫자를 숫자로 표기하면 다음과 같습니다.

Symbol       Value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

로마자를 숫자로 읽는 방법은 로마자를 왼쪽부터 차례대로 더하면 됩니다.
III = 3
XII = 12
XXVII = 27
입니다.

그런데 4를 표현할 때는 IIII가 아니라 IV 입니다.
뒤의 숫자에서 앞의 숫자를 빼주면 됩니다.
9는 IX입니다.

I는 V와 X앞에 와서 4, 9
X는 L, C앞에 와서 40, 90
C는 D, M앞에 와서 400, 900

풀이

function romanToNum(s) {


  const roman = {
    I : 1,
    V : 5,
    X : 10,
    L : 50,
    C : 100,
    D : 500,
    M : 1000,
  }
  
  let number = 0;
  for (let i =0; i<s.length; i++) {
    if(roman[s[i]] < roman[s[i+1]]) {
        number += (roman[s[i+1]] - roman[s[i]]);
        i++;
    } else { 
        number += roman[s[i]]
    }
  }
   return number
}
  • 발상 : 로마자를 한 글자씩 쪼갠 뒤 찾는 정보를 객체의 속성으로 접근해서 변환한다
  1. 로마 숫자를 key로, 아라비안 숫자를 value로 가진 객체 roman 을 선언했다.
  2. 변환된 아라비아 숫자를 저장할 변수 number를 let으로 선언했다.
  3. for 문에서 s[i]를 이용해 문자열 s를 인덱스 순서대로 한 글자씩 접근하는 반복문 안에서
  4. if 조건문으로 앞 글자와 뒷 글자의 아라비안 숫자 중 앞이 더 작다면 (예 : 로마자 IV 에서 I는 1, V는 5)
    number에 뒷 문자를 키로 가진 roman의 value(예 : 5) 에서
    앞 문자를 키로 가진 roman의 value(예 : 1) 을 뺀 값을 더한다.
    ( i가 마지막 인덱스일 때에는 if 안의 조건이 (roman[s[i]] < undefined ) 가 되므로 자동으로 false가 된다 )
  5. 그리고 다음 for 반복에서 I 뒤의 V를 추가로 변환하지 않기 위해서 인덱스를 하나 건너뛸 수 있게 i에 1을 더해준다.
  6. if 안의 조건이 true가 아닐 때 (예 : XI) 는 number에 s[i]를 키로 가진 roman의 value(예: i=0일 때 X의 value는 10, i=1일 때 I의 value는 1) 를 차례대로 더해준다.
  7. 반복이 끝나면 number를 반환한다.
  • 분명 생각한 대로 잘 로직을 짠 것 같은데 중간에 통과하지 못하는 테스트 케이스가 여럿 나와서 당황했다. 알고 보니 roman[s[i]] < roman[s[i+1]] 로 비교해야 하는 조건에서 s[i] < s[i+1] 으로 비교하고 있었다.
  • 문제가 생긴 테스트 케이스를 콘솔로 찍어보며 어느 부분에서 오류가 일어났는지 찾아보니 X와 C를 비교하는 부분이었다. X(값 10)는 C(값 100)보다 작은데 왜 조건문이 false가 나오지? 라는 의문이 들어 자세히 보다가 발견했다.
    10 < 100 으로 비교하는 대신 X < C로 비교하고 있었던 셈인데 문자끼리도 비교 연산자를 통해 비교했을 때 true 혹은 false의 값이 나온다는 것을 처음 알았다.
  • 해당 부분에서 s[i]와 s[i+1]을 각각 콘솔로 찍어봤으면 한눈에 찾았을 텐데 콘솔을 적재적소에 활용하는 부분이 아직 미숙하다는 것을 느꼈다.
    또한 숫자끼리 비교하지 않으면 NaN나 undefined 등이 나올 거라고 생각하고 있었기에 해당 부분의 로직이 틀렸다는 것을 빠르게 찾지 못했다. 막연히 이럴 것이다라고 생각하지 말고 확실한지 아닌지 늘 확인하는 자세를 가져야겠다.

0개의 댓글