
급하게 코테 준비할 일이 생겼습니다..
코테 준비 안 한지 너무 오래되어서 감이 아예 없어짐.
AI만 믿는다?
입력 받는 것 정리 -> 초기화 -> 반복문 돌면서 -> 조건처리 -> 결과 출력
한 문제당 30분 타겟으로 했습니다.
10분 로직 생각 - 15분 풀이 - 10분(리뷰)
힌트나 문법 찾아보면서 끝까지 풀어봄
내가 작성한 코드
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한테 제 코드에 대해서 리뷰도 받았습니다.
- 논리적으로 틀린 부분
- Edge case에서 깨질 수 있는 부분
- 코딩테스트에서 감점될 수 있는 습관 위주로 리뷰해줘.
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 조건 반복
내가 작성한 코드
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 체크
내가 작성한 코드
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 값 갱신 패턴
내가 작성한 코드
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
내가 작성한 코드
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] 오름차순
🔥 코테에서 점수 + 번호 같이 정렬할 때 엄청 자주 나옴