영어 끝말잇기 https://school.programmers.co.kr/learn/courses/30/lessons/12981
- 다시 나오는 단어 찾기
- 탈락한 사람은 몇 번째인지
- 몇 번째 사이클인지
function solution1(n, words) {
var answer = [];
let failNumber, failCount
for (i = 0; i < words.length; i++) {
if (answer.indexOf(words[i]) !== -1) break
if (i > 0 && words[i - 1][words[i - 1].length - 1] !== words[i][0]) break
answer.push(words[i])
}
failNumber = answer.length % n + 1
failCount = Math.floor(answer.length / n + 1)
return answer.length === words.length ? [0, 0] : [failNumber, failCount];
}
이것은 지금 글로 정리하면서 다시 처음에 했던 것을 돌아보며 수정하니까 이렇게 정답이 되었는데
failCount = Math.floor(answer.length / n + 1)를 나누고 1을 더해야 하는데 1을 더하고 나눈다던지,
[0,0]의 경우를 생각 못한 것이나
전에 단어의 끝글자와 다음 단어의 첫 글자가 다른 경우를 고려하지 못한 것 등의 문제가 있었다.
그래서 중간에 방법을 조금 바꿨다.
function solution2(n, words) {
var answer = new Map()
let arr = []
let count
for (i = 0; i < words.length; i++) {
answer.set((i + 1) % n, (answer.get((i + 1) % n) || 0) + 1)
if (arr.indexOf(words[i]) !== -1) {
return count = [(i + 1) % n === 0 ? n : (i + 1) % n, answer.get((i + 1) % n)]
}
if (i > 0 && words[i - 1][words[i - 1].length - 1] !== words[i][0]) {
return count = [(i + 1) % n === 0 ? n : (i + 1) % n, answer.get((i + 1) % n)]
}
arr.push(words[i])
}
return [0, 0];
}
이것도 상당히 지저분한데 Map 자료 구조를 이용해서 탈락한 사람의 번호를 키로 값을 사이클 수로 구한다. 이때 키가 0인 경우는 마지막 사람이기에 n으로 처리했다.
어떻게 풀긴 했지만 너무 지저분하고 이것을 정리하려던 것이 아니라 다른 사람의 모범답안을 이해하고 정리하려 글을 쓴다.
function solution3(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.floor(answer/n)+1] : [0,0];
}
깔끔하다. 왜 이렇게 코드를 구성했는지 내가 다시봤을 때 헷갈릴 부분을 정리해 보자.
먼저 answer = answer ||... 이것은 answer가 0이 아닌 경우에 뒤에 연산을 한다.
그다음으로 (words.slice(0, idx). indexOf(now) 이것을 보고 처음엔 왜 slice(0, idx)를 하지 했는데 나처럼 새로운 배열에 push 할 필요 없이 words에서 몇 번째 단어까지 끝말잇기 했는지 가져와서 지금 값이 나온 적이 있나 확인하는 것이다.
마지막으로 return now [now.length-1]삼항연산자를 이용해서 탈락자가 생기는 경우가 아니면 prev(누적값)을 항상 마지막 글자로 반환한다.
이렇게 내가 했던 불필요한 과정들이 간략하게 처리되었다.
reduce를 사용하는 방법에 있어서 나는 accumulator + currentValue를 이용해 모든 값을 더한 경우만 생각했는데 반복할 때마다 끝글자를 반환시켜서 사용한 것이 중요한 부분이며, 글을 정리하다 보니까 처음에 시도했던 방법에 잘못된 부분도 다시 고칠 수 있었다.
'오늘 뭐했냐 > 기억하면 좋을 문제들' 카테고리의 다른 글
구명보트 (0) | 2023.10.21 |
---|---|
피보나치 수 (0) | 2023.10.17 |
올바른 괄호 (0) | 2023.10.17 |
sort() 활용 (0) | 2023.06.28 |
스택을 사용하는 문제 (0) | 2023.06.25 |