[Python] Code Kata Day6

rang-dev·2020년 6월 15일
0

Wecode - Code Kata

목록 보기
6/18

문제

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 

내코드

def roman_to_num(string):
  
  roman = {'I':1, 'V': 5, 'X':10, 'L':50, 'C':100, 'D': 500, 'M':1000}

  total = 0

  for i in range(len(string)):
    current_rom = string[i]
    if i == (len(string)-1):
      total += roman[current_rom]
    else:
      if roman[string[i]]>=roman[string[i+1]]:
        total += roman[current_rom]
      else:
        total -= roman[current_rom]

  return(total)

앞뒤 대소비교를 해야해서 그럼 앞의 값이랑 뒤의 값이랑 더하거나 빼서 기존의 sum과 더해줘야하나? 계속 복잡하게 생각하다가 코드카타 짝꿍 정민님에게 어떻게 푸셨냐고 여쭤보니 그냥 앞>뒤면 수가 +이고 앞<뒤면 수가 -가 된다고 생각해서 푸셨다고 하셨다.(예를들어 XIV라면 10+(-1)+5)

이렇게 따로 떨어뜨려 생각하니 훨씬 생각하기 간단해져서 금방 풀 수 있었다. 감사합니다😀

Model Solution

#solution1
# def roman_to_num(s):
#         """
#         :type s: str
#         :rtype: int
#         """
#         L = []
#         sum = 0
#         d = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
#         for i in s[::-1]:
#             if L:
#                 if i=='I' and L[-1] in ['V','X']:
#                     sum -= 1
#                     L.pop()
#                 elif i=='X' and L[-1] in ['L','C']:
#                     sum -= 10
#                     L.pop()
#                 elif i=='C' and L[-1] in ['D','M']:
#                     sum -= 100
#                     L.pop()
#                 else:
#                     sum += d[i]
#                     L.append(i)
#             else:
#                 sum +=d[i]
#                 L.append(i)
#         return sum

#solution2
numbers = {
        "I" : 1,
        "IV" : 4,
        "V" : 5,
        "IX" : 9,
        "X" : 10,
        "XL" : 40,
        "L" : 50,
        "XC" : 90,
        "C" : 100,
        "CD" : 400,
        "D" : 500,
        "CM" : 900,
        "M" : 1000,
    }
def roman_to_num(s):
    if not s:
        return 0
    if numbers.get(s[:2]):
        return numbers.get(s[:2]) + roman_to_num(s[2:])
    return  numbers.get(s[:1]) + roman_to_num(s[1:])

model solution2에서는 예외인 부분들까지 딕셔너리에 포함시켜 만들었다. 나도 처음에 이렇게 딕셔너리를 만들어볼까 고민했었는데 그 뒤로 어떻게 풀어나갈지 몰라서 포기했었다.

여기서는 로마자 2자와 딕셔너리의 key중에 맞는게 있다면 숫자로 변환하고 일치하는게 없다면 1글자만을 확인해서 숫자로 변환해준다. 그리고 숫자로 변환한 것 이외의 나머지 로마자들은 또 원래의 함수에 넣어서(재귀함수) 더이상 비교할 값이 없을때까지 동일 과정을 반복하여 더해준다.

Python Dictionary get() Method

profile
지금 있는 곳에서, 내가 가진 것으로, 할 수 있는 일을 하기 🐢

0개의 댓글