
HSAT 3회 정기 코딩 인증평가 기출 | 플레이페어 암호
문제만 이해하면 금방 풀 수 있는 문제이다. 몇가지 체크포인트를 유의하자.
맵을 만들 때 빈 칸을 알파벳 순서대로 추가하기
: 입력받은 키 값을 set으로 바꾼 후 다시 list로 돌리자. 그러면 중복이 제거된다.
: 그 후 for문을 ascii A ~ Z까지의 범위로 돌리고, 입력받은 리스트에 알파벳이 있다면 추가x 없다면 추가 o
: 리스트에 저장된 값을 5*5 맵에 저장해주기
두글자씩 나누기(페어 찾기)
: i = 0부터 시작해서 while문으로 입력받은 메세지의 길이만큼 돌기
: 바로 오른쪽 글자와 현재 글자가 동일하다면 현재 글자에 X 붙이기, 이때 현재 글자가 X라면 Q 붙이기
동일하지 않다면 현재 글자와 오른쪽 글자를 페어로 묶고 저장.
: 마지막 글자가 혼자 남았다면 무조건 X 붙이고 저장
페어 두글자 암호화
: 같은 행에 존재하면, 현재 열번호에 +1 하기
이때, 1을 더한 열번호가 5를 넘어갈 수도 있으니 %5로 처리해주기
: 같은 열에 존재하면, 현재 행번호에 +1하기
위와 같이 5를 넘어갈 수 있으니 %5 처리
: 위 두 조건에 걸리지 않는 경우 서로 열 번호 교환
+) Softeer에서 바로 푸니까 디버깅도 안되고 그냥 하나하나 다 찍어봐야 마음ㅇ ㅣ편하더라 ,,,
import sys
message = input()
keys = list(set(input()))
key_maps = [[''] * 5 for _ in range(5)]
# 입력받은거에서 중복 제거하고, 그 뒤에 알파벳 붙이기
for i in range(ord('A'), ord('Z')+1):
char = chr(i)
if char not in keys and char != 'J':
keys.append(char)
# 맵 셋팅
for i in range(25):
key_maps[i//5][i%5] = keys[i]
# print(key_maps)
# LL -> LX LX
# XX -> XQ XX로 분리
# HELLOWORLD -> HE LX LO WO RL DX
# XXYYY -> XQ XY YX YX
# LEMONSTRAWBERRYAPPLEIUICE -> LE MO NS TR AW BE RX RY AP PL EI UI CE
pairs = []
i = 0
while i < len(message):
if i == len(message)-1:
pairs.append([message[i], 'X'])
break
if message[i] == message[i+1]:
if message[i] == 'X':
pairs.append([message[i], 'Q'])
else:
pairs.append([message[i], 'X'])
i += 1
else:
pairs.append([message[i], message[i+1]])
i += 2
def find_pos(target):
for i in range(5):
for j in range(5):
if key_maps[i][j] == target:
return i, j
# print(pairs)
result = []
for val in pairs:
x1, y1 = find_pos(val[0])
x2, y2 = find_pos(val[1])
if x1 == x2:
result.extend([key_maps[x1][(y1+1)%5], key_maps[x2][(y2+1)%5]])
elif y1 == y2:
result.extend([key_maps[(x1+1)%5][y1], key_maps[(x2+1)%5][y2]])
else:
result.extend([key_maps[x1][y2], key_maps[x2][y1]])
for val in result:
print(val, end = '')
