[프로그래머스] Lv1 - 신규 아이디 추천

김멉덥·2023년 7월 17일
0

알고리즘 공부

목록 보기
53/171
post-thumbnail
post-custom-banner

문제

프로그래머스 2021 KAKAO BLIND RECRUITMENT


코드 구현

def solution(new_id):
    # 1단계
    answer = new_id.lower()
    # print(answer)

    # 2단계
    for i in answer:
        if (i.islower() or i.isdigit() or i == '-' or i == '_' or i == '.'):
            continue
        else:
            answer = answer.replace(i, "")
    # print(answer)

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

    # 4단계
    if(len(answer) > 0):
        if(answer[0] == "."):
            answer = answer[1:]
    if (len(answer) > 0):
        if (answer[-1] == "."):
            answer = answer[:-1]
    # print(answer)

    # 5단계
    if(len(answer) == 0):
        answer = "a"

    # 6단계
    if(len(answer) >= 16):
        answer = answer[:15]
        if(answer[-1] == "."):
            answer = answer[:14]
    # print(answer)

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

    return answer

풀이

  • 1단계부터 7단계까지 하나씩 조건을 통과하는지 검사 → 통과하지 않는다면 규칙대로 변경

규칙

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이 될 때까지 반복해서 끝에 붙입니다.
  • replace(바꾸고싶은 문자, 대신 넣을 문자) 와 문자열 슬라이싱을 통해 해결하였다.
  • 테스트케이스를 모두 통과하는데 3단계 4단계에서 계속 막혀서 다소 시간이 소요되었다.
  • 틀렸던 이유
    • 3단계를 잘못읽어서 마침표가 2개 이상인 부분을 모두 하나의 마침표로 계속 치환해야하는데 반복문 사용 없이 그저 replace 함수로만 한번에 치환하였다.
    • 4단계에서 마침표가 첫 조건문에서 제거되어 빈칸이 되어버린 경우, 그 다음 조건문을 들어갔을 때 오류가 났다. 따라서 두 조건문 모두 앞에 문자열의 길이가 0 이상일때만 들어가도록 설정해주었다.

What I learned

정규표현식을 이용하면 정말 짧은 코드로 완성할 수 있는 문제였다. 그동안 정규표현식을 등한시했던게 후회되었다… (누가 이걸 외워서 쓰는가?!)

▶️ 아무튼 깔끔한 정답 코드
참고 : https://mizykk.tistory.com/116

import re

def solution(new_id):
    answer = ''

    # 1단계 & 2단계 : 소문자 치환
    answer = re.sub('[^a-z\d\-\_\.]', '', new_id.lower())

    # 3단계 : 마침표 2번 이상 > 하나로
    answer = re.sub('\.\.+', '.', answer)

    # 4단계 : 양 끝 마침표 제거
    answer = re.sub('^\.|\.$', '', answer)

    # 5단계 : 빈 문자열이면 a 대입
    if answer == '':
        answer = 'a'

    # 6단계 : 길이가 16자 이상이면 1~15자만 남기기 & 맨 끝 마침표 제거
    answer = re.sub('\.$', '', answer[0:15])

    # 7단계 : 길이가 3이 될 때까지 반복해서 끝에 붙이기
    while len(answer) < 3:
        answer += answer[-1:]

    return answer

▶️ 정규표현식 설명

2단계 newid에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(), 마침표(.)를 제외한 모든 문자를 제거합니다.

  • 소문자(a-z), 숫자(\d), 빼기(-), 밑줄(-), 마침표(.)를 제외한(대괄호 [] 맨 앞에 ^를 붙여준다.) 모든 문자 제거
  • 이때 빼기, 밑줄, 마침표 앞에 오는 \는 이스케이프이다.
  • 정규표현식이 일치하면 '' 빈 문자로 치환(sub)하여 문자를 제거한다.

3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.

  • 마침표가 2번 이상 (..+)인 것을 마침표로 치환(sub)

4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.

  • 마침표가 처음(^.)이나 끝(.$)

6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다. 만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.

  • 첫 15개의 문자만 사용 = answer[0:15]
  • 맨 끝에 위치한 마침표('.$')

▶️ 정규표현식 사용법 정리

참고 : https://nachwon.github.io/regular-expressions/

profile
데굴데굴 뚝딱뚝딱 개발기록
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 7월 18일

정말 유익한 글이었습니다.

답글 달기