TIL53. CodeKata : 로마자에서 숫자로 바꾸기 문제

ID짱재·2021년 10월 25일
0

CodeKata

목록 보기
4/18
post-thumbnail

🌈 로마자에서 숫자로 바꾸기 문제


🤔 나의 Solution

1~3999 사이의 로마자 s를 인자로 주면 그에 해당하는 숫자를 반환해주세요.

✔️ 로마자를 숫자로 읽는 방법은 로마자를 왼쪽부터 차례대로 더하면 됩니다.

  • III = 3 👈 I는 숫자 1이기 때문에 3(1+1+1)
  • XII = 12 👈 X는 숫자 10이기 때문에 12(10+1+1)
  • XXVII = 27 👈 V는 숫자 5이기 때문에 27(10+10+5+1+1)

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

✔️ I는 V와 X앞에 와서 4, 9 X는 L, C앞에 와서 40, 90 C는 D, M앞에 와서 400, 900입니다.

  • IV = 4 👈 1+5가 아닌, 5-1이기 때문에 4
  • IX = 9 👈 1+10가 아닌, 10-1이기 때문에 9
  • XL = 40 👈 10+50이 아닌, 50-10이기 때문에 40
  • XC = 90 👈 10+100이 아닌, 100-10이기 떄문에 90
  • CD = 400 👈 100+500이 아닌, 500-100이기 때문에 400
  • CM = 900 👈 100+1000이 아닌, 1000-100이기 때문에 900
def roman_to_num(s):
  if len(s) == 0: return 0 # 👈 s에 아무것도 전달되지 않으면 0 반환
  roman_d = {'I':1, 'V': 5, 'X':10, 'L':50, 'C':100, 'D': 500, 'M':1000}
  total = 0 
  for i in range(len(s)): # 👈 s의 길이만큼 순회
    if i == len(s)-1: # 👈 out of range 에러 발생하지 않도록!
      total += roman_d[s[i]]
    else:
      if roman_d[s[i]] >= roman_d[s[i+1]]: # 👈 s[i] >= s[i+1] 일때,,
        total += roman_d[s[i]]
      else:                                # 👈 s[i] < s[i+1] 일때,,
        total -= roman_d[s[i]]
  return total 
s = 'XXVII'
res = roman_to_num(s)
print(res)

✔️ 우선 주어진 표를 딕셔너리로 만들어두고, for문을 순회해 s[i]값을 딕셔너리에서 찾아 total에 더해줘야 한다.

✔️ 다만, for문 내부에서 s[i]와 s[i+1]를 비교하기 때문에 out of range 에러를 방지하기 위해서 현재 i가 마지막 요소라면 비교하지 않고 바로 더할 수 있게 처리했다.

✔️ total값을 구하는 핵심은 s[i]가 s[i+1] 보다 크거나 같을 때는 딕셔너리에서 value값을 total에 계속 더해주기만 하면 되고, s[i]가 s[i+1] 보다 작을 때만 현재 s[i]를 total값에서 빼주면 된다.

✔️ 빼주는 이유는 IV는 4인데, I가 1이고, V가 5이기 때문이다. 먼저 빼주고 더해주면 둘다 처리가 가능하다.


🤔 다른 해결 방법

def roman_to_num(s):
  roman_d = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
  res = 0
  for i in range(len(s)):
    if i > 0 and roman_d[s[i]] > roman_d[s[i-1]]:
      res += roman_d[s[i]] - 2 * roman_d[s[i-1]]
    else:
      res += roman_d[s[i]]
  return res
s = 'XXVII'
res = roman_to_num(s)
print(res)    

✔️ 이 방법은 s[i]가 s[i-1] 보다 클 때, s[i-1] 값에 2를 곱한 뒤, s[i]에서 빼주는 방식이다.

✔️ 즉, IV를보면, 여기서 I는 s[i-1]이 되고, V는 s[i]가 되기 떄문에 s[i]가 s[i-1] 보다 큰 상황이 발생된다.

✔️ 이럴 때, s[i-1]을 2를 곱해서 빼는 이유는 s[i-1]이 이 전 순회때 s[i]였기 때문에 이미 더해져버렸기 떄문이다. 미리 한번 더한뒤, 나중에 빼는 방식이기 때문에 2를 곱해서 빼야한다.


🤔 느낀점.

눈으로만 풀려하면 해결하기 어렵다. 손으로 그리며 규칙을 찾자.

profile
Keep Going, Keep Coding!

0개의 댓글