Post
복호화(백준 9046번) | Gihun Son

복호화(백준 9046번)

문제

암호학에서 치환 암호(substitution cipher)란, 평문에 들어있는 각각의 문자를 주어진 치환 방법으로 암호화하는 방법 중 하나다.

가장 단순한 방법은 평문의 알파벳을 암호문의 알파벳으로 대치시켜 치환시키는 것이다.

예를 들어, 아래와 같은 알파벳 대치표가 주어졌다고 하자.

  • 평문 알파벳 대치표 : abcdefghijklmnopqrstuvwxyz
  • 암호문 알파벳 대치표 : wghuvijxpqrstacdebfklmnoyz

위에 주어진 치환 방법을 통해 암호화하면 평문 “hello there”은 “xvssc kxvbv”가 된다.

한 가지 흥미로운 점은 영어 문법 특성상, 알파벳 ‘e’가 다른 영문 알파벳에 비해 자주 쓰인다는 것이다.

즉, 암호문 알파벳 대치표 없이 암호문을 복호화하려 할 때, 암호문 알파벳 빈도수를 체크하면 암호문 알파벳 빈도수 중 가장 빈번하게 나타나는 알파벳이 ‘e’라는 사실을 유추해볼 수 있다.

위 방법으로 암호문 알파벳의 빈도수를 체크하고, 가장 빈번하게 나타나는 문자를 출력하는 프로그램을 작성하면 된다.

만약 주어진 암호문에서 가장 빈번하게 나타나는 문자가 여러 개일 경우, 그 빈번한 문자 중 어느 것이 평문 알파벳 ’e’를 가리키는지 확실하게 알 수 없기 때문에 “모르겠음”을 의미하는 ‘?’를 출력하면 된다.

Untitled

나의 풀이

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import sys
from collections import defaultdict
T=int(input())

for _ in range(T):
    Input_str=sys.stdin.readline().strip()
    count_dic=defaultdict(int)
    for w in Input_str:
        if w==' ':
            continue
        count_dic[w]+=1
    sorted_w=sorted(count_dic.items(),key=lambda x:x[1])
    max_case=sorted_w.pop()
    if sorted_w and max_case[1]==sorted_w[-1][-1]:
        print('?')
    else:
        print(max_case[0])
    
  • defaultdict()의 사용법을 찾아보았다.
  • 위 코드는 각 문장을 입력으로 받고, 각 문자마다 몇 번 등장하는지 dictionary형태로 저장한 후, 정렬하여 가장 많이 나온 문자를 출력하는 코드이다.
  • 이 때, sort된 list에서 pop()을 하여 가장 빈도수가 높은 문자를 찾고, 이 빈도수와 같은 문자가 여전히 sorted_w에 남아있으면 “?”를 출력한다.
    • 주의) 만약 문자가 하나밖에 존재하지 않으면 sorted_w[-1][-1]을 할 때 오류가 발생한다. 따라서 조건에 sorted_w가 비어있는지 확인해주는 것이 중요하다.

추가적인 문법

  • from collections import defaultdict()
    • value에 어떤 타입으로 기본값을 설정할지 명시 ex) int, str, list, set 등등
This post is licensed under CC BY 4.0 by the author.