Daily Pogle

SWEA 1228. 암호문1 - Python 본문

알고리즘/SW Expert Academy

SWEA 1228. 암호문1 - Python

pogles 2023. 1. 20. 11:56

SW Expert Academy

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com


( + 개선코드 추가 )

 

해당 문제는 문자열처리만 잘 생각하고 푸는 것이 중요하다고 느꼈다.

로직자체는 쉬운데 문자열을 받을 때 잘생각하지 않으면 계속 꼬이는 문제였다.

 

 

문제조건 이해하기

 

첫번째줄 : 원본 암호문 길이

두번째줄 : 원본 암호문

세 번째 줄 : 명령어의 개수 ( 5 ≤ N ≤ 10 의 정수)


네 번째 줄 : 명령어 >>  I(삽입) x, y, s : 원본 암호문의 위치 x 바로 다음에 y개의 숫자를 삽입한다. s는 덧붙일 숫자들이다

.[ ex) I 3 2 123152 487651 ]

 

다음 네번째줄 예시의 의미는 다음과 같다.

I (삽입) 문자열 분리 기준
x = 3 원본 암호문 어디 위치에 삽입될 것인가? (3번째 위치삽입)
y = 2 몇개의 암호가 추가될 것인가? (2개의 암호추가)
s = 123152, 487651  추가할 암호들

 

 

command(암호문) 을 I 를 기준으로 split() 하면 빈 문자열이 받아지기 때문에 

이점을 유의해서 문자열을 다루면 될 것이다.

 

밑 코드에 print(command_lst) 를 넣어보면 첫 위치와 마지막 위치에 빈문자열(" ")이 받아지는 것을 확인할 수 있다.

def insert_to_pw(command): # 

    insert_index = int(command[0]) # x 의 위치 다음에
    #insert_len = int(command[1]) # (원본암호문 길이는 쓰이지 않음)
    for new_pw in command[2:]: # 삽입할 암호
        pw_lst.insert(insert_index,new_pw)
        insert_index+=1 # insert 하면 다음번호가 그 다음위치에 오기때문

def command(lst): # 빈문자열 주의

    for line in lst[1:]: # 첫번째 위치는 빈문자열
        one_command = line.split(" ")
        insert_to_pw(one_command[1:len(one_command)-1])  #마지막 위치도 빈문자열

# 여러개의 테스트 케이스가 주어지므로, 각각을 처리합니다.
T = 10
for test_case in range(1, T + 1):
    pw_num = int(input()) # 첫번째줄 : 원본암호문길이
    pw_lst = input().split(" ") # 두번째줄 : 원본암호문
    command_num = int(input()) # 세번째줄 : 명령문 개수
    command_lst = input().split("I") # 네번째줄 : 명령문 전체, I 를 기준으로 분리
    
    command(command_lst) 
    
    print(f"#{test_case}",end=" ")
    for pw in pw_lst[:10]:
        print(pw, end=" ")
    print()

 

 

느낀점

 

이 문제에 대해서 많은 분들이 JAVA 를 사용하여 풀으셨다. 

메모리 자체는 Python 이 불리했지만, 의아하게도 실행시간 자체는 Python 이 더 빨랐다는점이다.

 

정답자 기준으로 대체적으로 다음과 같이 볼 수 있었다.

 

메모리에서는 C++ > JAVA > Python

실행시간에서는 C++ > Python > JAVA

코드길이 Python > C++ > JAVA

 

 

확실히 C++ 이 성능면에서 매우 좋다. 역시 코테 상위권에서 애용되는 언어다.

하지만 코테대회 같은 고수가 될 것이 아니라면 Python 을 써야겠다는 생각이 들었다.

 

 


 

코드 개선사항

 

SWEA 의 암호문3 을 푸는데 위의 코드가 너무 하드코딩 같다는 생각이 들었다.

 

암호문 3에는 I A D 등 명령문이 추가되었다.

\

삽입, 제거, 추가 등 기능이 있다. 그런 경우에는 split() 을 계속 사용해서 나눌 수 없다. 그러면 매우 꼬이는 상황이 발생하므로 명령문을 처음부터 하나하나 검토하면서 처리하면 된다.

 

처리 방법으로 list.pop(0) 을 사용하였다. 또한 파이썬에서 list 는 전역변수로 사용되므로 계속 하나의 리스트를 사용하므로 효율적으로 구현할 수 있다.

 

 

def insert_pw():
    insert_pos = int(cmd_lst.pop(0))
    insert_len = int(cmd_lst.pop(0))
    for i in range(insert_len): # 암호문길이 만큼 삽입
        pw_lst.insert(insert_pos,cmd_lst.pop(0)) # 하나씩 뽑아서 삽입
        insert_pos+=1
        
    # 전부 작동하면 다음 알파벳 명령문을 만난다.
        
def check_cmd(len_cmd):
    while len(cmd_lst) > 0: # 명령문 모두 사용할때까지 계속
        cmd_opt = cmd_lst.pop(0)
        if cmd_opt == "I":
            insert_pw()
            
T = 10
for test_case in range(1, T + 1):
    len_pw = int(input())
    pw_lst = input().split()
    len_cmd = int(input())
    cmd_lst = input().split()
    check_cmd(len_cmd)
    print(f'#{test_case}',end=" ")
    for pw in pw_lst[:10]:
        print(f"{pw}",end=" ")
    print()