# [boj] 10989 수 정렬하기 3

[https://www.acmicpc.net/problem/10989](https://www.acmicpc.net/problem/10989) 

![](/assets/img/posts/Pasted%20image%2020230909165109.png)
_메모리 초과로 고생을 좀 했다..._

## 문제

N개의 수가 주어졌을 때, 이를 오름차순으로 정렬하는 프로그램을 작성하시오.

## 입력

첫째 줄에 수의 개수 N(1 ≤ N ≤ 10,000,000)이 주어진다. 둘째 줄부터 N개의 줄에는 수가 주어진다. 이 수는 10,000보다 작거나 같은 자연수이다.

## 출력

첫째 줄부터 N개의 줄에 오름차순으로 정렬한 결과를 한 줄에 하나씩 출력한다.

## 예제 입력 1

```
10
5
2
3
1
4
2
3
5
1
7
```

## 예제 출력 1

```
1
1
2
2
3
3
4
5
5
7
```
## 풀이

- 메모리 제한이 8MB로 리스트와 힙정렬이나 퀵정렬과 같은 일반적인 정렬 알고리즘을 사용했을 때 메모리 초과가 떴다.
- Counting sort를 사용해서 입력 받은 nums 이외에 counting에 필요한 메모리만 사용하도록 하여 메모리 사용량을 줄여봤다.
	- 하지만 계속해서 메모리 초과 오류가 떠서 메모리 사용을 줄일 수 있는 곳을 찾아보니 nums를 초기화할 때 list comprehension을 사용하지 않고 generator 표현을 사용하면 메모리 사용을 줄일 수 있다는 것을 찾게 되었다.
	

	```python
	import sys
	
	input = sys.stdin.readline
	N = int(input())
	# list comprehension 사용으로 리스트를 메모리에 저장하게 됨
	nums = [int(input()) for _ in range(N)]
	
	# 문제 조건을 참고하여 counts 리스트 선언
	counts = [0] * 10001
	for n in nums:
		counts[n] += 1
	  
	# counting sort
	for i, count in enumerate(counts):
		while count:
			print(i)
			count -= 1
	```
- 아래와 같이 6번째 줄을 generator 표현으로 바꿈으로써 입력 받은 숫자들을 모두 메모리에 올리지 않고 iteration을 돌 수 있도록 하여 문제를 해결하였다.
    
	```python
	...
	# generator를 통해서 리스트를 메모리에 두지 않고 nums 입력
	nums = (int(input()) for _ in range(N))
	...
	```
- 앞으로는 파이썬을 사용할 때 실행속도도 항상 염두에 두고 사용해야겠고 느꼈다.

## 참고자료
- [파이썬 실행속도 개선 방법](https://camel-it.tistory.com/140)

