Code Kata | Review(2)

이진웅·2021년 12월 6일
0

알고리즘

목록 보기
2/14
post-thumbnail

문제

로마자를 숫자로 바꾸기

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

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이 됩니다.

나의 접근법

이번 문제는 처음에 어떻게 풀어야할지 감이 오질 않았다.
일단은 문제에 나온 자료가 뭔가 object구조같이 생겨서 저걸 object로 선언하고,
.map() 메서드를 이용해 로마자를 숫자로 변경해 정답을 찾아야겠다고는 생각했다.

하지만 IV, IX, CD와 같은 숫자들은 어떻게 따로 처리해야 될 지 고민이 많았다.
그래서 로마숫자에 대한 정보를 구글링해보니 Roman Numerals Converter 라는 페이지를 찾았고,
로마숫자가 구성될 때 VI, XI 같이 반대로 된 숫자는 4나 9처럼 빼지지 않고, 6과 11이 된다는걸 확인했다.
또한 VX같은 숫자는 존재하질 않아서 고려할 필요가 없었다.

그래서 첫번째 로마자보다 두번째 로마자가 크다면 큰 로마자값에서 작은 로마자값을 빼서 더해주면 되는것이었다.

function romanToNum(s) {
  let romeNum = {
    I: 1,
    V: 5,
    X: 10,
    L: 50,
    C: 100,
    D: 500,
    M: 1000
  }

  let splitRomeNum = s.split("") // ex) ['I', 'X']
  let mappingNum = splitRomeNum.map((a) => romeNum[a]) // map을 통해 로마자를 숫자로 변경
  let sum = 0;                                         // [1, 10]
   
  for (i = 0; i < mappingNum.length; i++) {  
    if (mappingNum[i] < mappingNum[i + 1]) { // index기준 i번째 숫자보다 그 다음 i+1이 크다면 
                                             // ex) 1 < 10
      sum = sum + (mappingNum[i+1] - mappingNum[i]) // 원래 sum + 큰수 - 작은수
      i++ // 이미 다음 숫자까지 더한게 반영이 됐기 때문에 i가 한칸 더 움직이게 해줘야한다 
          // ex) XCIV = 94 C-X V-I
    } else {
      sum = sum + mappingNum[i] // i+1이 i와 같거나 작다면, 그대로 그 값을 sum에 더해준다
    }
  } 
  return sum // 마지막으로 결과를 반환해준다
}

0개의 댓글