코린이의 공부일기

[Python] 프로그래머스 LEVEL1> 신규 아이디 본문

STUDY/[Python] Coding Test

[Python] 프로그래머스 LEVEL1> 신규 아이디

SOJUNG 2021. 1. 28. 20:04

안녕하세요 ! 오늘은 2021년 카카오 블라인드채용 코딩테스트문제를 가져왔습니다!

이 문제에서는 내장되어있는 함수들을 많이알고, 써봤다면 금방 풀 수 있었을 것 같은데..

함수들을 잘 모른다면 정말 오래걸리고 테스트케이스도 다 통과하기 어려웠을듯...(그게 제얘기입니다..)

이 문제를 풀면서 파이썬 내장, 외장함수를 많이찾아보고 공부해서 정말 좋은 문제 같아요 ㅎㅎ!

만약 틀린게있다거나, 추가보충 해주시는 댓글은 환영합니다 ㅎㅎ

 

문제설명

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

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

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

 

조건

 

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번 째 풀이

일단 처음 문제를 딱 보고나서 든 생각은 아 함수를 많이 알고있어야 금방 풀 수 있고 아니면 돌고돌아 풀 것같은 느낌이었다.. 

일단 1단계 소문자변환은 쉽게 lower() 를 사용했다.

2단계는 new_id에 알파벳 소문자,숫자,빼기,밑줄,마침표 만 들어갈 수 있기에 S에 들어갈 수 있는 문자열 모두를  선언했다. 그 다음으로 new_id를  for - if not in을 사용해 S 문자열에 포함되어있지 않는 문자열을 replace를 사용해 사용했다.!

3단계는 2개이상 연속되는 마침표(.)를 하나의 마침표(.)로 바꾸도록 하기위해서 마침표(.)의 개수는 얼마나 들어올지 모르기 때문에 마침표의 개수가 최대가 될 수 있는 경우부터 따졌다. 

answer1의 문자열을 새로만들고 if-else를 사용해 연속되는 2개이상의 마침표를 한개로 바꾸도록 만들었다.

4단계는  문자열의 양 옆의 지우고싶은 문자열을 없앨 수 있는 strip()를 사용해 지웠다.

5,6,7은 워낙 기본적은 파이썬 함수를 써서 금방 할 수 있는데 여기서 주의할 점은 if -elif-elif-elif를 사용하면 절대 안된다는점! 첫번째 elif에서 걸리면 3-4번째 elif 조건문은 가지 않기 때문에 따로 if문을 새로 만들었다.

 

def solution(new_id):
    answer1=''
    S='abcdefghijklmnopqrstuvwxyz0123456789-_.' 
    new_id = new_id.lower()   #1단계
    for i in new_id:
        if i not in S:
            new_id=new_id.replace(i,'')  #2단계
    answer1=answer1+new_id[0]
    for v in range(1,len(new_id)):
        if answer1[-1]=='.'and new_id[v]=='.':
            v=v+1
        else:
            answer1=answer1+new_id[v]
    answer1=answer1.strip('.')#3단계   #4단계
    if answer1=='':
        answer1='a'     #5단계
    elif len(answer1)>15:
        answer1=answer1[0:15].strip('.')   #6단계
    if len(answer1)==1:
        answer1=answer1*3 
    elif len(answer1)==2:
        answer1=answer1+answer1[1]   #7단계
        
        
    return answer1

요게 첫 번째 방법이고 정말 이 문제는 re.sub 의 기능만 알았다면 정말 쉽고 빠르게 풀 수 있었을 문제였다..

 

2번 째 풀이

import re

def solution(new_id):
    answer1=new_id.lower()    #1단계
    answer1=re.sub('[^a-z0-9-_.]','',answer1) #2단계
    answer1=re.sub('\.+','.',answer1)     #3단계
    answer1=answer1.strip('.')#4단계
    answer1= 'a' if len(answer1)==0 else answer1[0:15].strip('.') 
    answer1= answer1*3 if len(answer1)==1 else answer1+answer1[1] if len(answer1)==2 else answer1

    return answer1

변수는 같게 하고 ,2단계 ,3단계, 4단계 모두 re.sub을 이용하니 첫 번째 풀이에서 아이디로 할 수 있는 문자열들을 따로 S에 하나하나 안적어도 되는 수고를 확 줄일 수 있는 정말 큰 장점이 있었다! 요 함수는 꼭,, 따로 구글링해보며 찾아보기! 1번째 풀이에서 썼던 replace기능함수의 단점들을 보안해준 함수 같다.ㅎㅎ 그리고 이전엔 for-if-else를 다쓰며 훨씬 복잡하고 한 눈에 보기어려웠다면 2번째 풀이는 for문은 쓰지 않고 if문도 한줄로 줄여쓰니 훨씬 보기편하고 이해도 빨리 할 수 있었다

주석 2단계부분에서 sub('[^a-z0-9-_.]','',answer1)이부분 에서 (^) 이 특수기호가 [ ]이 안에있는 문자들과 기호만 answer1값으로 지정해준다는 것이고 만약 (^)이 기호가 없다면 [ ] 안에있는 문자들과 기호를 제외한 모든 문자들만 answer1값으로 지정해준다는 것이다. 

 

프로그래머스를 풀어보며 내 풀이 뿐아니라 다른사람의 풀이도보고 어떤 함수를 썼는지 찾아보며 나의 방식대로 써먹는게 내 실력향상에 정말 큰 것같다.

문제 풀때 테스트케이스를 다 통과했다해서 그냥 넘어가지말고 다른풀이들도 찾아보고 그 중 내가 모르고있던 부분은 더 찾아보고 IDLE로 기본 예제도 직접 실행해보며 익히는게 실력 쌓아가는데에 더 큰 도움을 주는 것  같다.ㅎㅎ

 

읽어주셔서 감사합니다!!!

잘못된 부분 지적은 환영입니다 ㅎㅎ

 

Comments