Stay Hungry Stay Foolish

SWEA

[SWEA] 1228. [S/W 문제해결 기본] 8일차 - 암호문1 (Python/D3)

dev스카이 2024. 10. 30. 18:27

[문제 링크] 👇

 

SW Expert Academy

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

swexpertacademy.com


풀이

입력 데이터 파싱

  • 명령어를 "I" 구분자로 나누어 저장한다.

 

명령어 처리

  • 각 명령어를 다시 리스트로 따로 저장하고, 이를 통해 삽입위치, 삽입할 값의 개수, 그리고 삽입할 값들을 구분한다.
  • 빈 명령어는 생략하고, 각 명령어에서 위치와 값을 추출해 기존 리스트에 삽입한다.

 

삽입 실행

  • 기존 리스트에 주어진 위치에 값을 차례로 삽입한다.
  • 위치를 잘 관리하여, 삽입할 때마다 원본 리스트의 위치가 변동되는 점에 유의한다.

 

출력

  • 기존 리스트의 앞 10개 값을 result로 출력한다.

Solution

for test_case in range(1, 11):
    _ = int(input())
    origin = list(map(int, input().split()))
    _ = int(input())
    command = list(map(str, input().split("I")))  # I 구분자 기준으로 분리하여 저장

    for i in command:
        command_list = list(map(int, i.split()))  # 명령어를 한 줄씩 꺼내서 다시 따로 저장
        if len(command_list) == 0:  # 첫 번째 리스트는 비어있기 때문에 무시하는 코드 작성
            continue
        for j in range(command_list[1]):
            origin.insert(command_list[0] + j, command_list[j + 2])  # 원하는 위치 i 앞에 추가할 값 x를 삽입

    result = origin[:10]  # 10번째까지만 출력

    print(f"#{test_case} {' '.join(map(str, result))}")

 

개선할 부분

  • 불필요한 조건문 제거
    • command_list가 비어 있는지 확인하는 조건이 있지만, split("I")를 사용했기 때문에 처음 요소만 빈 리스트가 될 가능성이 높다. 이 부분을 슬라이싱을 통해 command[1:]로 접근하면 첫 번째 빈 요소를 무시할 수 있다.
  • 명령어 처리 최적화
    • origin.insert()는 매번 리스트를 이동시키므로, 반복적으로 호출하면 성능 저하가 생길 수 있다. 따라서, 삽입 명령어를 미리 한 번에 계산해 origin에 추가하는 것이 효율적이다.
  • 데이터 가공 최적화
    • command에서 각 명령을 미리 나누고 각 부분에 대해 필요한 처리를 하도록 하면 코드가 더 간결해진다.

 

최적화된 코드

for test_case in range(1, 11):
    _ = int(input())
    origin = list(map(int, input().split()))
    _ = int(input())
    command = input().split("I")[1:]  # 첫 번째 빈 요소를 제거하고 시작

    for i in command:
        command_list = list(map(int, i.split()))
        insert_position = command_list[0]
        num_to_insert = command_list[2:]
        
        # 해당 위치에 명령어대로 값 삽입
        origin[insert_position:insert_position] = num_to_insert

    # 10번째까지만 출력
    result = origin[:10]
    print(f"#{test_case} {' '.join(map(str, result))}")

 

 

 

👩‍💻 회고

실수한 부분

 for j in range(command_list[1]):
            origin.insert(origin[command_list[0] + j], command_list[j + 2])

 

처음에 이렇게 했는데 원하는 값이 안 나오길래 for 문 돌리면서 일일이 출력해봤는데 계속 orgin 맨 뒤에 값이 추가됐었다. 다시 확인해보니 origin[command_list[0] + j]에서 리스트 값 origin[command_list[0] + j]를 인덱스로 넣고 있었다. 이 때문에 insert()가 참조한 값의 위치에 추가하지 않고, 맨 끝에 추가된 것이었다. 그래서 해당 위치 인덱스만 전달하도록 수정했다. 

이미 origin에 insert() 를 하고 있는데 또 origin 리스트의 인덱스에 추가하니 중첩이 돼서 맨 뒤에 값이 추가된 것 같다. 

 

이것 때문에 계속 테스트 해보느라 시간을 많이 썼다. 분명 맞게 썼는데 자꾸만 맨 뒤에만 추가 되니 미칠 뻔 했다...

 

새로 알게 된 점

join() 을 사용할 때 정수 리스트는 안 된다. 정수 리스트에 대해 join() 을 사용하려고 하면 TypeError 가 발생한다. 그래서 정수형 리스트를 join() 하려면 리스트의 요소를 모두 문자열로 변환한 후 사용해야 한다.