프로그래머스
끝말잇기가 끝나는 경우는 다음과 같다.
리턴해야하는 값은 [차례, 라운드]이다.
function solution(n, words) {
let round = 1;
for(let i=1; i<words.length; i++) {
const prev = words[i-1];
const now = words[i];
if((i+1)%n===1) round++;
if(prev[prev.length-1] !== now[0] || words.indexOf(now) !== i) {
const turn = (i+1)%n || n;
return [turn, round];
}
}
return [0,0]
}
나는 turn과 round라는 변수를 따로 만들어서 사용했는데, 이 풀이에서는 answer라는 변수값을 사용해서 두가지 정보를 만들어낸 점이 너무 신기했다. 그런데, answer에 idx값이 할당되어서 끝말잇기를 끝내는 지점을 찾아냈음에도 계속 reduce가 실행되는 것이 조금 아쉬웠다.
answer는 끝말잇기가 끝난 인덱스이다. 이를 활용해서 몇번째 라운드인지, 몇번째 사람이 틀렸는지를 알 수 있다. 끝말잇기가 틀리지 않고 모두 끝났다면 answer=0이다. [0,0]을 리턴한다. function solution(n, words) {
let answer = 0; //끝말잇기가 끝난 인덱스
words.reduce((prev, now, idx) => {
answer = answer || ((words.slice(0, idx).indexOf(now) !== -1 || prev !== now[0]) ? idx : answer);
return now[now.length-1];
}, "");
return answer ? [answer%n+1, Math.ceil((answer+1)/n)] : [0,0];
}
위에서 작성한 풀이에서 reduce를 중단하는 코드를 추가해 작성해보았다. reduce에서는 break를 쓸 수 없고, return 시키면 첫번째 인자에 값이 undefined가 담기므로 사용할 수 없다. 따라서, (옵션)인자로 입력받는 네번째 array를 mutate시키는 점을 활용해야한다.
이때 splice를 사용해 현재 인덱스부터 모든 요소를 제거시켜 reduce를 종료시킬 수 있다.
function solution(n, words) {
let answer = 0;
words.reduce((prev, now, idx, arr) => {
answer = answer || ((words.slice(0, idx).indexOf(now) !== -1 || prev !== now[0]) ? idx : answer);
if(answer) arr.splice(idx); //추가한 부분
return now[now.length-1];
}, "")
return answer ? [answer%n+1, Math.ceil((answer+1)/n)] : [0,0];
}