급하게 코테 준비할 일이 생겼습니다..
코테 준비 안 한지 너무 오래되어서 감이 아예 없어짐.

AI만 믿는다?

Day 1 (프로그래머스 Lv.1-2)

  1. 신규 아이디 추천
  2. 키패드 누르기
  3. 문자열 압축
  4. 오픈채팅방
  5. 실패율

문제 풀 때 체크할 사항

  1. 입출력 정확히 해석
  2. 조건 분기 설계
  3. Edge Case
  4. 상태 변수로 관리하는 습관
  5. 구현 순서 정리 능력

입력 받는 것 정리 -> 초기화 -> 반복문 돌면서 -> 조건처리 -> 결과 출력

시간분배

한 문제당 30분 타겟으로 했습니다.

10분 로직 생각 - 15분 풀이 - 10분(리뷰)
힌트나 문법 찾아보면서 끝까지 풀어봄


1. 프로그래머스 - 신규 아이디 추천

내가 작성한 코드

import re 

def solution(new_id):
   
    #First Round 치환 : 대문자 -> 소문자
    n = new_id.lower()
    
    #Second Round 제거 : 소문자,숫자,_,-,. 제외
    n = re.sub(r'[^a-z0-9\-_.]','',n)
    
    #Third Round 치환: 마침표 2번 이상 -> 하나의 마침표로 처리
    n = re.sub(r'\.+','.',n)
               
    #Fourth Round 치환: 마침표 처음이랑 끝에 있으면 제거
    n = n.strip('.')
    
    #Fifth Round 대입: new_id 빈 문자열 -> "a"대입
    if n == "":
        n = "a"
    
    #Six round 제거: 15개까지 허용, 제거 후 .가 처음과 끝에 있으면 제거
    if len(n)>=16:
        n = n[:15].strip('.')
    
    #Last: 2자 미만일 경우, 3자 이상이 될 때까지 끝 알파벳 추가
    while len(n) <=2 : 
        n += n[-1]

    return n

AI한테 제 코드에 대해서 리뷰도 받았습니다.

  1. 논리적으로 틀린 부분
  2. Edge case에서 깨질 수 있는 부분
  3. 코딩테스트에서 감점될 수 있는 습관 위주로 리뷰해줘.

AI가 개선한 내 코드

import re

def solution(new_id):
    user_id = new_id.lower()
    user_id = re.sub(r'[^a-z0-9\-_.]', '', user_id)
    user_id = re.sub(r'\.+', '.', user_id)
    user_id = user_id.strip('.')

    if not user_id:
        user_id = 'a'

    if len(user_id) > 15:
        user_id = user_id[:15].strip('.')

    while len(user_id) < 3:
        user_id += user_id[-1]

    return user_id

피드백 개선 후 코드인데? 흠 그냥 별 차이 없습니다. 바뀐 건 변수명,조건식 명확화,가독성 입니다.

이 연습에서 가져가야할 것

파이썬 문법

str.lower()
re.sub(pattern, repl, string)
str.strip('.')
슬라이싱: s[:15]
빈 문자열 체크: if not s
while 조건 반복


2. 프로그래머스 - 키패드 누르기

내가 작성한 코드

def solution(numbers, hand):
    #변수
    answer = ""
    key_pos = {1:(0,0),2:(0,1),3:(0,2),4:(1,0),5:(1,1),6:(1,2),
              7:(2,0),8:(2,1),9:(2,2),'*':(3,0),0:(3,1),'#':(3,2)}
    
    #초기 위치 설정
    left_pos = key_pos['*']
    right_pos = key_pos['#']

    for num in numbers:
    #1,4,7이 배열에 보일 경우, 무조건 L 출력
        if num in [1,4,7]:
            answer += "L"
            left_pos = key_pos[num]
    
    #3,6,9 배열에 보일 경우, 무조건 R 출력
        elif num in [3,6,9]:
            answer += "R"
            right_pos = key_pos[num]
    
    #2,5,8,0 -> 거리 계산 
        else:
            target = key_pos[num] #현재 위치
        
            dist_l = abs(target[0]-left_pos[0]) + abs(target[1]-left_pos[1])
            dist_r = abs(target[0]-right_pos[0]) + abs(target[1]-right_pos[1])
        
            if dist_l < dist_r:
                answer += "L"
                left_pos = target
            elif dist_l > dist_r:
                answer += "R"
                right_pos = target
            else:
                if hand == "left":
                    answer += "L"
                    left_pos = target
                else:
                    answer += "R"
                    right_pos = target
    return answer            

AI가 개선한 내 코드

def solution(numbers, hand):
    answer = ""

    positions = {
        1:(0,0), 2:(0,1), 3:(0,2),
        4:(1,0), 5:(1,1), 6:(1,2),
        7:(2,0), 8:(2,1), 9:(2,2),
        '*':(3,0), 0:(3,1), '#':(3,2)
    }

    left_keys = {1,4,7}
    right_keys = {3,6,9}

    left_pos = positions['*']
    right_pos = positions['#']

    for num in numbers:
        if num in left_keys:
            answer += "L"
            left_pos = positions[num]

        elif num in right_keys:
            answer += "R"
            right_pos = positions[num]

        else:
            target = positions[num]

            lx, ly = left_pos
            rx, ry = right_pos
            tx, ty = target

            dist_l = abs(tx - lx) + abs(ty - ly)
            dist_r = abs(tx - rx) + abs(ty - ry)

            if dist_l < dist_r:
                answer += "L"
                left_pos = target
            elif dist_l > dist_r:
                answer += "R"
                right_pos = target
            else:
                if hand == "left":
                    answer += "L"
                    left_pos = target
                else:
                    answer += "R"
                    right_pos = target

    return answer

파이썬 문법
딕셔너리로 좌표 매핑
튜플 언패킹
절댓값 거리 계산 (abs)
집합(set)으로 membership 체크


3. 프로그래머스 문자열 압축

내가 작성한 코드

def solution(s):
    
    #길이가 1이면?
    if len(s) == 1:
        return 1
    
    results = []
    
    #for문은 배열 처음 문자와 같은 문자가 발견되면 멈춤.
    for step in range(1,len(s)//2 + 1):
        compressed = ""
        prev = s[0:step]
        count = 1
        
        for j in range(step,len(s),step):
            curr = s[j:j+step]
            
            if prev == curr:
                count += 1
            else:
                compressed += (str(count)+prev) if count >= 2 else prev
                prev = curr
                count = 1
        
        compressed += (str(count)+prev) if count >= 2 else prev
        results.append(len(compressed))
        
    #가장 최소값 출력
    return min(results)

AI가 개선한 내 코드

def solution(s):
    if len(s) <= 1:
        return len(s)

    min_length = len(s)

    for step in range(1, len(s)//2 + 1):
        compressed = ""
        prev = s[:step]
        count = 1

        for idx in range(step, len(s), step):
            curr = s[idx:idx+step]

            if prev == curr:
                count += 1
            else:
                compressed += (str(count) + prev) if count > 1 else prev
                prev = curr
                count = 1

        compressed += (str(count) + prev) if count > 1 else prev
        min_length = min(min_length, len(compressed))

    return min_length

파이썬 문법
슬라이싱 with step
range(start, end, step)
문자열 누적
min 값 갱신 패턴


4. 프로그래머스 - 오픈채팅방

내가 작성한 코드

def solution(record):
    #record가 근데 문장 형태로 들어오잖아. 그러면 이걸 여기서 유저 id만 뽑아
    
    answer = []
    user_db = {}
    
    #Enter, Change
    for r in record:
        info = r.split()
        if info[0] in ["Enter", "Change"]:
            user_db[info[1]] = info[2]
    #Enter, Leave
    for r in record:
        info = r.split()
        if info[0] == "Enter":
            answer.append(f"{user_db[info[1]]}님이 들어왔습니다.")
        elif info[0] == "Leave":
            answer.append(f"{user_db[info[1]]}님이 나갔습니다.")
    return answer

AI가 개선한 내 코드

def solution(record):
    answer = []
    user_db = {}

    # 1. build final nickname mapping
    for log in record:
        info = log.split()
        if info[0] in ("Enter", "Change"):
            user_db[info[1]] = info[2]

    # 2. generate messages
    for log in record:
        info = log.split()
        if info[0] == "Enter":
            answer.append(f"{user_db[info[1]]}님이 들어왔습니다.")
        elif info[0] == "Leave":
            answer.append(f"{user_db[info[1]]}님이 나갔습니다.")

    return answer

파이썬 문법
str.split()
딕셔너리 업데이트
리스트 append
f-string


5. 프로그래머스 - 실패율

내가 작성한 코드

def solution(N, stages):
    answer = {}
    #분모는 스테이지에 있는 사람들 수
    denominator = len(stages)
            
    for i in range(1,N+1):
        if denominator != 0:
            count = stages.count(i)
            answer[i] = count / denominator
            denominator -= count
        else:
            answer[i] = 0
    #내림차순으로 정렬 : dic에서 만들었던 실패율만 뽑아냄
    res = sorted(answer.items(), key=lambda x:x[1], reverse = True) 
    #스테이지만 뽑아서 이제 나열
    return [s[0] for s in res]

AI가 개선한 내 코드

def solution(N, stages):
    failure_rate = {}
    denominator = len(stages)

    for stage in range(1, N + 1):
        if denominator > 0:
            count = stages.count(stage)
            failure_rate[stage] = count / denominator
            denominator -= count
        else:
            failure_rate[stage] = 0

    result = sorted(
        failure_rate.items(),
        key=lambda x: (-x[1], x[0])
    )

    return [stage for stage, _ in result]

파이썬 문법
.count()
dict에 비율 저장
sorted() + lambda
다중 정렬 기준


공통적인 개념

문자열

lower(), strip(), split()
슬라이싱
문자열 누적 vs 조건부 누적

‼️ 주의점
문자열 +=는 느릴 수 있음
→ 길어지면 리스트에 담고 ''.join()

temp = []
temp.append(c)
result = ''.join(temp)

자료구조

dict (상태 저장) : 키 -> 값
list (결과 저장) : 순서가 중요할 때, 결과 출력용
set (조건 체크) : 중복제거, 포함여부 체크

제어 흐름

if / elif / else 분기
for + range
while 조건 반복

정렬

sorted(iterable, key=lambda x: (조건1, 조건2))

‼️ 조건 섞기 (고급)

sorted(data, key=lambda x: (-x[1], x[0]))

👉 x[1] 내림차순, 같으면 x[0] 오름차순
🔥 코테에서 점수 + 번호 같이 정렬할 때 엄청 자주 나옴

profile
Challenging & Growing

0개의 댓글