HeoBrain AI · DEV · GROWTH

HEO BRAIN · DEV LAB

배운 것을 구조화하고,
실제로 작동하게 만듭니다.

AI, 코딩, 영어, 포트폴리오를 직접 공부하고 만들며 얻은 지식을 누구나 다시 써먹을 수 있게 정리합니다.

heobrain.workflow LIVE
01 collect(experience) 02 structure(knowledge) 03 ship(something useful)

EMAIL NEWSLETTER

새 글을 이메일로 받아보세요

하루 동안 올라온 HeoBrain의 새 글을 매일 오후 8시에 한 통으로 보내드립니다.

인증 이메일의 링크를 눌러야 구독이 완료되며, 언제든 해지할 수 있습니다.

LATEST NOTES

최근에 정리한 글

모든 글 보기

Day20)프로그래머스: 정렬, 인덱스 보존, 실수의 정수 부분, 문자열을 숫자로 다루는 방법

이 글의 목차 펼치기

Python 코딩테스트 학습 기록

이번에는 정렬, 인덱스 보존, 실수의 정수 부분, 문자열을 숫자로 다루는 방법을 함께 정리했다. 정답만 적기보다 처음 풀이에서 어떤 정보가 빠졌는지와 짧은 풀이가 동작하는 이유까지 기록해 두었다.

1. 뒤에서 5등 위로

가장 작은 다섯 수를 제외하고, 남은 수를 오름차순으로 반환하는 문제다. 정렬한 뒤 앞의 다섯 칸을 슬라이싱으로 건너뛴다.

def solution(num_list):
    return sorted(num_list)[5:]

sorted(num_list)로 새 리스트를 오름차순 정렬하고, [5:]로 인덱스 5부터 끝까지 가져온다. 인덱스는 0부터 시작하므로 가장 작은 다섯 수가 제외된다.

2. 전국 대회 선발 고사

참석 가능한 학생 중 등수가 높은 세 명을 고른 뒤, 그 학생 번호를 10000 × a + 100 × b + c에 넣는 문제다. 정렬 기준은 등수지만 최종 답에 필요한 값은 학생 번호라는 점이 핵심이다.

처음 풀이에서 놓친 점

def solution(rank, attendance):
    box = []
    for seq, is_true in zip(rank, attendance):
        if is_true:
            box.append(seq)

    top3 = sorted(box)[:3]
    return 10000 * top3[0] + 100 * top3[1] + 100 * top3[2]

참석 가능한 학생의 등수만 box에 담으면 그 등수가 몇 번 학생의 등수였는지 알 수 없다. 또한 마지막 값 c에는 100을 곱하지 않는다.

내 풀이: 등수를 찾은 뒤 원래 위치 확인하기

def solution(rank, attendance):
    box = []

    for score, can_attend in zip(rank, attendance):
        if can_attend:
            box.append(score)

    top3 = sorted(box)[:3]
    a = rank.index(top3[0])
    b = rank.index(top3[1])
    c = rank.index(top3[2])

    return 10000 * a + 100 * b + c

zip(rank, attendance)는 같은 위치의 등수와 참석 여부를 한 쌍으로 꺼낸다. 이 문제는 모든 등수가 서로 다르므로 rank.index()로 원래 학생 번호를 다시 찾아도 안전하다.

기본 풀이: 등수와 학생 번호를 함께 저장하기

def solution(rank, attendance):
    candidates = []

    for student_no, (score, can_attend) in enumerate(zip(rank, attendance)):
        if can_attend:
            candidates.append((score, student_no))

    top3 = sorted(candidates)[:3]
    a = top3[0][1]
    b = top3[1][1]
    c = top3[2][1]

    return 10000 * a + 100 * b + c

enumerate()는 학생 번호와 값을 함께 준다. (등수, 학생 번호) 형태의 튜플은 첫 번째 값인 등수를 기준으로 정렬된다. top3[0][1]은 첫 번째 튜플의 두 번째 값, 즉 학생 번호다.

짧은 풀이: 리스트 컴프리헨션과 튜플 정렬

def solution(rank, attendance):
    arr = sorted((score, i) for i, score in enumerate(rank) if attendance[i])
    return arr[0][1] * 10000 + arr[1][1] * 100 + arr[2][1]

이 한 줄은 학생 번호와 등수를 함께 꺼내고, 참석자만 남기고, (등수, 학생 번호)로 묶어 정렬하는 과정을 압축한 것이다.

다른 풀이 1: 딕셔너리 사용

def solution(rank, attendance):
    rank_to_student = {}

    for i, can_attend in enumerate(attendance):
        if can_attend:
            rank_to_student[rank[i]] = i

    sorted_ranks = sorted(rank_to_student)
    a = rank_to_student[sorted_ranks[0]]
    b = rank_to_student[sorted_ranks[1]]
    c = rank_to_student[sorted_ranks[2]]

    return 10000 * a + 100 * b + c

참석 가능한 학생만 {등수: 학생 번호} 형태로 기록한다. 이 문제는 등수가 중복되지 않아 딕셔너리 키로 사용할 수 있다.

다른 풀이 2: 학생 번호를 key로 정렬

def solution(rank, attendance):
    attendees = [i for i, can_attend in enumerate(attendance) if can_attend]
    attendees.sort(key=lambda i: rank[i])

    a, b, c = attendees[:3]
    return 10000 * a + 100 * b + c

key=lambda i: rank[i]는 학생 번호를 정렬할 때 해당 학생의 등수를 기준으로 줄 세우라는 뜻이다.

3. 정수 부분

def solution(flo):
    return int(flo)

int(3.14)3을 반환한다. 이 문제처럼 정수 부분을 의도적으로 반환할 때 가장 명확한 표현이다.

def solution(flo):
    return flo // 1

flo // 1도 입력이 0 이상이면 값은 같지만 결과가 3.0처럼 실수형이다. 또 음수에서는 int(-1.2)-1, -1.2 // 1-2.0이므로 일반적으로 같은 방법이 아니다.

4. 문자열 정수의 합

내 풀이

def solution(num_str):
    answer = 0

    for char in num_str:
        answer += int(char)

    return answer

문자열을 순회하면 한 글자씩 나온다. "123"을 순회하면 "1", "2", "3"이 차례대로 나온다. 글자는 문자이므로 int()로 바꾼 뒤 더한다.

더 간단한 풀이

def solution(num_str):
    return sum(map(int, num_str))
def solution(num_str):
    return sum(int(char) for char in num_str)

list(num_str)는 필요 없다. 문자열은 리스트는 아니지만, 글자를 순서대로 꺼낼 수 있는 반복 가능한 객체이므로 formap에서 그대로 사용할 수 있다.

5. 문자열을 정수로 변환하기

def solution(n_str):
    return int(n_str)

int("8542")는 정수 8542를 반환한다. "0010"도 정수로 바꾸면 10이 된다. 문자열 형태가 필요하다면 str(int(n_str))처럼 다시 문자열로 변환한다.

오늘 기억할 것

정렬 기준과 최종 답에 필요한 값이 다르면 인덱스 정보를 잃지 않는다.

문자열은 리스트가 아니지만 반복 가능하므로 바로 순회할 수 있다.

짧은 코드보다 먼저 여러 줄로 데이터 흐름을 확인한다.

EMAIL NEWSLETTER

새 글을 이메일로 받아보세요

하루 동안 올라온 HeoBrain의 새 글을 매일 오후 8시에 한 통으로 보내드립니다.

인증 이메일의 링크를 눌러야 구독이 완료되며, 언제든 해지할 수 있습니다.

블로그 검색