
정해진 규칙과 순서에 맞춰 낱말을 골라 말해야 하는 낱말게임이 있습니다.
예를 들어 주어진 문자열 패턴 p 가 가다가라 라면, 가, 다, 라에 해당하는 단어 개나리, 버스, 카메라 를 정한 후 개나리, 버스, 개나리, 카메라 라고 말합니다.
각 패턴에는 아무 낱말이나 사용할 수 있지만 한 턴이 돌아갈 때까지 한 패턴에는 첫 번째로 정한 한 낱말만 사용합니다. 다음 턴이 돌아올 때, 다른 패턴에 사용한 낱말을 다시 사용할 수는 없습니다.
패턴 p와 정답 a가 주어졌을 때, 게임의 규칙을 지켰는지의 여부를 출력하세요.
제약사항
p.length = 4
0 < s.length <= 1000
입출력 예
| p | s | return |
|---|---|---|
| "가다가라" | "개나리 버스 개나리 카메라" | true |
| "가나다라" | "헤드폰 시계 패드 달력" | true |
| "가갸가갸" | "바나나 드래곤 바나나 드레곤" | false |
| "가가나나" | "장미꽃 장미꽃 장미꽃 장미꽃" | false |
이번 문제에서는 새로운 배열인 map을 사용하려고 합니다.
주요로 검사할 내용은 아래와 같습니다.
map의 p와 s의 각 요소를 순서대로 저장하면서 조건을 따집니다.
만약 map이 비었다면 첫 번째 요소이므로 우선 저장해야 합니다.
저장을 하다가 현재 패턴이 앞서 나왔던 패턴이라면, 함께 나오는 낱말이 앞서 나왔던 패턴의 낱말과 같은지 검사해야 합니다.
그런데 이번 문제에서는 예외 케이스가 여러 개 있습니다.
p의 길이는 4로 한정했지만, s의 길이는 0부터 1000까지임을 주목해야 합니다. 만약 p와 s의 길이가 다르다면 위 게임의 규칙에 부합하지 않으므로 더 진행하지 않고 false를 반환해야 합니다.
네 번째 테스트 케이스처럼, 같은 패턴에 같은 단어를 매치했더라도 앞서 다른 패턴이 사용한 단어를 재사용한 경우 규칙에 위반됩니다. 따라서 만약 같은 패턴이 아님에도 현재 값이 앞선 value들 중 하나와 같다면, false를 반환해야 합니다.
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는 공백이 없는 문자열로 문자열 자체만으로도 하나씩 검사가 가능하기 때문에 따로 이 과정을 거치지 않아도 됩니다.