📍 숫자 짝꿍
두 정수 X
, Y
의 임의의 자리에서 공통으로 나타나는 정수 k(0 ≤ k ≤ 9)들을 이용하여 만들 수 있는 가장 큰 정수를 두 수의 짝꿍이라 합니다(단, 공통으로 나타나는 정수 중 서로 짝지을 수 있는 숫자만 사용합니다). X
, Y
의 짝꿍이 존재하지 않으면, 짝꿍은 -1입니다. X
, Y
의 짝꿍이 0으로만 구성되어 있다면, 짝꿍은 0입니다.
두 정수 X
, Y
가 주어졌을 때, X
, Y
의 짝꿍을 return하는 solution 함수를 완성해주세요.
X
, Y
의 길이(자릿수) ≤ 3,000,000입니다.X
, Y
는 0으로 시작하지 않습니다.X
, Y
의 짝꿍은 상당히 큰 정수일 수 있으므로, 문자열로 반환합니다.'0'
부터 '9'
까지 돌며, 각각의 문자가 X와 Y에 포함된 개수를 구한다.same[0]
에는 '0'
이 포함된 개수, same[1]
에는 '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
}
}
첫 번째 풀이를 제출했을 때, 테스트케이스는 전부 성공하는데 채점할 때 계속 일부 테스트만 실패를 해서 도대체 어디가 틀린걸까 엄청 고민했었다. 반례를 잘 찾는 능력도 중요한 것 같다. 나는 다행히도 문제 질문하기에 비슷한 경우가 있어서 쉽게 알아차렸는데, 만약 없었더라면... 상상도 하기 싫다... 스스로 반례를 찾아보는 연습의 필요성을 느꼈다.