코딩 테스트 연습/[프로그래머스] Python

[LV.3] 연습문제 > 옹알이 (2)

duswjd_data 2025. 8. 14. 09:32

문제

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

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


문제 설명

  • 조카가 발음할 수 있는 단어: "aya", "ye", "woo", "ma"
  • 이 단어들을 조합해서 만들 수 있는 단어만 발음 가능
  • 단, 같은 발음을 연속해서 말하지 못함
  • babbling이라는 문자열 리스트가 주어졌을 때, 조카가 발음 가능한 단어의 개수를 반환
  • 제한사항
    1 ≤ babbling의 길이 ≤ 100
    1 ≤ babbling[i]의 길이 ≤ 30
    문자열은 알파벳 소문자로만 이루어짐

정답 코드

def solution(babbling):
    speak = ["aya", "ye", "woo", "ma"]
    count = 0

    for word in babbling:
        prev = ""
        i = 0
        success = True

        while i < len(word):
            matched = False
            for s in speak:
                # 현재 위치부터 s 길이만큼 단어가 s와 같고, 이전 음절과 같지 않을 때
                if word[i:i+len(s)] == s and s != prev:
                    prev = s
                    i += len(s)
                    matched = True
                    break
            if not matched:
                success = False
                break

        if success:
            count += 1

    return count

코드 설명

def solution(babbling):
    speak = ["aya", "ye", "woo", "ma"]  # 1. 조카가 발음할 수 있는 음절 목록
    count = 0                           # 조건을 만족하는 단어 개수를 셀 변수

 

  • speak 리스트에 허용된 음절들을 저장
  • count는 조건에 맞는 단어의 개수를 세기 위한 변수
    for word in babbling:  # 2. babbling 배열의 각 단어를 하나씩 검사
        prev = ""          # 이전에 매치된 음절을 저장 (연속 중복 방지용)
        i = 0              # 현재 단어에서 검사할 위치 인덱스
        success = True     # 이 단어가 조건에 맞는지 표시하는 변수

 

 

  • word는 현재 검사 중인 단어
  • prev는 바로 전 음절과 비교해 연속 중복 발음을 막기 위해 저장
  • i는 단어 내 현재 탐색 위치 인덱스
  • success가 True면 단어가 조건에 부합한다는 뜻
        while i < len(word):        # 3. 단어 끝까지 음절 단위로 검사
            matched = False         # 현재 위치에서 음절이 맞는지 여부 판단
            for s in speak:         # 4. 허용 음절 목록에서 가능한 음절을 찾음
                if word[i:i+len(s)] == s and s != prev:  
                # 현재 위치부터 s 길이만큼 자른 문자열이 s와 같고,
                # 이전 음절과 같지 않을 때
                    prev = s        # 현재 음절을 이전 음절로 저장
                    i += len(s)     # 인덱스를 음절 길이만큼 이동
                    matched = True  # 성공적으로 음절 하나를 매치함
                    break           # 더 이상 음절 찾지 않고 다음 위치 검사

 

  • 단어를 음절 단위로 차례로 쪼개 검사
  • speak에 있는 음절 중 현재 위치에 맞는 음절 찾기
  • 이전 음절과 같으면 안 되므로 체크
  • 맞으면 인덱스를 음절 길이만큼 이동하고 matched를 True로 설정
            if not matched:      # 5. 현재 위치에서 가능한 음절을 찾지 못하면
                success = False  # 이 단어는 조건에 맞지 않음
                break            # 더 이상 검사할 필요 없이 중단

 

  • 현재 인덱스 위치에서 speak 음절 중 어느 것도 매치되지 않으면 실패
        if success:     # 6. 단어 끝까지 성공적으로 음절 분해를 마쳤으면
            count += 1  # 조건에 맞는 단어 개수 증가
  • 모든 음절을 문제 조건대로 검사해 이상 없으면 count를 1 증가
    return count  # 7. 모든 단어 검사 후 조건에 맞는 단어 개수 반환
  • 최종적으로 조건에 부합하는 단어 수를 반환

첫 번째 시도 (실패)

def solution(babbling):
    speak = ["aya", "ye", "woo", "ma"]
    
    for i in speak:
        if i in babbling:
            babbling.replace(i, "")
    
    return babbling.count("")

틀린 이유

for i in speak:
    if i in babbling:
        babbling.replace(i, "")
  1. babbling은 리스트인데 str.replace()를 호출
    replace()는 문자열에서만 사용 가능하고, babbling은 문자열이 아니라 문자열들의 리스트
  2. replace()는 원본을 변경하지 않음
    → replace()는 문자열을 수정한 새 문자열을 반환할 뿐
    → babbling.replace(i, "")는 아무 효과 없음

→ 풀이 흐름

각 단어(babbling의 요소)에 대해, 네 가지 발음들을 제거하면서 연속 발음은 제외하고, 모두 제거되고 빈 문자열이면 발음 가능한 단어로 판단하는 방식


두 번째 시도 (실패)

def solution(babbling):
    speak = ["aya", "ye", "woo", "ma"]
    result = []

    for word in babbling:
        temp = word
        for s in speak:
            temp = temp.replace(s, "")
        if temp == "":
            result.append(word)
    
    return len(result)

틀린 이유

  • 연속해서 같은 발음이 나오는 경우는 걸러내지 못함
    예) "yeye" → "ye"를 두 번 연속 쓰는 경우, replace로 모두 지워버려서 통과