Algorithm - CodeKata #06

Sangho Moon·2020년 9월 7일
0

Algorithm

목록 보기
19/37
post-thumbnail

1. Question

로마자에서 숫자로 바꾸기

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


2. Try & Answer

알고리즘 문제는 항상 나한테 너무 어렵다.. 오늘도 구글링...

먼저 아래에는 reduce 메서드가 적용되었다.

이 게시물을 쓰기전에 reduce 메서드의 개념과 예시를 이곳에 정리해 두었다.

function romanToNum(s) {
  const romanTable = {
    I : 1,
    V : 5,
    X : 10,
    L : 50,
    C : 100,
    D : 500,
    M : 1000,
  }
  
  const arr = s.split('');
  
  return arr.reduce((acc, item, index) => {
    const currentValue = romanTable[item];
    const nextValue = romanTable[arr[index + 1]];
    
    if (nextValue > currentValue) {
      acc -= currentValue;
    } else {
      acc += currentValue;
    }
    
    return acc;
  }, 0);
}

console.log(romanToNum("XII")); // 12
console.log(romanToNum("XXVII")); // 27
console.log(romanToNum("XL")); // 40
console.log(romanToNum("XC")); // 90

먼저 문제에서 로마자를 더하거나 뺀다는 설명이 있으므로 if, else 문을 생각해볼 수 있다.

또 예시를 통해 로마자 중 뒤의 값이 앞의 값보다 클 때는 뺀다는 것을 유추해 볼 수 있다.

그럼 로마자에서 뒤의 값이 앞의 값보다 클 때는 두 개의 값을 비교해서 빼줘야 한다는 것을 알 수 있다.

그런데 XXVII 가 27로 출력되려면 10 + 10 + 5 + 1 + 1 , 이런식으로 값을 다 더해줘야 한다는 것도

알 수 있다.


  1. 함수를 실행할 때 받는 string 인자를 split 메서드를 사용해서 문자 하나하나를 배열 요소로 만듦.

  2. 그럼 위에서 이 문제에서 써야 할 숫자들을 미리 객체의 key, value 형태로 변수에 담아놓았으니 활용 가능.

  3. reduce 메서드를 사용하여 조건마다 값을 더해주거나 빼준 다음 그 값을 리턴하도록 설정하는 함수 만들기.


그러면 이제 위 코드를 해석해 보겠다. ( 다른 쪽에 문제 + 코드 띄워 놓고 보는게 편함 )

  1. arr이라는 변수에 s라는 인자를 받아 split 메서드를 사용

    (ex: s = XXVII 는 [ 'X', 'X', 'V', 'I', 'I' ] 의 형태가 됨)

  2. acc 의 초기 값은 0, item = 'X' 즉, item = 10, index = 0 인 상태에서 시작.

  3. currentValue = romanTable['X'] = 10

  4. nextValue = romanTable[현재 배열[0 + 1]] = romanTable['X'] = 10

  5. 조건문에서 else의 경우에 해당하므로 acc = 0 에 currentValue = 10 을 더하면 acc = 10

  6. 다시 돌아와서 currentValue = romanTable['X'] = 10

  7. nextValue = romanTable[현재 배열[1 + 1]] = romanTable['X'] = 10

  8. currentValue 10, nextValue 10 은 조건문의 else에 해당되므로

    acc는 기존 acc 10 + currentValue 10 = 20이 된다.

  9. 다시 돌아와서 currentValue = romanTable['V'] = 5

  10. nextValue = romanTable[현재 배열[2 + 1]] = romanTable['I'] = 1

  11. currentValue 5, nextValue 1 은 조건문의 else에 해당되므로

    acc는 기존 acc 20 + currentValue 5 = 25가 된다.

  12. 다시 돌아와서 currentValue = romanTable['I'] = 1

  13. nextValue = romanTable[현재 배열[3 + 1]] = romanTable['I'] = 1

  14. currentValue 1, nextValue 1 은 조건문의 else에 해당되므로

    acc는 기존 acc 25 + currentValue 1 = 26이 된다.

  15. 다시 돌아와서 currentValue = romanTable['I'] = 1

  16. nextValue = romanTable[현재 배열[4 + 1]] = romanTable[undefined] = 값 없음.

  17. currentValue 1, nextValue '값 없음' 은 조건문의 else에 해당되므로

    acc는 기존 acc 26 + currentValue 1 = 27이 된다.


작성하면서도 많이 헷갈렸다.. 일단 나중을 위해 기록해두었음!

profile
Front-end developer

0개의 댓글