숫자 짝꿍 | 프로그래머스

김태영·2024년 5월 30일
0

코딩 테스트

목록 보기
7/33
post-thumbnail

📍 숫자 짝꿍

💡 문제

두 정수 X, Y의 임의의 자리에서 공통으로 나타나는 정수 k(0 ≤ k ≤ 9)들을 이용하여 만들 수 있는 가장 큰 정수를 두 수의 짝꿍이라 합니다(단, 공통으로 나타나는 정수 중 서로 짝지을 수 있는 숫자만 사용합니다). X, Y의 짝꿍이 존재하지 않으면, 짝꿍은 -1입니다. X, Y의 짝꿍이 0으로만 구성되어 있다면, 짝꿍은 0입니다.

두 정수 X, Y가 주어졌을 때, X, Y의 짝꿍을 return하는 solution 함수를 완성해주세요.

⚠️ 제한사항

  • 3 ≤ X, Y의 길이(자릿수) ≤ 3,000,000입니다.
  • X, Y는 0으로 시작하지 않습니다.
  • X, Y의 짝꿍은 상당히 큰 정수일 수 있으므로, 문자열로 반환합니다.

✅ 풀이

👆 첫 번째 풀이 (실패)

  • X와 Y의 공통된 숫자와 그 개수를 구해야 한다.
    • '0'부터 '9'까지 돌며, 각각의 문자가 X와 Y에 포함된 개수를 구한다.
    • same[0]에는 '0'이 포함된 개수, same[1]에는 '1'이 포함된 개수, ...
    • 공통으로 있는 개수를 구하려면 더 작은 값을 사용하면 된다.
  • 9부터 0까지 돌면서 공통된 개수만큼 해당 인덱스를 반복해 문자열을 만든다.
    • 0의 경우 여러 개가 공통되었을 때, "000"이 되므로 처리가 필요하다.
    • 문자열의 길이가 0이면, -1을 반환해야 한다.

여기서 나는 0이 겹친 개수가 1 이상이면 1로 처리를 했고, 이 점 때문에 풀이에 실패했다. 예를 들어, 답이 "9000"이면 나의 풀이는 "90"을 반환하게 된다.

class Solution {
    fun solution(X: String, Y: String): String {
        var same = ('0'..'9').map { n ->
            arrayOf(X.count { it == n }, Y.count { it == n }).minOrNull()!! }
        var str = (9.downTo(0)).fold("") { t, i ->
            t + "$i".repeat(if (i == 0 && same[0] > 0) 1 else same[i])
        }
        
        return if (str == "") "-1" else str
    }
}

✌️ 두 번째 풀이 (성공)

첫 번째 풀이 실패 후, 0을 처리하는 방식을 바꿔보았다. 전체 요소가 해당 조건에 일치하는지 확인해주는 all을 사용해 결과값이 "000" 인 경우만 "0"으로 처리하도록 바꿔주었다.

class Solution {
    fun solution(X: String, Y: String): String {
        var same = ('0'..'9').map { n ->
            arrayOf(X.count { it == n }, Y.count { it == n }).minOrNull()!! }
        var str = (9.downTo(0)).fold("") { t, i ->
            t + "$i".repeat(same[i])
        }

        return if (str == "") "-1" else if (str.all{ it == '0' }) "0" else str
    }
}

🔥 다른 사람의 풀이

0을 처리할 때 문자열을 리스트로 바꿔 중복을 제거하는 방식으로 사용한 풀이가 있어서 신기했다. 게다가 minOrNull 대신 min을 사용해서 nullable 값 없이 최소값을 구한 것도 좋아보였다..

import kotlin.math.min

class Solution {
    fun solution(X: String, Y: String): String {
        var answer: String = ""

        for (ch in (9 downTo 0).toList().map { it.toString() }) {
            answer += ch.toString().repeat(min(X.count { it.toString() == ch }, Y.count { it.toString() == ch }))
        }
        if (answer.isEmpty()) answer = "-1"
        if (answer.toList().distinct() == listOf('0')) answer = "0"

        return answer
    }
}

💭 후기

첫 번째 풀이를 제출했을 때, 테스트케이스는 전부 성공하는데 채점할 때 계속 일부 테스트만 실패를 해서 도대체 어디가 틀린걸까 엄청 고민했었다. 반례를 잘 찾는 능력도 중요한 것 같다. 나는 다행히도 문제 질문하기에 비슷한 경우가 있어서 쉽게 알아차렸는데, 만약 없었더라면... 상상도 하기 싫다... 스스로 반례를 찾아보는 연습의 필요성을 느꼈다.

profile
화이팅

0개의 댓글

관련 채용 정보