관리 메뉴

솜씨좋은장씨

[BaekJoon] 2999번 : 비밀 이메일 (Python) 본문

Programming/코딩 1일 1문제

[BaekJoon] 2999번 : 비밀 이메일 (Python)

솜씨좋은장씨 2022. 8. 25. 19:41
728x90
반응형

코딩 1일 1문제! 오늘의 문제는 백준의 비밀 이메일 입니다.

 

2999번: 비밀 이메일

정인이는 원래 "bombonisuuladici"를 보내려고 했다. 이 메시지는 16글자이므로, 정인이는 1*16, 2*8, 4*4 행렬을 선택할 수 있다. R이 가장 큰 것은 4*4이므로, 4*4를 선택한다. 정인이가 만든 행렬은 다음과

www.acmicpc.net

👨🏻‍💻 문제 풀이

정인이가 사용하는 암호 알고리즘은 다음과 같다. 정인이가 보내는 메시지는 총 N글자이다.

먼저, 정인이는 R<=C이고, R*C=N인 R과 C를 고른다. 만약, 그러한 경우가 여러 개일 경우, R이 큰 값을 선택한다.

그 다음, 행이 R개고, 열이 C개인 행렬을 만든다.

-> 여기서 R과 C를 구하는데에는 글자의 길이인 N의 약수를 모두 구한 다음

-> 가장 R 값이 크게 나올 수 있도록 약수 중에 가운데 값을 활용했습니다.

def find_a_factor(N):
    factor_list = []
    cnt = 0
    
    for num in range(1, (N // 2) + 1):
        if N % num == 0:
            factor_list.append(num)
    return factor_list


def caculate_R_C(message_length):
    factor_list = find_a_factor(N=message_length)
    
    factor_list_len = len(factor_list)
    
    r_c_idx = factor_list_len // 2
    
    if factor_list_len < 2:
        R, C = 1, message_length
    elif factor_list_len % 2 == 0 and factor_list_len > 1:
        R = C = factor_list[r_c_idx]
    else:
        R, C = factor_list[r_c_idx], factor_list[r_c_idx + 1]
    
    return R, C

이제 메시지를 행렬에 옮긴다. 첫 번째 행의 첫 번째 열부터 C번째 열까지 메시지를 순서대로 옮긴 뒤, 남은 메시지는 두 번째 행, 세 번째 행,... R번째 행에 첫 번째 행을 채운 방법과 동일한 순서대로 옮긴다.

행렬에 모두 메시지를 옮겼다면, 이 것을 첫 번째 열의 첫 번째 행부터 R번째 행까지 차례대로 읽으면서 다시 받아 적는다. 그 다음에, 두 번째 열, 세 번째 열,..., C번째 열에 쓰여 있는 문자를 첫 번째 열을 읽은 방법과 동일하게 받아적는다.

-> 여기에서는 구한 R과 C를 활용하여 문자열을 R개로 균일 하게 자른 다음 

-> 자른 글자들의 첫번째 문자부터 꺼내와서 암호화 시킨 문자열을 만들었습니다.

def encrypt_message(message):
    encryped_message = ""
    message_length = len(message)
    
    if message_length > 3:    
        R, C = caculate_R_C(message_length=message_length)

        for row in range(R):
            for col in range(C):
                encrypt_idx = row + R * col
                encryped_message += message[encrypt_idx]
    else:
        return message
    
    return encryped_message

👨🏻‍💻 코드 ( Solution )

def find_a_factor(N):
    factor_list = []
    cnt = 0
    
    for num in range(1, (N // 2) + 1):
        if N % num == 0:
            factor_list.append(num)
    return factor_list


def caculate_R_C(message_length):
    factor_list = find_a_factor(N=message_length)
    
    factor_list_len = len(factor_list)
    
    r_c_idx = factor_list_len // 2
    
    if factor_list_len < 2:
        R, C = 1, message_length
    elif factor_list_len % 2 == 0 and factor_list_len > 1:
        R = C = factor_list[r_c_idx]
    else:
        R, C = factor_list[r_c_idx], factor_list[r_c_idx + 1]
    
    return R, C
    


def encrypt_message(message):
    encryped_message = ""
    message_length = len(message)
    
    if message_length > 3:    
        R, C = caculate_R_C(message_length=message_length)

        for row in range(R):
            for col in range(C):
                encrypt_idx = row + R * col
                encryped_message += message[encrypt_idx]
    else:
        return message
    
    return encryped_message


if __name__ == "__main__":
    message = input()
    print(encrypt_message(message))
 

GitHub - SOMJANG/CODINGTEST_PRACTICE: 1일 1문제 since 2020.02.07

1일 1문제 since 2020.02.07. Contribute to SOMJANG/CODINGTEST_PRACTICE development by creating an account on GitHub.

github.com

Comments