CodeWars 06: Word to initial number

김기욱·2021년 5월 17일
0

코딩테스트

목록 보기
44/68
post-custom-banner

문제설명

Your task is to write the word to number converter. Digits in the number should match letters in the word. Plus generated number should be the smallest possible number you can get.
당신의 임무는 주어진 단어를 숫자로 바꾸는 것입니다. 숫자들(digits)은 반드시 단어안에 문자들(letters)과 매칭이 되어야합니다. 또한 숫자를 생성할 땐 만들 수 있는 숫자들 중 가장 작은 숫자로 만들어야합니다.

  • Words will contain of maximum 10 distinct letters, but word can be any length, even longer than 10 characters long.
    단어는 최대 10종류의 문자를 포함하게 됩니다. 다만 단어의 길이가 최대 10글자라는 건 아닙니다. 더 될 수 있습니다.
  • Number can NOT start with 0
    숫자는 0으로 시작할 수 없습니다.
  • Same letters share the same digit regardless of case
    case(대소문자)랑 상관없이 하나의 문자는 하나의 숫자를 갖게됩니다.
  • For empty string return 0
    주어진 단어가 공백이라면 0을 리턴시켜줘야합니다.

제한사항

None

입출력 예시

"A" -> 1 - OK
"ABA" -> 353 - WRONG ( number is OK, but it's not the smallest number )
"ABA" -> 333 - WRONG ( different letters map to same digits )
"ABA" -> 357 - WRONG ( same letters map to different digits )

풀이

def convert(st): 
    digit_num_dic = {}
    num_list = ['9','8','7','6','5','4','3','2','0','1']
    result = ''
    
    if len(st) == 0:
        return 0
    
    for v in st.upper():
        if v in digit_num_dic:
            result += digit_num_dic[v])
        else:
            num = num_list.pop()
            digit_num_dic[v] = num
            result += num
            
    return int(result)
  1. 우선 변수 세 개를 만들어 줍니다.
    중복 문자 확인용 딕셔너리, 문자와 매칭할 숫자 리스트, 최종결과를 위한 빈 문자열입니다.
  2. 주어진 조건에서 빈 글자는 0을 return하라고 했으므로, 가장 먼저 조건문을 통해 필터링 해줍니다.
  3. 대소문자 구분없이 문자->숫자로 변환하라고 했으니 upper()를 써서 문자열 전체를 대문자로 바꿔줍니다.
  4. for loop을 사용합니다. 만약 문자가 이미 digit_num_dic에 포함되어있다면 dict[문자]를 통해 딕셔너리에 저장된 숫자를 가져와 결과값에 붙여줍니다.
  5. digit_num_dic에 포함되지 않는다면 num_list에서 pop을 통해 숫자를 잘라내줍니다.
    최소수를 만드려면 자리수가 큰 자리에 작은 숫자를 집어넣어야하므로 num_list의 숫자는 역순으로 하되, 첫 번째 수는 0이될수 없으므로 1을 가장 앞에 배치합니다.
  6. 잘라낸 숫자는 딕셔너리에 넣어주고, result에 붙여줍니다.
  7. 이를 반복하면 숫자로 구성된 문자열이 완성됩니다. 이를 return해주면 됩니다.

다른풀이

def convert(s):
    w2n = dict(zip(dict.fromkeys(s.upper()), '1023456789'))
    return int('0' + ''.join([w2n[ch] for ch in s.upper()]))

너무 예쁜 파이써닉한 코드입니다.🎃

저 같은 경우 for loop를 통해 dict를 만들고 검증하는 과정이 들어있는데 여기서는 fromkeys와 zip 메서드를 활용해 미리 사전을 만들어버리는 원리입니다.
fromkeys같은 경우는 밸류가 없이 키만 있는 사전을 만들수 있습니다. 해당 메서드를 통해 문자열을 하나하나 잘라 키만 있는 사전을 만듭니다. dict의 기본속성 상 중복을 허용하지 않으므로 중복제거도 문제없이 됩니다. 이 상태에서 zip을 통해 병렬배치를 하고 다시 dict로 바꿔주면 문자-숫자가 매칭이 완성된 사전을 만들게됩니다. 이를 다시 문자열을 돌리면서 숫자를 빼내서 문자열로 붙여주면 완성!

다만 빈 문자열일 경우 0을 리턴해야 하므로 '0'을 앞에다가 놔둡니다.

profile
어려운 것은 없다, 다만 아직 익숙치않을뿐이다.
post-custom-banner

0개의 댓글