본문 바로가기

알고리즘/프로그래머스

[프로그래머스][2021 KAKAO BLIND RECRUITMENT][Python] 신규 아이디 추천

문제를 정리해보자.

 

카카오 아이디가 주어진다.

규칙에 맞지 않는 아이디라면 규칙에 맞는 아이디로 바꿔야 한다.

 

다음은 카카오 아이디의 규칙이다.

 

1. 아이디의 길이는 3자 이상 15자 이하여야 한다.

2. 아이디는 알파벳 소문자, 숫자, 빼기, 밑줄, 마침표 문자만 사용할 수 있다.

(단, 마침표는 처음과 끝에 사용할 수 없으며 또한 연속으로 사용할 수 없다.)

 

규칙 맞는 아이디로 처리하는 과정은 아래와 같다.

 

1단계: 모든 대문자를 대응되는 소문자로 변환한다.

2단계: 알파벳 소문자, 숫자, 빼기, 밑줄, 마침표를 제외한 모든 문자를 제거한다.

3단계: 마침표가 2번 이상 연속된 부분을 하나의 마침표로 치환한다.

4단계: 마침표가 처음이나 끝에 위치한다면 제거한다.

5단계: 빈 문자열이라면, "a"를 대입한다.

6단계: 길이가 16자 이상이면, 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거한다.

6-1단계: 만약 제거 후 마침표가 끝에 위 끝에 위치한 마침표 문자를 제거한다.

7단계: 길이가 2자 이하라면, 마지막 문자를 길이가 3이 될 때까지 반복해서 끝에 붙인다.

 

 


 

풀이를 생각해보자.

 

2단계는 아스키코드를 이용해서 구현하자.

 

 

https://ooyoung.tistory.com/104

 

 


 

구현해보자.

 

 

# 문제 순서 준수
def solution(new_id):
    tmp = ''
    answer = ''

    # 1단계
    new_id = new_id.lower()

    # 2단계 (소문자:97~122, 숫자:48~57, 빼기:45, 밑줄:95, 마침표:46)
    if new_id:
        for string in new_id:
            change = ord(string)
            if 96 < change < 123 or 47 < change < 58 or 44 < change < 47 or change == 95:
                tmp += string

    # 3단계
    pre_string = ''
    for string in tmp:
        if string == '.' and pre_string == '.':
            pre_string = string
            continue

        pre_string = string
        answer += string

    # 4단계
    answer = answer.strip('.')

    # 5단계
    if answer == '':
        answer = 'a'

    # 6단계
    answer = answer[:15].rstrip('.')

    # 7단계
    answer += answer[-1] * (3 - len(answer))

    return answer


print(solution("b=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.x)"))

 

 


시행착오

 

1

처음에는 문제를 효율적으로 풀고 싶어서 단계를 섞었다.

하지만 계속 반례가 발생했고, 로직에 오류가 있음을 깨달았다.

문제에서 7단계의 '순차적인' 처리 과정을 제시했다. 문제에 명시된 내용을 앞으로는 준수하자.

 

아래는 잘못 구현한 코드이다.

 

반례: b=.=.=.=.=.=.=.=.=.=.=.=.=.=.=.x

출력 결과: b.............

올바른 결과: b.x

 

 

def solution(new_id):
    answer = ''
    pre_string = ''

    # 3단계
    for string in new_id:
        if string == '.' and pre_string == '.':
            pre_string = string
            continue

        pre_string = string

        # 2단계 (대문자:65~90, 소문자:97~122, 숫자:49~57, 빼기:45, 밑줄:95, 마침표:46)
        if not string == '':
            tmp = ord(string)
            if 64 < tmp < 91 or 96 < tmp < 123 or 48 < tmp < 58 or 44 < tmp < 47 or tmp == 95:
                # 1단계
                answer += string.lower()

 

 

2

숫자는 0부터 들어올 수 있다.

2단계에서 숫자의 아스키코드 범위를 48~57로 잡아야 한다.

 

0을 생각하지 못해서 6번 18번 26번에서 통과하지 못했다.

 

 


 

다른 사람의 풀이

 

 

    # 2
    for c in new_id:
        if c.isalpha() or c.isdigit() or c in ['-', '_', '.']:
            answer += c
    # 3
    while '..' in answer:
        answer = answer.replace('..', '.')

 

 

2단계에서 isalpha와 isdigit 함수를 쓰는 방법이 있다.

3단계에서 replace를 이용하면 코드 길이가 짧게 구현이 가능하다.