문제
[1212번] 8진수 2진수 : www.acmicpc.net/problem/1212
8진수를 2진수로 변환하는 간단한 문제였다.
하지만 나는 진법 변환하는 문제를 처음 풀어보았고 파이썬 내장 함수에 대해서 모르고 있었다.
그렇기 때문에 브론즈 4문제 치고 많은 코드를 쓰게 되었다.
코드
[첫 번째 시도]
import sys
n = list(map(int, sys.stdin.readline().rstrip()))
def EightTwo(list):
result = ''
for i in range(len(list)):
if list[i] == 0:
result += '000'
elif list[i] == 1:
result += '001'
elif list[i] == 2:
result += '010'
elif list[i] == 3:
result += '011'
elif list[i] == 4:
result += '100'
elif list[i] == 5:
result += '101'
elif list[i] == 6:
result += '110'
else:
result += '111'
return result
result = EightTwo(n)
while result[0] == '0':
result = result[1:]
print(result)
위가 내 첫 번째 코드였다.
result에 한 숫자씩 2진수로 변환한 뒤 while문을 통해 제일 앞이 0이면 그 뒤부터를 다시 result에 저장하고 출력하는 알고리즘이었다.
하지만 이 코드는 시간 초과가 떴고 다른 사람들이 한 질문을 보다가 result라는 곳에 2진수로 변환한 수를 저장하지 말고 바로바로 출력하는 알고리즘을 사용하는 게 어떻냐는 답변을 보았다.
그 후 바로 코드를 다시 짜 보았다.
[두 번째 시도]
import sys
n = list(map(int, sys.stdin.readline().rstrip()))
def EightTwo(list):
for i in range(len(list)):
if list[i] == 0:
if i == 0:
print('0', end='')
else:
print('000', end='')
elif list[i] == 1:
if i == 0:
print('1', end='')
else:
print('001', end='')
elif list[i] == 2:
if i == 0:
print('10', end='')
else:
print('010', end='')
elif list[i] == 3:
if i == 0:
print('11', end='')
else:
print('011', end='')
elif list[i] == 4:
print('100', end='')
elif list[i] == 5:
print('101', end='')
elif list[i] == 6:
print('110', end='')
else:
print('111', end='')
EightTwo(n)
사실 0을 입력받았을 때 0이 아닌 000을 출력해서 한 번 틀렸었다. 하지만 금방 오류를 잡았고 이 코드로 수정했다.
결과는 맞았다. 하지만 시간이 많이 소비되었고 나는 무언가 내가 잘못된 알고리즘을 사용하고 있다는 것을 깨달았다.
그래서 이 문제를 맞은 사람의 코드를 하나씩 보게 되었다.
맞은 사람들의 코드를 크게 나누면 3 분류였다.
bin으로 푼 사람, format으로 푼 사람, 나처럼 푼 사람들이었다.
알게 된 점
1. bin으로 푼 사람
print(bin(int(input(), 8))[2:])
딱 한 줄로 풀었다. 이 코드를 보고 아직 나는 햇병아리에 불과하다는 것을 알게 되었다.
먼저 int(input(), 8)에 대해서 알아보았다.
print(int(input()))
# 314 -> 314
print(int(input(), 2))
# 11 -> 3
print(int(input(), 8))
# 314 -> 204
print(int(input(), 16))
# 314 -> 788
int(a, b)는 b진수인 a를 10진수로 바꾸어 주는 함수였다.
즉, 8진수인 314를 10진수로 바꾸어주니 204가 된 것이다.
그다음 bin()에 대해서 알아보았다.
print(bin(int(input(), 8)))
# 314 -> 0b11001100
print(bin(int(input(), 8))[2:])
# 314 -> 11001100
bin(n)는 10진수인 n을 2진수 값으로 변환해 주는 함수였다.
2진수의 표현은 0b를 앞에 붙여서 쓰기 때문에 314를 그냥 bin()으로 출력하면 0b11001100이 나오게 된다.
그렇기 때문에 인덱스 2부터 끝까지 출력하기 위해 [2:]을 붙여서 쓰게 되면 원하는 답인 11001100이 나오게 된다.
참고로 아래는 8진수와 16진수 값으로 변환해 주는 함수다.
bin(n)
# 10진수인 n을 2진수 값으로 변환해 주는 함수
# 0b로 시작
oct(n)
# 10진수인 n을 8진수 값으로 변환해 주는 함수
# 0o로 시작
hex(n)
# 10진수인 n을 16진수 값으로 변환해 주는 함수
# 0x로 시작
2. format으로 푼 사람
print(format(int(input(), 8), 'b'))
앞서서 int(input(), 8)은 8진수인 입력된 값을 10진수로 변환해 주는 것이라는 걸 알았다.
그렇기 때문에 format(n, s)만 알면 된다.
format(n, s)는 10진수 n을 s에 들어가는 진수로 만들어 주는 함수다.
s에는 'b', 'o', 'x'가 들어갈 수 있다.
print(format(int(input(), 8), 'b'))
# 10진수를 2진수로 만들어주는 함수
# 314 -> 11001100
print(format(int(input(), 8), 'o'))
# 10진수를 8진수로 만들어주는 함수
# 314 -> 314
print(format(int(input(), 8), 'x'))
# 10진수를 16진수로 만들어주는 함수
# 314 -> cc
# format(n, s)에서 s 부분에 #을 붙여주면 접두어가 같이 출력된다
print(format(42, '#b'))
# 314 -> 0b11001100
print(format(int(input(), 8), '#o'))
# 314 -> 0o314
print(format(int(input(), 8), '#x'))
# 314 -> 0xcc
더 풀어볼 문제
[1373번] 2진수 8진수 : www.acmicpc.net/problem/1373
[1550번] 16진수 : www.acmicpc.net/problem/1550
[2998번] 8진수 : www.acmicpc.net/problem/2998
[3460번] 이진수 : www.acmicpc.net/problem/3460
[8741번] 이진수 합 : www.acmicpc.net/problem/8741
[10829번] 이진수 변환 : www.acmicpc.net/problem/10829
[11179번] 2진수 뒤집기 : www.acmicpc.net/problem/11179
[11816번] 8진수, 10진수, 16진수 : www.acmicpc.net/problem/11816