본문 바로가기
PS(Problem Solving)/프로그래머스_Programmers

[프로그래머스] 2021 카카오 공채 - 신규 아이디 추천 (파이썬) 문제 및 풀이

by 초코칩프라푸치노 2021. 2. 3.

문제) 프로그래머스 - 2021 카카오 공채 - 신규 아이디 추천

-> programmers.co.kr/learn/courses/30/lessons/72410

 

코딩테스트 연습 - 신규 아이디 추천

카카오에 입사한 신입 개발자 네오는 카카오계정개발팀에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. 네오에게 주어진 첫 업무는 새로 가

programmers.co.kr

① 나의 풀이

아무 생각 없이 (빡?) 구현했다. 모든 단계를 주어진 new_id를 이용해 처리했다.

  • 1단계:  대문자를 소문자로 치환하는 것이므로 lower() 메서드를 이용해 쉽게 해결했다.
  • 2단계:  알파벳(isalpha()), 숫자(isdigit()), 특수 문자를 확인하며 그것이 아닐 경우 슬라이싱으로 처리했다.
  • 3단계:  i번째 문자열과 i + 1번째 문자열이 모두 마침표('.') 일 경우 하나만 남긴다.
  • 4단계:  이전 단계들을 거치고 나서 new_id가 빈 문자열이 될 수도 있다. 따라서 빈 문자열이 아닐 경우에만 검사할 수 있게 조건(new_id != '')을 붙여준다.
  • 5단계: 빈 문자열일 경우, new_id는 'a'가 된다.
  • 6단계:  문자열의 길이가 16 이상이면 15 이하만 채택하고 자른 후 그 끝에 마침표('.')가 있다면 제거한다.
  • 7단계: 문자열의 길이가 2 이하이면, (3 - 문자열의 개수)만큼 끝 문자를 추가한다.

 

반성)

파이썬의 장점을 이용 못한 기분이다. 파이썬의 강력함은 문자열에서 발휘되는데 그 강력함을 이용하지 못한 기분이 들어 아쉽다. 아마 시간제한이 빡빡하게 있었다면 통과 못했을 것 같다. 그리고 어떤 고집이었는지 모르겠지만, 처음부터 new_id만을 조작해 곤란한 상황이 있었다. (4단계 같은 경우)

 

소스 코드)

def solution(new_id:str):
	
    	# step 1
    new_id = new_id.lower()
	
    	# step 2
    i = 0
    while i < len(new_id):
        if new_id[i].isalpha() or new_id[i].isdigit() or new_id[i] == '-' or new_id[i] == '_' or new_id[i] == '.':
            i += 1
        else:
            new_id = new_id[: i] + new_id[i + 1 :]

    	# step 3
    i = 0
    while i < len(new_id) - 1:
        if new_id[i] == '.' and new_id[i + 1] == '.':
            new_id = new_id[: i] + new_id[i + 1:]
        else:
            i += 1
    
	# step 4
    while (new_id != '' and new_id[0] == '.') or (new_id != '' and new_id[-1] == '.'):
        if new_id[0] =='.':
            new_id = new_id[1:]
        elif new_id[-1] == '.':
            new_id = new_id[:len(new_id) - 1]
    
	# step 5
    if new_id == '':
        new_id = 'a'
    
	# step 6
    if len(new_id) >= 16:
        new_id = new_id[:15]
        if new_id[-1] == '.':
            new_id = new_id[:14]
    
    	# step 7        
    elif len(new_id) <= 2:
        new_id = new_id + new_id[-1] * (3 - len(new_id))

    answer = new_id
    return answer

 

② 다른 사람 풀이

⊙ 비슷하지만 더 간결한 풀이

def solution(new_id):
    answer = ''
    # 1
    new_id = new_id.lower()
    # 2
    for c in new_id:
        if c.isalpha() or c.isdigit() or c in ['-', '_', '.']:
            answer += c
    # 3
    while '..' in answer:
        answer = answer.replace('..', '.')
    # 4
    if answer[0] == '.':
        answer = answer[1:] if len(answer) > 1 else '.'
    if answer[-1] == '.':
        answer = answer[:-1]
    # 5
    if answer == '':
        answer = 'a'
    # 6
    if len(answer) > 15:
        answer = answer[:15]
        if answer[-1] == '.':
            answer = answer[:-1]
    # 7
    while len(answer) < 3:
        answer += answer[-1]
    return answer

 

  • 2단계: 특수 문자 제거까지 new_id를 사용함
  • 3단계: replace() method와 in 연산자를 활용해 마침표가 연속을 있을 경우, 계속 하나로 치환한다.

 

⊙ 정규식을 이용한 풀이

import re

def solution(new_id):
    st = new_id
    st = st.lower()
    st = re.sub('[^a-z0-9\-_.]', '', st)
    st = re.sub('\.+', '.', st)
    st = re.sub('^[.]|[.]$', '', st)
    st = 'a' if len(st) == 0 else st[:15]
    st = re.sub('^[.]|[.]$', '', st)
    st = st if len(st) > 2 else st + "".join([st[-1] for i in range(3-len(st))])
    return st

 

정규식이 무엇인지 이 풀이를 보고 공부하는 계기가 되었다. 이렇게 간단히 구현할 수 있다는 거에 놀랐으며, 문자열을 다루는 무기가 하나 더 늘어났다.

 

 

 

③ 배운 점

1. 정규식의 존재(더 공부하도록 하자)

2. replace()와 in의 활용(분명 몰랐던 건 아니지만 활용을 못해 코드가 복잡해졌다)

 

 

반응형

댓글