본문 바로가기

개발/Algorithm

[프로그래머스] 신규 아이디 추천(python)

2021년 5월 26일 Algorithm, 프로그래머스, 신규 아이디 추천

2021년 카카오 블라인드 채용

 

TL;DR

  • 주어진 문제의 조건을 구현할 수 있는지
  • 정규 표현식(정규식)을 활용할 수 있는지

문제 분석

1. new_id의 모든 대문자를 대응되는 소문자로 치환한다.
2. new_id에서 알파벳 소문자, 숫자 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거한다.
3. new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환한다.
4. new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거한다.
5. new_id가 빈 문자열이라면, new_id에 "a"를 대입한다.
6. new_id의 길이가 16자 이상이라면, new_id의 첫 15개 문자를 제외한 나머지 문자들을 모두 제거한다. 만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거한다.
7. new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙인다.

 

- 명시된 1 ~ 7의 조건을 순차적으로 구현하면 된다.

- 각각의 조건은 정규식을 사용할 때의 힌트이다.

입출력 형태

입출력 예시

 

- new_id : 새롭게 바꿔야 하는 아이디이다.

- result : 문제 조건에 명시된 7개의 조건을 거친 후 최종적으로 사용자에게 추천되는 아이디이다.

풀이

ALPHABET = 'abcdefghijklmnopqrstuvwxyz'
NUMBER = '0123456789'
SPECIAL = '-_.'

def solution(new_id):
    # step 1. 대문자 -> 소문자
    new_id = new_id.lower()
    
    # step 2. 규격 외 문자 제거
    for s in new_id:
        if s in ALPHABET or s in NUMBER or s in SPECIAL:
            continue
        else:
            new_id = new_id.replace(s, '')

    # step 3. 연속 마침표 제거
    while '..' in new_id: # '..'이 존재하지 않을 때 까지 반복, 최종적으로 1개의 '.'가 남게 된다.
        new_id = new_id.replace('..', '.')
        
    # step 4. 처음과 끝에 있는 . 제거
    if new_id[0] == '.':
        new_id = new_id[1:]
        if len(new_id) != 0 and new_id[-1] == '.': # 처음과 끝이 모두 '.' 인 경우 처리
            new_id = new_id[:-1]
    elif new_id[-1] == '.':
        new_id = new_id[:-1]
    
    # step 5. 빈 문자열이라면 'a' 대입
    if len(new_id) == 0:
        new_id = 'a'
        
    # step 6. 16자가 넘어갈 경우 처리
    if len(new_id) >= 16:
        new_id = new_id[:15]
        if new_id[-1] == '.':
            new_id = new_id[:-1]
            
    # step 7. 2자 이하일 경우 처리
    if len(new_id) <= 2:
        while len(new_id) < 3:
            new_id = new_id + new_id[-1]

    return new_id

 

개선된 풀이

import re

def solution(new_id):
    new_id = new_id.lower() # 1번 조건
    new_id = re.sub('[^a-z\d\-_.]', '', new_id) # 2번 조건
    new_id = re.sub('\.+', '.', new_id) # 3번 조건
    new_id = re.sub('^[.]|[.]$', '', new_id) # 4번 조건
    new_id = 'a' if len(new_id) == 0 else new_id[:15] # 5, 6(길이 자르기)번 조건
    new_id = re.sub('[.]$', '', new_id) # 6번 나머지 조건
    new_id = new_id if len(new_id) > 2 else new_id + new_id[-1] * (3 - len(new_id)) # 7번 조건
    
    return new_id

 

- 정규식을 적용하면 더 간단하게 동작하는 코드를 작성할 수 있다. 문제에서 주어진 조건이 각 정규식의 구현 형태를 말해준다.

- `re.sub(pattern, repl, string, ...)`

    : 주어진 문자열(string)에서 정규식 패턴(pattern)에 맞는 요소들을 원하는 형태(repl)로 변경한 문자열을 리턴해준다.

 

- [^a-z\d\-_.] : 문자열에 알파벳 소문자(a-z), 숫자(\d), 빼기/밑줄/마침표(\-_. )가 아닌(^) 경우를 나타낸다.

- \.+ : 마침표(\.)가 여러개(+) 있을 경우를 나타낸다.

- ^[.]|[.]$ : 문자열의 처음(^) 또는(|) 마지막($)에 마침표([.])가 있을 경우를 나타낸다.

- [.]$ : 문자열의 마지막($)에 마침표([.])가 있을 경우를 나타낸다.

반응형