본문 바로가기

알고리즘 삽질장

[이코테] 정렬 - 국영수

반응형

해당 포스팅의 문제의 출처는 나동빈님의 이것이 취업을 위한 코딩 테스트 교재를 공부하면서 풀이할 때 본인의 사고 과정 흐름과 문제 풀이를 기록하기 위함 입니다. 

 


문제설명

도현이네 반 학생 N명의 이름과 국어, 영어, 수학 점수가 주어진다. 이 때, 다음과 같은 조건으로 학생의 성적을 정렬하는 프로그램을 만들어라.

  1. 국어 점수가 감소하는 순서로(감소 = 내림차순)
  2. 국어 점수가 같으면 영어 점수가 증가하는 순서로(증가 = 오름차순)
  3. 국어 점수와 영어 점수가 같으면 수학 점수가 감소하는 순서로(감소 = 내림차순)
  4. 모든 점수가 같으면 이름이 사전 순으로 증가하는 순서로(문자열 사전 순으로 증가 = 오름차순) 든, 아스키 코드에서 대문자는 소문자보다 작으므로 사전 순으로 앞에 온다)

입력조건

  • 첫째 줄에 도현이네 반의 학생 수 N(1 <= N <= 100,000)이 주어진다.
  • 둘째 줄부터 한 줄에 하나씩 각 학생의 이름, 국어, 영어, 수학 점수가 공백으로 구분해 주어진다
  • 점수는 1보다 크거나 같고, 100보다 작거나 같은 자연수이다.
  • 이름은 알파벳 대소문자로 이루어진 문자열이고, 길이는 10자리를 넘지 않는다.

출력조건

  • 문제에 나와 있는 정렬 기준으로 정렬한 후 첫째 줄부터 N개의 줄에 걸쳐 각 학생의 이름을 출력한다.

사고과정

  • 파이썬 정렬 메소드인 sort, sorted 에서 다중 조건을 주는 것이 구체적으로 문법이 생각나지 않아서 구글링해서 해결함
  • 이외에 주목해야 할 점은 리스트 안에 튜플로 원소를 가진다면 리스트를 정렬했을 때, 기본적으로 튜플 원소를 기준으로 자동 정렬됨(Only 튜플만)
  • key, lambda 를 이용해 다중 정렬 조건 부여 가능. 포인트는 -로 하면 내림차순을 의미

풀이

스스로 푼 풀이

내가 푼 풀이는 입력을 받을 때 정수형에 해당하는 점수 값들을 int 형으로 일일이 바꾸어줌

import sys

n = int(input())
array = []
for _ in range(n):
    name, kor, eng, mat = input().split()
    kor, eng = int(kor), int(eng)
    mat = int(mat)
    array.append((name, kor, eng, mat))

# 이름, 국, 영, 수
array = sorted(array, key=lambda x: (-x[1], x[2], -x[3], x[0]))

for i in range(len(array)):
    print(array[i][0])

책 속 풀이

그러나 책 풀이에서는 튜플이 아닌 리스트를 활용함. 그리고 key 인자로 줄 때 int() 로 감싸주면 자동으로 원소값을 정수형으로 변환 후 정렬 시킴. 그래서 코드가 더 간결화됨

import sys

n = int(input())
array = []
for _ in range(n):
    array.append(input().split())

# 이름, 국, 영, 수
array = sorted(array, key=lambda x: (-int(x[1]), int(x[2]), -int(x[3]), x[0]))

for i in range(len(array)):
    print(array[i][0])

 

반응형