SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
<나의 풀이>
문제를 보자마자 짜증이 난다.
MSB 오랜만이다.
단순하게 생각하면 가장 왼쪽에 있는 비트라고 생각하면 될듯하다.
주어진 문제에서는 총 24bit짜리 버퍼에 왼쪽부터 한 byte씩 총 3byte의 문자를 넣는다고 한다.
1 byte = 8bit
이후 MSB부터 6bit씩 잘라서 그 값을 읽고, 주어진 표에 따라서 Encoding 한다.
즉 주어지는 입력값을 암호라고 생각하고 이를 해독한다고 생각하면 이해하기 쉬워 보인다.
빠르게 입력값을 세팅해보자.
T = int(input())
for i in range(1,T+1):
S = input()
정상적으로 S에 문자열이 설정되었다.
이제 이를 디코딩해야 한다.
예를 들어서 T의 경우 표를 참고하면 19이다.
이는 표의 19번째 인덱스라는 것을 알 수 있다. (표를 리스트라고 가정한다면)
이 19를 2진법으로 표기하면 010011이다.
6자리로 표기한 이유는 6bit씩 자르고 이를 encoding 한 것이 T이기 때문이다.
따라서 이 모든 입력 문자열을 2진법으로 바꿔줘야 한다.
그리고 중요한 것은 처음 문자를 넣을 때 24bit에 3byte씩 문자를 넣는다고 했다.
이는 다시 말하면 3글자를 넣는데 24비트 -> 한 글자당 8 비트라는 것이다.
그런데 우리는 입력값을 표에 따라 2진법을 바꿨을 때 6자리(비트)로 바꿨던 것을 기억해야 한다.
진짜 결론은 입력값을 이진법으로 바꾼 수에서
MSB부터 8자리씩 자르고,
이를 10진법으로 표기한 후에
그 수를 아스키코드표를 보고 대입하면 해당하는 문자가 나오는 것이다.
라이브러리를 사용하지 않고 풀 수 있는지는 의문이지만, 아스키코드는 사용해야 한다는 것과
문법적인 방법을 통해 이진법 및 십진법 표기를 해낼 수 있어야 하는 문제이다.
다시 문제로 돌아와서 입력된 값의 문자 하나하나를 이진법으로 바꾸기 위해서는 표-1을 활용해야 한다.
따라서 우리는 표-1에 해당하는 리스트를 만들어줘야 한다.
sample = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/']
아까 말한 것처럼 T를 입력받는다면 sample 리스트 19번째 인덱스, 즉 19를 이진법으로 표기하면 된다.
그렇다면 이진법으로 변환하는 코드를 작성해야 한다.
주의할 점은 6자리로 표기해야 하는 것이다.
입력 문자열의 글자 수만큼 반복문을 실행해야 하므로 len()을 사용하면 좋겠다.
for j in range(len(S)):
number = sample.index(S[j])
글자를 표를 보고 바꾼 수를 number라고 하면, 이는 sample이라는 리스트에서 입력받은 S의 문자 하나랑 같은 것을 찾으면 된다.
그래서 index()를 사용하여 해당 인덱스 번호를 찾아온다. (이는 곧 문자의 숫자)
이 number를 2진법으로 표기하면 되는 것이다.
bit_num = str(bin(number))
파이썬에서 제공해주는 bin() 함수를 사용하면 간단하게 이진법으로 표기할 수 있다.
그런데 주의할 점은 앞에 2글자는 몇 진법인지를 표기해주기 때문에, 우리가 필요한 것은 2번째 자리부터이다.
따라서 문자열을 슬라이싱할 필요가 있다.
bit_num = str(bin(number)[2:])
그런데 예시 '19'처럼 5자리만 표기가 되는 것이 아니라 6자리로 표기하기 위해 앞자리에 0을 표기해주는 것이 필요하다.
이는 파이썬에서 제공하는 zfill()을 사용하면 된다.
bit_number = bit_num.zfill(6)
6자리를 기준으로 빈칸이 존재할 경우 앞에서부터 0을 채워준다.
이렇게 하면 입력 문자열의 한 글자를 바꾼 것이다.
따라서 모든 글자마다 이 과정을 반복해야 하고, 각 결과를 하나의 문자로 이어 줄 필요가 있다.
그래서 새로운 문자열 text_number을 선언하고 이에 순차적으로 저장을 해두자.
T = int(input())
for i in range(1,T+1):
S = input()
text_number = ''
for j in range(len(S)):
number = sample.index(S[j])
bit_num = str(bin(number)[2:])
text = bit_num.zfill(6)
text_number += text
010011000110100101100110011001010010000001101001011101000111001101100101011011000110011000100000011010010111001100100000011000010010000001110001011101010110111101110100011000010111010001101001011011110110111000101110
대략 이런 식으로 잘 저장되는 것을 확인했다.
이제 이 이진법으로 된 수를 8자리씩 자른 후 아스키코드로 해독을 하면 된다.
총길이를 확인하고 이를 8자리씩 자르는 과정이 필요하다.
for k in range(len(text_number)//8):
이렇게 시도를 해봤는데 에러가 발생했다.
다른 방법을 생각해보았는데, 주어지는 S의 길이에 6을 곱하고 8을 나누면 같은 값이 나올 것이라 생각해서 바꿔보았다.
T = int(input())
for i in range(1,T+1):
S = input()
t
ext_number = ''
for j in range(len(S)):
number = sample.index(S[j])
bit_num = str(bin(number)[2:])
text = bit_num.zfill(6)
text_number += text
for k in range(len(S)*6//8):
이후 0번째부터 8자리를 자르는 과정을 진행해야 한다.
text_number[0:8],text_number[8:16],...
이를 반복문과 연관 지어 작성해보면 다음과 같다.
for k in range(len(S)*6//8):
text_number[k*8:k*8+8]
이때 text_number[k*8:k*8+8]는 이진법으로 표기된 수이다.
이를 10진법으로 표기하려면 다음을 활용하면 된다.
int('2진법 수', 2) / int('8진법 수', 8) / int('16진법 수', 16)
for k in range(len(S)*6//8):
value = int(text_number[k*8:k*8+8],2)
마지막으로 10진법 수를 아스키코드 변환을 통해 바꿔주는 함수 chr()을 사용하자.
result = ''
for k in range(len(S)*6//8):
value = int(text_number[k*8:k*8+8],2)
result += chr(value)
최종 코드를 작성하면 다음과 같다.
sample = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/']
T = int(input())
for i in range(1,T+1):
S = input()
text_number = ''
for j in range(len(S)):
number = sample.index(S[j])
bit_num = str(bin(number)[2:])
text = bit_num.zfill(6)
text_number += text
result = ''
for s in range(len(S)*6//8):
value = int(text_number[s*8 : s*8+8],2)
result += chr(value)
print('#{} {}'.format(i,result))
정말 많은 개념이 담겼던 문제였다.
풀고 나서 힘이 빠지는 듯했으나 배운 것들을 잘 활용할 수 있도록 복습도 해야겠다.
'개발 > SWEA (D2) 문제 풀이' 카테고리의 다른 글
SW Expert Academy - 1945. 간단한 소인수분해(D2) (0) | 2022.11.13 |
---|---|
SW Expert Academy - 1940. 가랏! RC카!(D2) (0) | 2022.11.13 |
SW Expert Academy - 1288. 새로운 불면증 치료법(D2) (0) | 2022.11.12 |
SW Expert Academy - 1285. 아름이의 돌 던지기(D2) (0) | 2022.11.12 |
SW Expert Academy - 1284. 수도 요금 경쟁(D2) (0) | 2022.11.12 |
댓글