문제

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

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

www.acmicpc.net/problem/10825

  • 입력

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

  • 출력

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

lambda 함수

이 문제를 풀기 위해서는 lambda 함수 라는 것을 알아야 한다.

람다 함수는 이름 없이 간단히 사용할 수 있는 함수다. 실제 함수와 비교하면 아래와 같다.

#일반 함수
def func(x, y):
  return x+y

#람다 함수
lambda x,y : x+y

좀 더 복잡하게 map 함수 안에서 람다를 사용할 수도 있다.

print(map(lambda x : x*x, [1, 2, 3, 4, 5]))
#출력: [1, 4, 9, 16, 25]

print(map(lambda x, y : x+x, [1, 2, 3, 4, 5], [6,7,8,9,10]))
#출력: [7, 9, 11, 13, 15]

print(map(lambda x : x*2 if x % 2 == 0 else 0, [1,2,3,4,5,6,7,8,9,10]))
#출력: [0, 4, 0, 8, 0, 12, 0, 16, 0, 20]

이번 문제에서는 sort 함수 내에서 정렬의 기준이 되는 key 값을 람다 함수를 통해 정해준다. 코드는 아래에서 확인할 수 있다..

람다 함수에 대한 더 자세한 내용은 여기를 참고하자!

최종 코드

위에서 설명한 람다 함수를 사용한 코드는 아래와 같다. 조건 4순위부터 1순위 순서로 코딩해서 조건을 만족했다.

import sys

n = int(sys.stdin.readline())
arr = []
for i in range(n):
    name, kor, eng, math = sys.stdin.readline().split()
    arr.append([name, int(kor), int(eng), int(math)])

arr.sort(key = lambda array: array[0])
arr.sort(key = lambda array: array[3], reverse = True)
arr.sort(key = lambda array: array[2])
arr.sort(key = lambda array: array[1], reverse = True)

for student in arr:
    print(student[0])

Enhanced

위에서는 sort 함수를 4번이나 불렀는데, sort 한 번으로 더 간단하게 해결하는 방법도 있었다.

import sys

n = int(sys.stdin.readline())
arr = []
for i in range(n):
    name, kor, eng, math = sys.stdin.readline().split()
    arr.append([name, int(kor), int(eng), int(math)])

arr.sort(key = lambda array: -array[1], array[2], -array[3], array[0])

for student in arr:
    print(student[0])

참고 사이트