Algorithm/프로그래머스

세무민의 코딩일기 : 프로그래머스 신규 아이디 추천 문제 풀기

세기루민 2021. 2. 19. 01:00
728x90

이 문제를 포스팅 하는 이유는.......

진짜 간단한 문제를 1시간 30분동안 풀었다는 점에서...

사실 풀고 난 후 테스트 케이스에 통과 못한 것들이 존재해서....하 ㅠㅠ 

이번에 풀 문제는 신규 아이디 추천!

20201년 카카오 신규 블라인드 모집 문제 중 하나입니다.


문제 설명

카카오에 입사한 신입 개발자 네오는 카카오계정개발팀에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. 네오에게 주어진 첫 업무는 새로 가입하는 유저들이 카카오 아이디 규칙에 맞지 않는 아이디를 입력했을 때, 입력된 아이디와 유사하면서 규칙에 맞는 아이디를 추천해주는 프로그램을 개발하는 것입니다.
다음은 카카오 아이디의 규칙입니다.

  • 아이디의 길이는 3자 이상 15자 이하여야 합니다.
  • 아이디는 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.) 문자만 사용할 수 있습니다.
  • 단, 마침표(.)는 처음과 끝에 사용할 수 없으며 또한 연속으로 사용할 수 없습니다.

네오는 다음과 같이 7단계의 순차적인 처리 과정을 통해 신규 유저가 입력한 아이디가 카카오 아이디 규칙에 맞는 지 검사하고 규칙에 맞지 않은 경우 규칙에 맞는 새로운 아이디를 추천해 주려고 합니다.
신규 유저가 입력한 아이디가 new_id 라고 한다면,

신규 유저가 입력한 아이디를 나타내는 new_id가 매개변수로 주어질 때, 네오가 설계한 7단계의 처리 과정을 거친 후의 추천 아이디를 return 하도록 solution 함수를 완성해 주세요


Example


제한사항 및 입출력 예시

[제한사항]

new_id는 길이 1 이상 1,000 이하인 문자열입니다.
new_id는 알파벳 대문자, 알파벳 소문자, 숫자, 특수문자로 구성되어 있습니다.
new_id에 나타날 수 있는 특수문자는 -_.~!@#$%^&*()=+[{]}:?,<>/ 로 한정됩니다.

[입출력 예]

 

no new_id result
예1 "...!@BaT#*..y.abcdefghijklm" "bat.y.abcdefghi"
예2 "z-+.^." "z--"
예3 "=.=" "aaa"
예4 "123_.def" "123_.def"
예5 "abcdefghijklmn.p" "abcdefghijklmn"

[ 입출력 예에 대한 설명 ]


풀이

이번 문제는 단계별로 하나씩 풀어나가면 됩니다.

진짜 생각보다 어려운 건 하나도 없어요 ㅠㅠ 

저는 멍청한 짓을 했으나 고민을 열라했죠 ㅋㅋㅋㅋㅋ

4단계를 재대로 생각하지 못했어요 

예를 들어서 보면 

new_Id = "[][][][][][][][][][]."라고 해보면 

1단계는 속하지 않습니다.

2단계에서 []는 제거가 되기 때문에 new_Id = "."

3단계도 속하지 않습니다.

4단계에서는 처음이나 끝에 위치하기 때문에 제거하면 new_Id = ""

5단계에 일치하기 때문에 new_Id = "a"

6단계는 일치하지 않고 7단계에 속하며 결과적으로 new_Id = "aaa" 

위에 예시를 해보기 전에는 제 코드의 문제점을 확인하지 못했었어요 ㅋㅋㅋㅋㅋㅋㅋㅋ

제가 처음에 만들었던 코드에서 4단계를 재대로 체크하지 못해서 삽질을 오래했습니다...


코드

import re
new_id = "abcdefghijklmn.p"
# 1단계
for i in range(len(new_id)):
    if ord(new_id[i]) >= 65 and ord(new_id[i]) < 91:
        new_id = new_id.replace(new_id[i], chr(ord(new_id[i]) + 32))

# 2단계
temp = re.sub('[=+,#/\?:^$@*\"※~&%ㆍ!』\\‘|\(\)\[\]\<\>`\'…》]', '', new_id)    

# 3단계
while ".." in temp:
    temp = temp.replace("..", ".")
       
# 4단계 - 문자열은 replace로 제거하는건 힘듬 
print(temp[0], temp[-1])
if ord(temp[0]) == 46:
    temp = temp[1:]
elif ord(temp[-1]) == 46:
    print(temp)
    temp = temp[:-1]

# 5단계
if temp == "":
    temp = a

# 6단계
if len(temp) >= 16:
    print("6", temp)
    temp = temp[:15]
    print(temp[-1])
    if ord(temp[-1]) == 46:
        print(temp)
        temp = temp[:-1]

#7단계
if len(temp) <= 2:
    while len(temp) < 3:
        temp = temp + temp[-1]

    
print(temp)

위에 코드는 초기 버전입니다.

위에 코드를 확인하다보면 틀린 부분이 보이겠지만

결과도 처참합니다 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

그래서 변경한 코드를 보여드리면

import re
def solution(new_id):
    # 1단계
    new_id = new_id.lower()
    

    # 2단계
    temp2 = ""
    for i in range(len(new_id)):
        if ord('a') <= ord(new_id[i]) and ord('z') >= ord(new_id[i]):
            temp2 += new_id[i]
        elif ord('0') <= ord(new_id[i]) and ord('9') >= ord(new_id[i]):
            temp2 += new_id[i]
        elif ord('-') <= ord(new_id[i]) and ord('.') >= ord(new_id[i]):
            temp2 += new_id[i]
        elif ord('_') == ord(new_id[i]):
            temp2 += new_id[i]

    temp = temp2

    # 3단계
    while ".." in temp:
        temp = temp.replace("..", ".")

    # 4단계 - 문자열은 replace로 제거하는건 힘듬 
    FristCheck, LastCheck = False, False
    
    if ord(temp[0]) == ord('.'):
        FristCheck = True
        # temp = temp[1:]
    if ord(temp[-1]) == ord('.'):
        LastCheck = True
        # temp = temp[:-1]
        
    if FristCheck == True:
        temp = temp[1:]
    if LastCheck == True:
        temp = temp[:-1]
        
    # 5단계
    if temp == "":
        temp = "a"

    # 6단계
    if len(temp) >= 16:
        temp = temp[:15]
        if ord(temp[-1]) == ord('.'):
            temp = temp[:-1]

    #7단계
    if len(temp) <= 2:
        while len(temp) < 3:
            temp = temp + temp[-1]


    return temp

위와 같습니다.

간략하게 변경된 부분을 하나씩 설명해보면 

1단계는 반복문으로 대소문자를 변경했던 걸 lower()라는 대문자를 소문자로 변경해주는 매소드를 이용합니다.

2단계에서 정규식을 이용해서 문자를 제거했지만 이 부분에서도 오류가 발생해서 

하나씩 체크하면서 제거해줍니다.

4단계에서는 FristCheck와 LastCheck를 각각 둬서 해당 값이 "."라면 True로 변환해준 후  True인 경우 제거해주면 끝!

이렇게 한 이유는 문자열을 제거하는 경우 인덱스가 같이 변경되기 때문! 

3,5,6,7단계는 동일합니다.

끝!


일단 코딩공부를 더 열심히 해야겠다는 생각 뿐이네요 ㅋㅋㅋㅋㅋ

백준 -> HackerRank -> 프로그래머스로 넘어오면서 

각 사이트마다 장단점이 뚜렷하지만 일단 프로그래머스로 보는 기업들이 많으니깐....

무튼 화이팅!

 

728x90