본문 바로가기
백준/python

[Python/백준15552] sys 모듈을 활용한 빠른 입력

by EATSTAR 2024. 5. 24.
반응형
문제

첫 줄에 테스트케이스의 개수 T가 주어진다. T는 최대 1,000,000이다. 다음 T줄에는 각각 두 정수 A와 B가 주어진다. A와 B는 1 이상, 1,000 이하이다.

 

예제

입력


5
1 1
12 34
5 500
40 60
1000 1000

 

출력

2
46
505
100
2000

 

시간 제한
  • Java 8: 1.5 초
  • Java 8 (OpenJDK): 1.5 초
  • 나머지 언어 : 1초

음.. 이 문제는 조금 복잡하다. 일단, 입력을 살펴보면 6줄이다! 근데 줄력은 5줄인 것을 알 수 있다. 이것은 저 '5'라는 테스트케이스 T가 어떤 모듈에 의해 사용되어야 한다는 것을 시사한다 (원래 쓰던 input은 사용할 일이 없으므로)

 

기존에 입력을 할 때 쓰던 코드
a = int(input())
b, c = map(int,input().split())

한 정수를 입력받을 때는 input함수를 이용하고, 두 개 이상일 경우 map 함수와 split()도 이용한다.

그러나 이 문제를 풀 때 input 함수를 이용하면 시간초과가 뜨게 된다.. 그렇다면 어떻게 구성해야 하는가?

 

sys 모듈을 사용해보자!

sys 모듈을 사용하면 시간을 획기적으로 단축 가능하다.

sys.stdin.readline()를 이용하는 것이다!

 

# 변수가 1개이고, 정수형일 경우
b = int(sys.stdin.readline())

# 변수가 여러개고, 정수형일 경우
c, d = map(int, sys.stdin.readline().split())

 

import sys
T = int(sys.stdin.readline().strip())

result = []

for i in range(T):
    x, y = map(int, sys.stdin.readline().split())
    result.append(x + y)

for i in range(T):
    print(result[i])

 

일단 sys 모듈을 import하자.

 

strip()은 개행문자(\n)를 삭제하는데 이용된다. (안해주면 다음 답에 공백이 튀는 경우가 생길 수 있다.)

strip([chars])와 같이 입력하면 chars에 들어온 인자를 양쪽에서 제거한다. 하지만 우리는 공백을 지우므로

인자를 공백으로 간주해 strip()으로만 작성한다.

비슷하게, lstrip()과 rstrip()도 있는데 각각 인자를 왼쪽(left), 오른쪽(right)에서 제거한다. 물론, 다음의 올 공백문자를 지우는 것이라면 rstrip()도 활용할 수 있겠으나, 이 코드에서는 굳이 쓸 효용성이 없다.

직접적인 오류가 발생하지 않는다면 난 굳이 strip같은 함수를 쓰지 않는 주의이지만, 그래도 미연에 방지하는 것이 좋지 않은가 싶기도 하다.

 

우리가 한 개를 입력할 때마다 출력을 할 것은 아니므로 result[]라는 배열을 생성하고

append로 배열을 이어나간다. 그리고 T만큼 반복해서 result[i]를 출력하면 된다.

 

다른 사람의 관점

백준에 등록되어있는 다른사람의 소스코드로 성향을 분석해보자.

import sys

case_num = int(sys.stdin.readline().rstrip())

for num in range(case_num):
    a,b = map(int, sys.stdin.readline().rstrip().split())
    
    print(a+b)

이 사람도 유사하지만 배열을 생성하지 않았다. 그리고 a, b 값을 받자마자 출력하고 또 a,b값을 받고 출력하는 형식으로 작동한다는 것을 알 수 있다. 나의 코드는 모든 입력을 마친 이후 출력을 한번에 한다는 점에서 다르다.

 

T = int(input())
import sys

for _ in range(T):
    a,b = map(int,sys.stdin.readline().split())
    print(a+b)

이 코드도 특이하다. 일반적으로 for i in ~으로 쓰는데 i와 같은 루프 인덱스 자리에 _를 써놨다.

찾아보니 그냥 루프 인덱스를 사용하지 않고 반복한다는 의미로 (마치 void와 같이) 사용한다고 한다.

나도 i를 코드 내에서 사용하지는 않으므로 _로 대체해도 가능할 것이다.

 

import sys
input = sys.stdin.readline
n = int(input())
pairs = [tuple(map(int, input().split())) for _ in range(n)]


for a, b in pairs:
    result = a + b
    print(result)

tuple이라는 것을 이용한 것도 눈에 띈다.

 

import sys
i = 1
T = int(input())
while i <= T:
    A, B = map(int, sys.stdin.readline().split())
    print(A + B)
    i += 1

for 문이 아닌, while 문으로 구성한 경우다.

 

import sys

for _ in range(int(input())):
  print(sum(map(int,sys.stdin.readline().rstrip().split())))

할 수 있는 것을 다 했다. _사용, range 안에 바로 갯수 집어넣기, 한줄로 바로 프린트(!!)

sum이라는 함수도 이용했다. 원래 리스트의 합을 구할 때 잘 사용되는 함수인 모양. 이것도 2개의 인수가 있으니 리스트긴 하다.

 

1일 전 정도 코드까지만 수집했는데 스타일이 정말 다양하다는 것을 느낀다. 이것이 코딩의 묘미이지 않은가?

 

여담

사실 input()를 안쓰는 것에 대한 시간 절감이 잘 체감이 되지 않지만 데이터의 양이 많아지만 차이가 점점 생길 것이다.

Google Colab에서는 도저히 sys~가 실행이 되지 않는 시스템이라 고생했다. IDLE로 하는 수 밖에 없다.

반응형