Skip to content

[mingxoxo] programmers_가장 큰 수_Python - #29

Open
mingxoxo wants to merge 1 commit into
sejongbinary:mainfrom
mingxoxo:2025-01-w5-2
Open

[mingxoxo] programmers_가장 큰 수_Python#29
mingxoxo wants to merge 1 commit into
sejongbinary:mainfrom
mingxoxo:2025-01-w5-2

Conversation

@mingxoxo

Copy link
Copy Markdown
Member

🔗 문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/42746

  • 0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내기

💡 풀이 아이디어

처음에는 단순히 사전 순으로 큰 순서대로 정렬하면 되지 않을까? 라고 생각했는데, 자릿수가 다른 경우의 비교가 제대로 되지 않았습니다.

예시에서 나오는 34, 3, 30 에서의 비교가 34와 3을 비교하는 경우에는 334, 343 중 343이 크기 때문에 34가 앞서야 하고, 3과 30에서는 330, 303 중 330이 크기 때문에 3이 더 앞서야 하지만 단순히 사전 순으로 정렬할 경우 30이 3보다 더 크게 처리됩니다.

따라서 해당 경우에 대해서 모두 고려해야 하기 때문에 새로운 정렬 기준을 고민했습니다..

아까 예시에서 언급했던 문자열 합치기를 사용하여 정렬하는 것이 가장 정확한 비교라고 생각되어 활용했습니다.
살짝 그리디가 섞인 풀이인 것 같습니다.

이를 적용하고자 functools 모듈의 cmp_to_key 함수를 사용하였습니다.
(뭔가 이렇게 두 수를 비교해서 새로운 커스텀 비교 함수를 작성할 수 있었던 것 같은데.. 라는 생각으로 GPT에게 물어보았더니 친절히 가르쳐줬습니다 😆)

커스텀 비교 함수에서 1, 0, -1을 반환하도록 하여 a, b를 비교한다고 했을 때 a가 클 경우 1, a와 b가 같을 경우 0, b가 클 경우 -1을 반환하도록 하여 정렬 기준을 처리하는 것과 sorted()를 사용하였을 때와 동일한 것 같았습니다.
오름차순 정렬일 때 a가 더 클 경우 -1로 반환되기 때문에 반대로 내림차순으로 정렬하기 위해서 swap이 필요할 경우 -1로 반환해주었습니다.

하지만 아래와 같이 제출했을 때 딱 하나의 테스트 케이스가 계속 실패했습니다..

from functools import cmp_to_key

def custom_compare(a:str, b:str):
    return -1 if a + b > b + a else 1
    

def solution(numbers):
    return ''.join(sorted(map(str, numbers), key=cmp_to_key(custom_compare)))

계속 고민해보다 도저히 모르겠어서 GPT에게 힌트를 요청했는데... 특수한 케이스인 0으로만 숫자가 이루어진 경우가 존재했습니다.
[0, 0, 0, 0] -> "0" 으로 정답이 나와야 하지만 제가 제출한 풀이에서는 "0000"으로 제출하게 되어 오답이었습니다..!

따라서 이에 대한 처리를 위해 마지막으로 구해진 문자열을 int로 변환한 후 다시 str로 변환해서 반환했습니다.
문제를 풀 때 이렇게 생각하지 못한 테스트 케이스를 고민하고 찾는 능력이 중요한 것 같습니다.. 😂

📝 새로 학습한 내용

  • functools.cmp_to_key(func)

    • 구식 비교 함수를 키 함수로 변환
    • 예시: sorted(iterable, key=cmp_to_key(locale.strcoll)) # locale-aware sort order
  • 다른 사람의 풀이 중 최대로 만들 수 있는 문자열 길이로 만들어서 비교하는 방법이 인상 깊었습니다. 첫 번째 자릿수가 같은 수인 경우에만 다음 자릿수를 비교하기 때문에 이러한 방법이 가능한 것 같습니다. 아래 풀이에서 숫자가 100000 이하이기 때문에 자릿수 3이 아닌 5을 곱해야 정확할 것 같은데 댓글을 보니 아마 옛날에 numbers의 길이가 1000 이하였던 것 같습니다.

    def solution(numbers):
        numbers = list(map(str, numbers))
        numbers.sort(key=lambda x: x*3, reverse=True)
        return str(int(''.join(numbers)))

📚 참고 자료

functools — Higher-order functions and operations on callable objects
Sorting Techniques

@mingxoxo mingxoxo added 🪄Programmers 프로그래머스 문제 풀이 🫧Python 풀이 언어 (Python) labels Jan 31, 2025
@mingxoxo mingxoxo self-assigned this Jan 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🪄Programmers 프로그래머스 문제 풀이 🫧Python 풀이 언어 (Python)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant