Stay Hungry Stay Foolish

SWEA

[SWEA] 1221. [S/W 문제해결 기본] 5일차 - GNS (Python/D3)

dev스카이 2024. 10. 26. 19:07

[문제 링크] 👇

 

SW Expert Academy

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

swexpertacademy.com


풀이

💡딕셔너리와 정렬 사용

각 단어의 순서를 매핑하는 딕셔너리를 사용하고, 주어진 문자열의 각 단어를 이 순서에 따라 정렬한다.

 

풀이 방법

  • 행성의 숫자 단어들을 리스트로 정의하고, 이를 이용해 순서 딕셔너리를 만든다.
  • 입력 문자열을 공백을 기준으로 분할하여 각 숫자 단어를 추출한다.
  • 각 단어를 딕셔너리 순서에 맞춰 정렬한다.
  • 정렬된 결과를 공백으로 연결하여 출력한다.

 

★ 딕셔너리 예시

planet_nums = ["ZRO", "ONE", "TWO", "THR", "FOR", "FIV", "SIX", "SVN", "EGT", "NIN"]
planet_dict = dict(zip(planet_nums, range(len(planet_nums))))  # list to dict
print(planet_dict)

 

출력 결과

{'ZRO': 0, 'ONE': 1, 'TWO': 2, 'THR': 3, 'FOR': 4, 'FIV': 5, 'SIX': 6, 'SVN': 7, 'EGT': 8, 'NIN': 9}
  • planet_nums 리스트
    • 각 숫자를 표현하는 문자열을 0에서 9까지 순서대로 나열한 리스트이다.
  • dict(zip(planet_nums, range(len(planet_nums))))
    • planet_nums 의 각 원소를 로, range(len(planet_nums)) 에서 생성된 각 인덱스를 값으로 하여 planet_dict 딕셔너리를 만든다.
  • 이로 인해 각 문자열이 그에 해당하는 숫자 값으로 매핑된다.

 

[딕셔너리 사용 방법] 🔗 https://dev-cloud.tistory.com/344

 

Solution

sol.1 (54,504 kb  / 237 ms)

T = int(input())
for test_case in range(1, T + 1):
    tc, tc_len = map(str, input().split())
    nums = list(map(str, input().split()))
    planet_nums = ["ZRO", "ONE", "TWO", "THR", "FOR", "FIV", "SIX", "SVN", "EGT", "NIN"]
    
    planet_dict = dict(zip(planet_nums, range(len(planet_nums))))  # list to dict
    value_list = []
    for key in nums:
        value_list.append(planet_dict[key])  # 키로 값에 접근해서 값만 저장
    value_list = sorted(value_list)
    
    # 리스트 인덱스에 맞게 출력
    result = []
    print(f"#{test_case}")
    for i in value_list:
        result.append(planet_nums[i])
    print(*result)

 

위 코드에서 성능을 조금 더 개선하고 간결하게 만들 수 있는 부분이 몇 가지가 있다. 주요 수정 사항은 리스트 컴프리헨션을 활용하여 중간 리스트를 줄이고, sorted() 에서 직접 변환과 정렬을 한 번에 처리하는 것이다. 이렇게 하면 코드가 더 깔끔해지고 불필요한 변수 생성도 줄어든다.

 

주요 변경 사항

  • planet_dict의 선언 방법 간소화
    • 리스트에서 딕셔너리를 생성하면서 인덱스도 바로 설정하도록 수정
  • 리스트 컴프리헨션과 sorted() 함수 사용
    • 중간에 value_list를 생성하지 않고, sorted(nums, key=lambda word: planet_dict[word])를 통해 바로 정렬된 리스트를 만듦
  • 출력 형식 간소화
    • print(' '.join(sorted_nums))를 사용해 정렬된 숫자 리스트를 바로 출력

 

최적화된 코드

T = int(input())
for test_case in range(1, T + 1):
    _, _ = input().split()  # 테스트 케이스 번호와 길이는 무시
    nums = input().split()  # 숫자 문자열 리스트 입력

    # 숫자 단어와 인덱스를 매핑하는 딕셔너리 생성
    planet_nums = ["ZRO", "ONE", "TWO", "THR", "FOR", "FIV", "SIX", "SVN", "EGT", "NIN"]
    planet_dict = {word: index for index, word in enumerate(planet_nums)}

    # planet_dict의 인덱스에 따라 정렬된 숫자 리스트 생성
    sorted_nums = sorted(nums, key=lambda word: planet_dict[word])

    # 출력
    print(f"#{test_case}")
    print(' '.join(sorted_nums))

 

 

sol.2 (53,628 kb / 214 ms)

# 행성의 숫자 단어와 순서를 매핑
planet_numbers = ["ZRO", "ONE", "TWO", "THR", "FOR", "FIV", "SIX", "SVN", "EGT", "NIN"]
order_dict = {word: index for index, word in enumerate(planet_numbers)}


# 입력된 문자열 리스트를 정렬하는 함수
def sort_planet_numbers(words):
    # 각 단어를 order_dict의 값(숫자)에 따라 정렬
    sorted_words = sorted(words, key=lambda word: order_dict[word])
    # 결과를 공백으로 연결하여 반환
    return ' '.join(sorted_words)


# 테스트 케이스 실행
T = int(input())
for test_case in range(1, T + 1):
    input()  # 테스트 케이스 번호와 길이를 받는 줄은 생략
    nums = input().split()  # 숫자 문자열 리스트 입력
    sorted_string = sort_planet_numbers(nums)
    print(f"#{test_case}")
    print(sorted_string)

 

 

 

👩‍💻 회고

시간 많이 쏟은 문제다... 풀이 방법도 다양해서 이 문제는 풀기 나름이구나 생각했다. 딕셔너리를 쓰지 않아도 풀 수 있겠지만 이게 제일 좋은 해결법인 것 같다.

 

실행 시간 측면에서.

sol.1 으로 제출 전에 출력문을 print(planet_nums[i], end = '') 라고 했더니 실행 시간이 길었었다. append() 하는게 더 오래 걸릴 것 같았는데 역시 출력이 더 오래걸렸다. 웬만하면 print() 는 최대한 한 번만 쓸 수 있도록 짜야겠다는 걸 깨달았다. 

 

사용하지 않을 변수.

사용하지 않는 건 굳이 이름을 붙일 필요 없이 _(언더바)를 해주기만 하면 된다는 걸 알았다. 안 그래도 변수 이름을 짓는데 나름 고심하기 때문에 보기에는 편하지만 가끔 주객전도가 될 때도 있다.

 

컴프리헨션.

파이썬 특징 답게 최적화된 코드에서 컴프리헨션을 많이 사용된 걸 볼 수 있다. 컴프리헨션을 자주 사용하려고는 하지만 아직 노력이 많이 필요해 보인다. 자연스럽게 생각 않고 칠 수 있도록 연습을 많이 해봐야겠다.

 

🖊️ 추가로 공부해야 할 거.

enumeratelambda 사용법