해당 게시글에서는 [백준] 1431 시리얼 번호 문제를 해설하고 Python
을 이용하여 풀고자 한다.
🤔 접근법
1341번 문제는 정렬
에 관한 문제이다.
애초에 문제에서 정렬이라고 밝히고 있기 때문에 정렬 문제라는 걸 아는 건 크게 어렵지 않을 것이다.
시리얼번호 A가 시리얼번호 B의 앞에 오는 조건은 다음과 같이 해석할 수 있다.
- A와 B의 길이가 다르면, 짧은 것이 먼저 온다. 👉 문자열의 길이에 따라 정렬
- 만약 서로 길이가 같다면, A의 모든 자리수의 합과 B의 모든 자리수의 합을 비교해서 작은 합을 가지는 것이 먼저온다. (숫자인 것만 더한다) 👉 각 자리 숫자의 모든 합에 따라 정렬
- 만약 1,2번 둘 조건으로도 비교할 수 없으면, 사전순으로 비교한다. 숫자가 알파벳보다 사전순으로 작다. 👉 사전순 정렬(기본 sort 정렬)
따라서 람다함수를 통해 정렬의 우선 순위에 따라 인자를 잘 넘겨주면 될 것이라 생각했다.
하지만 첫 번째, 세 번째 조건은 len() 함수와 일반적인 sort를 쓰면 될 것이라 생각했지만, 두 번째 조건을 처리할 방법을 모르겠어서 다른 블로그를 참고했다.
💡 문제 풀이
이제 문제의 조건은 모두 파악했으므로 sort
함수와, 정렬의 조건이 되는 lambda
식을 잘 작성하면 된다.
첫 번째 조건은 len 함수를, 세 번째 조건은 원래 값을 lambda에 넘겨주면 되지만, 두 번째 조건을 바로 나타낼 수 있는 함수는 없다.
따라서 다음과 같이 string에서의 숫자 문자들의 합을 반환하는 함수를 정의했다.
1
2
3
4
5
6
def sum_digit(str):
ans = 0
for s in str:
if s.isdigit():
ans += int(s)
return ans
모든 조건을 처리할 수 있게 됐으므로 이제 lambda 식을 작성하면 된다.
lambda를 통해 여러 조건에 따른 정렬을 할 때, 조건이 앞
에 올수록 먼저 정렬된다는 것을 알아두자. 또 lambda에 넘겨준 매개변수의 값이 작을수록 앞에 위치한다.
우선순위가 큰 것이 앞에 와야하므로 첫 번째 조건인 string의 길이를 나타내는 len(x)를 맨 앞에, 두 번째 조건인 sum_digit(x)를 그 다음에, 사전순 정렬(일반 정렬)을 나타내는 x를 마지막에 작성했다.
1
sorted(num, key=lambda x:(len(x), sum_digit(x), x))
📂 Code
위 문제 풀이 방식을 통해 해당 문제를 풀어낸 필자의 코드는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
import sys
read = sys.stdin.readline
def sum_digit(str):
ans = 0
for s in str:
if s.isdigit():
ans += int(s)
return ans
num = [read().strip() for _ in range(int(read().strip()))]
for n in sorted(num, key=lambda x:(len(x), sum_digit(x), x)):
print(n)