프로그래머스 | 낱말 게임

chaen·2024년 3월 7일
post-thumbnail

📌 문제

정해진 규칙과 순서에 맞춰 낱말을 골라 말해야 하는 낱말게임이 있습니다.
예를 들어 주어진 문자열 패턴 p가다가라 라면, , , 에 해당하는 단어 개나리, 버스, 카메라 를 정한 후 개나리, 버스, 개나리, 카메라 라고 말합니다.
각 패턴에는 아무 낱말이나 사용할 수 있지만 한 턴이 돌아갈 때까지 한 패턴에는 첫 번째로 정한 한 낱말만 사용합니다. 다음 턴이 돌아올 때, 다른 패턴에 사용한 낱말을 다시 사용할 수는 없습니다.
패턴 p와 정답 a가 주어졌을 때, 게임의 규칙을 지켰는지의 여부를 출력하세요.

제약사항
p.length = 4
0 < s.length <= 1000

입출력 예

psreturn
"가다가라""개나리 버스 개나리 카메라"true
"가나다라""헤드폰 시계 패드 달력"true
"가갸가갸""바나나 드래곤 바나나 드레곤"false
"가가나나""장미꽃 장미꽃 장미꽃 장미꽃"false

✨ 해결 방법

이번 문제에서는 새로운 배열인 map을 사용하려고 합니다.
주요로 검사할 내용은 아래와 같습니다.
mapps의 각 요소를 순서대로 저장하면서 조건을 따집니다.
만약 map이 비었다면 첫 번째 요소이므로 우선 저장해야 합니다.
저장을 하다가 현재 패턴이 앞서 나왔던 패턴이라면, 함께 나오는 낱말이 앞서 나왔던 패턴의 낱말과 같은지 검사해야 합니다.

그런데 이번 문제에서는 예외 케이스가 여러 개 있습니다.

  1. p의 길이는 4로 한정했지만, s의 길이는 0부터 1000까지임을 주목해야 합니다. 만약 ps의 길이가 다르다면 위 게임의 규칙에 부합하지 않으므로 더 진행하지 않고 false를 반환해야 합니다.

  2. 네 번째 테스트 케이스처럼, 같은 패턴에 같은 단어를 매치했더라도 앞서 다른 패턴이 사용한 단어를 재사용한 경우 규칙에 위반됩니다. 따라서 만약 같은 패턴이 아님에도 현재 값이 앞선 value들 중 하나와 같다면, false를 반환해야 합니다.

💻 solution

function solution(p, s) {
    const string = s.split(" ");

    if (p.length !== string.length) {
        return false;
    }

    const map = new Map();

    for (let i = 0; i < p.length; i++) {
        const pattern = p[i];
        const answer = string[i];

        if (map.has(pattern)) {
            if (map.get(pattern) !== answer) {
                return false;
            }
        } else {
            if (Array.from(map.values()).includes(answer)) {
                return false;
            }
            map.set(pattern, answer);
        }
    }
    return true;
}

s는 공백이 있는 문자열로 구성되어 있으므로 각 공백을 기준으로 문자열을 나눠 배열로 만드는 과정이 필요합니다. p는 공백이 없는 문자열로 문자열 자체만으로도 하나씩 검사가 가능하기 때문에 따로 이 과정을 거치지 않아도 됩니다.

0개의 댓글