function solution(n, words) {
const existSameWord = (words) => {
const set = new Set();
for(let i = 0; i < words.length; i++) {
if(set.has(words[i])) return words[i];
!set.has(words[i]) && set.add(words[i])
}
return false
}
const verifyWordChain = (words) => {
for(let i = 1; i < words.length; i++) {
const prevWord = words[i - 1];
const currWord = words[i];
if(currWord.length === 1) return i
if(prevWord[prevWord.length - 1] !== currWord[0]) return i
}
return true
}
const getTurn = (idx) => { // 사람들 중 몇번째 순서인지
return ((idx + 1) % n === 0 ? n : (idx + 1) % n)
}
const getNthTurn = (idx) => { // 내 차례가 몇번 돌아왔는지
return Math.ceil((idx + 1) / n)
}
// 탈락자 없는 조건 먼저 걸어주기
if(existSameWord(words) === false && verifyWordChain(words) === true) return [0, 0]
if(existSameWord(words) !== false) { // 같은 단어가 있다는 뜻!
const repeatedWord = existSameWord(words);
const idxOfRepeated = words.lastIndexOf(repeatedWord);
return [getTurn(idxOfRepeated), getNthTurn(idxOfRepeated)]
}
if(verifyWordChain(words) !== true) { // 끝말잇기를 틀리게 한 사람 존재
const idxOfWrongWord = verifyWordChain(words);
return [getTurn(idxOfWrongWord), getNthTurn(idxOfWrongWord)]
}
}
문제에 정답 리턴값이 하나인 것으로 보아 어떤 경우든 탈락자가 2명 이상 나오지 않을 것이라는 것을 염두에 두고 탈락하는 경우를 나누어보았다.
코드를 작성하기 전에 함수를 최대한 쪼개어보기로 마음먹었다. 코드가 복잡해보이지만 함수 4개와 실행부 조건 3개로 이루어져 있다.
existSameWord
has()
메서드를 이용하여 단어가 이미 앞에서 나온 단어인지 확인하고, 있으면 그 단어
를 바로 리턴, 없으면 Set 객체에 단어를 추가. for문이 모두 끝나면 중복 단어가 없다는 뜻이므로 false
를 리턴처음에는 const set = new Set(words)
라고 작성 후 set
의 길이와 words
의 길이만 비교해서 중복 값이 있는지 없는지 체크했는데, 답을 구하려면 어떤 단어가 중복됐는지를 알아야 words
배열에서의 인덱스를 알아낼 수 있으니 방법을 위와 같이 바꾸었다.
verifyWordChain
인덱스
를 리턴하고, 정상적으로 for문이 끝난다면 끝말이 제대로 이어졌다는 뜻이므로 true
를 리턴어쨌거나 탈락하는 사람이 2명 이상 나오지 않는다는 게 포인트!!
getTurn
n명의 사람들 중 내가 몇번째 순서인지 구하는 함수. 위에 두 함수에서 받은 리턴값을 활용해 구한다.
getNthTurn
내 차례가 몇 번 돌아왔는지 구하는 함수. 역시 위에 두 함수에서 받은 리턴값을 활용해 구한다.
existSameWord
함수를 이용해 중복되는 단어를 알아낸 뒤, words
배열에 제일 마지막에 나오는 해당 단어가 바로 탈락 지점임을 이용해 정답을 구한다.verifyWordChain
함수를 이용해 틀린 지점의 인덱스를 구하고 그것을 이용해 정답을 구한다.함수에서 리턴값이 일관되게 true/false처럼 나와야할 것 같은데 저렇게 조건에 따라 어떨 때는 인덱스 반환하고 어떨 때는 true 를 반환하는 게 맞는 건지 모르겠다. 그리고 함수 이름이랑 리턴값이 잘 매치가 안 되는 부분도 있는 것 같다. 이름 짓기 넘 어려워~~~ 함수를 최대한 잘게 쪼개보는 게 목표였는데 다른 사람들 풀이 보니까 코드가 훨씬 짧아서 또 내가 푼 방법이 맞나 의문이 들기도 했다.
아! 어제 코어자바스크립트 책 공부한 내용에서 함수 선언식으로 작성 시 호이스팅 때문에 오류를 쉽게 찾을 수 없을 수도 있다는 점 때문에 앞으로는 화살표 함수를 사용한 표현식으로 다시 쓰려고 한다.
끝!