[프로그래머스] 옹알이 (2)

neoneoneo·2024년 3월 18일
0

kotlin

목록 보기
36/49

문제

옹알이 (2)

요약 | "aya", "ye", "woo", "ma"만 발음할 수 있는 조카가 발음할 수 있는 단어의 개수를 구하라. 조카는 네 가지 발음을 조합할 수 있으나, 연속해서 같은 발음은 할 수 없다..!

나의 풀이

최초 삽질

class Solution {
    fun solution(babbling: Array<String>): Int {
        var answer: Int = 0
        val baby = listOf("aya", "ye", "woo", "ma")        
        for (i in babbling.indices) {
            for (j in 0 .. 3) {
                if (babbling[i].contains(baby[j])) {
                    val temp = babbling[i].replace(baby[j], "")                    
                    if (!temp.contains(baby[j])) {
                        answer++
                    }                   
                    break
                }
            }
        }        
        return answer
    }
}
  • babblin에 가능한 발음이 포함되어 있으면 공백으로 replace하고, 더 이상 남아있는 발음이 없으면 answer에 1씩 더한다.
  • 이 코드를 쓰면서 replace가 "모든" 동일 단어를 대체 단어로 변경한다는 사실을 깨달았고, 하나의 단어만 대체하려면 replaceFirst 같은 함수를 써야한 다는 사실을 알게 되었다.
  • 만약 replaceFirst 쓰려면 4번만 반복할 게 아니라 더 이상 남아있는 단어가 없을 때까지 반복하면서 가능한 발음들을 대조해야 한다는 것을 알게 되고 두 번째 삽질을 시작했다.

두 번째 삽질

class Solution {
    fun solution(babbling: Array<String>): Int {
        var answer: Int = 0
        var pron = listOf("aya", "ye", "woo", "ma")       
        babbling.forEach {
            var check = true
            while(check) {
                for (i in pron.indices) {
                    if (it.contains(pron[i])) {
                        var nextIdx = it.indexOf(pron[i]) + pron[i].length
                        var nextStr = it.substring(nextIdx)
                        if (nextStr.indexOf(pron[i]) == 0) {
                            check = false
                            break
                        } else {
                            if (nextStr == "") {
                                answer++
                                check = false
                                break
                            } else if (pron.count { nextStr.contains(it) } == 0) {
                                check = false
                                break
                            } else {
                                continue
                            }
                        }
                    }  
                }
            }
        } 
        return answer
    }
}
  • repalceFirst를 알게 되었지만 이를 어떻게 써야할 지 막막한 찰나에 substring의 존재가 떠올랐고, 아까 전에 깨달은 반복 처리를 while(check)로 짜보았다.
  • substring으로 이번에 비교한 단어는 잘라내고 다음에 비교할 문자열을 저장해둔 뒤 다시 불러와서 비교 대상으로 활용하는 것을 목표로 코드를 짰으나..별개로 while 문을 잘 못 짜서 그런지 시간 초과가 나서 답이 나오는 지도 확인이 어려웠다.

세 번째 삽질

class Solution {
    fun solution(babbling: Array<String>): Int {
        var answer: Int = 0
        var pron = listOf("aya", "ye", "woo", "ma")        
        for (i in babbling.indices) {
            var nextStr = babbling[i]
            for (j in pron.indices) {                
                if (babbling[i].contains(pron[j] + pron[j])) {
                    break
                }                
                if (babbling[i].contains(pron[j])) {
                    nextStr = nextStr.replace(pron[j], "")                   
                    if (nextStr == "") {
                        answer++
                        break
                    }                    
                }
            }
        }                
        return answer
    }
}        
  • 도저히 while문을 어떻게 컨트롤 해야할지 감이 안와서 이번에는 while을 뺐다.
  • if (babbling[i].contains(pron[j] + pron[j]))로 중복되는 단어를 보다 쉽게 찾아낼 수 있었다.
  • 그러나 여전히 오답을 뱉어내는 코드이다. replace에서 모든 공백으로 대체시키면서 공백 앞 뒤로 있는 문자를 발음할 수 있다고 여기게 되기 때문인데, 예를들어 ymae 면, ma를 제거하고 남은 ye를 발음할 수 있다고 처리하기 때문에 오답이 나는 것이다.
    • 이번에야 말로 replaceFirst를 잘 써볼 수 있는 기회인가..? 싶어서 다시 삽질을 했고, 여전히 오답!(지금 생각해보니 replaceFirst를 쓴다고 딱히 저 상황이 해결되지 않는데 왜 그랬을까..)
    • 그래서 다음에 한 시도는..

네 번째 삽질

class Solution {
    fun solution(babbling: Array<String>): Int {
        var answer: Int = 0
        var pron = listOf("aya", "ye", "woo", "ma")        
        for (i in babbling.indices) {
            var temp = babbling[i]
            for (j in pron.indices) {
                if (babbling[i].contains(pron[j] + pron[j])) break
            }            
            var nextIndex = 0
            for (j in pron.indices) {
                if (temp.contains(pron[j])) { //포함하고 있으면
                    if (temp.indexOf(pron[j]) == 0) { //그게 첫 번째 인덱스에 있으면
                        nextIndex = temp.indexOf(pron[j]) + pron[j].length //그 다음 인덱스를 저장
                        temp = temp.substring(nextIndex)                                              
                    }
                }
            }
        }
        return answer
    }
}
  • ymae 같은 케이스를 처리하기 위해, 아예 인덱스 값을 가져와서 다음 인덱스부터 substring하여 처리할 수 있게 짰지만, 여전히 오답이었다. 왜냐하면.. 아까 두 번째 삽질에서 해결하지 못한 반복을 여기에도 적용을 해야 최종적으로 답이 나올 수 있기 때문이다. pron의 개수 만큼 반복을 하면 4번만 반복하고 말거기 때문에 mayemaye 같은 단어가 들어오면 처리를 정상적으로 할 수 없게 된다.
  • 이 난리를 4시간을 해보니.. 이쯤되면 선조들의 지혜를 빌려보자 싶어 구글링하여 다른 분들의 코드를 참고하여 마지막 삽질을 해보는데...

마지막 삽질

class Solution {
    fun solution(babbling: Array<String>): Int {
        var answer: Int = 0
        var pron = listOf("aya", "ye", "woo", "ma")        
        for (i in babbling.indices) {
            var temp = babbling[i]
            for (j in pron.indices) {
                if (babbling[i].contains(pron[j] + pron[j])) continue
                else temp = temp.replace(pron[j], " ")
            }
            if (temp.replace(" ", "") == "") answer++
        }
        return answer
    }
}
  • 이 코드의 핵심은 .replace(pron[j], " ")인데, replace를 하되 " " 스페이스 하나의 공백으로 대체하여 ymae 같은 상황을 깔끔하게 처리한다.
  • 결국 나의 최초 삽질에 " "의 활용만 추가된 것이다... 이 코드를 짜고 나서 정말 허무했지만, 처음에 문제를 풀기 시작할 때 조금만 더 디테일한 부분까지 생각을 해보고 짰으면 이렇게까지 고생은 안했겠다 싶었다.

기타

  • 위에는 5개의 삽질 기록을 써놨지만, 이 문제 때문에 삽집을 어마어마하게 했다. 평일에는 시간에 제약이 있어 한 문제에 시간을 많이 쏟지 못 했는데, 주말이라 마음 놓고 이것저것 시도해 본답시고 시간을 허투루 쓴 것 같아 마음이 좋지 않았다.
  • 또한 이게 시간을 많이 쓴다는 게 마냥 좋은 것은 아닌게, 시간이 주어져도, 깊게 파고들지 못 하고 결국 챗바퀴 돌듯 내가 아는 선에서만 시도하게 된다는 것이다. 이는 나에게 레퍼런스로 삼을 만한 사례나 지식이 많이 쌓이지 않았다는 것이다.
  • 한 문제를 풀어 나갈 때 시간이 1~2시간 이상 넘어가게 되면 다른 사례를 찾아보고, 내가 모르는 개념 때문인건지 아니면 내가 아는 개념이라도 어떻게 활용할 지를 잘 모르는 것인지 판단해보고 공부하면서 내 코드로 녹여내는 작업을 해야겠다.

[TIL-240316]

0개의 댓글