[프로그래머스] 영어 끝말잇기
월, 수, 금에 프로그래머스 1문제 풀려고 했는데 슬슬 너무 어려워요😥
실력이 부족해서 그런 건지 어제 하루 종일 풀어도 답이 안 나와서... 돌고 돌아 쉬운 문제 찾아서 풀어서 올려봅니다.
https://programmers.co.kr/learn/courses/30/lessons/12981
코딩테스트 연습 - 영어 끝말잇기
3 ["tank", "kick", "know", "wheel", "land", "dream", "mother", "robot", "tank"] [3,3] 5 ["hello", "observe", "effect", "take", "either", "recognize", "encourage", "ensure", "establish", "hang", "gather", "refer", "reference", "estimate", "executive"] [0,0]
programmers.co.kr
접근방법
이문제는 평소에 끝말잇기 게임하는 거와 똑같고, 아래 두 개의 조건에만 맞게 풀면 됩니다.
- 정답은 [ 번호, 차례 ] 형태로 return 해주세요.
- 이전에 등장했던 단어는 사용할 수 없습니다.
제가 생각한 방식은 words배열 단어 중에서
끝말잇기에 맞는 단어면 배열에 담아주고
끝말잇기에 맞는 단어가 아니던가 이전에 등장했던 단어이기 전까지의 단어만 배열에 담아주고
그 배열의 개수가 몇 개인지에 따라 번호, 차례를 담아 주었습니다.
테스트 1
n=3
words = ["tank", "kick", "know", "wheel", "land", "dream", "mother", "robot", "tank"]
words[9] "tank"가 words[0] "tank"랑 겹칩니다.
그러므로 connect에 words[0]~words[8]을 담아줍니다.
connect = ["tank", "kick", "know", "wheel", "land", "dream", "mother", "robot"]
words.length === connect.length가 아님으로 탈락자가 있습니다.
번호 : connect.length % n +1 -> 3
차례 : Math.floor(connect.length / n)+1 -> 3
테스트 2
n=5
words = ["hello", "observe", "effect", "take", "either", "recognize", "encourage", "ensure", "establish", "hang", "gather", "refer", "reference", "estimate", "executive"]
words의 모든 단어가 끝말잇기에 맞는 단어임으로 words의 모든 담어를 connect에 담아줍니다.
connect= ["hello", "observe", "effect", "take", "either", "recognize", "encourage", "ensure", "establish", "hang", "gather", "refer", "reference", "estimate", "executive"]
words.length === connect.length임으로 탈락자 없습니다.
테스트 3
n=2
words = ["hello", "one", "even", "never", "now", "world", "draw"]
words[4] "now"가 words[3] "never"이랑 끝말잇기가 맞지 않습니다.
그러므로 connect에 words[0]~words[3]을 담아줍니다.
connect= ["hello", "one", "even", "never"]
words.length === connect.length가 아님으로 탈락자가 있습니다.
번호 : connect.length % n +1 -> 1
차례 : Math.floor(connect.length / n)+1 -> 3
해결방안
function solution(n, words) {
let connect = [];
connect.push(words[0]);
for(let i=1; i<words.length; i++){
let prev = words[i-1][ words[i-1].length-1]
let now = words[i][0];
let nowTrue = connect.indexOf(words[i]);
if(prev === now && nowTrue === -1) connect.push(words[i])
else break;
}
// if(connect.length === words.length) return [0,0];
// else{
// let a = connect.length % n +1;
// let b = Math.floor(connect.length / n)+1;
// return [a, b]
// }
return connect.length === words.length ? [0, 0] : [connect.length % n +1, Math.floor(connect.length / n)+1]
}
해결방안 순서
- for문으로 끝말잇기에 맞지 않는 단어가 나오기 전까지의 단어를 connect에 담아주기
- 탈락자가 있을 경우 [번호, 차례]를 없을 경우 [0, 0]을 return 해주기
1단계. for문으로 끝말잇기에 맞지 않는 단어가 나오기 전까지의 단어를 connect에 담아주기
let connect = [];
connect.push(words[0]);
for(let i=1; i<words.length; i++){
let prev = words[i-1][ words[i-1].length-1]
let now = words[i][0];
let nowTrue = connect.indexOf(words[i]);
if(prev === now && nowTrue === -1) connect.push(words[i])
else break;
}
- connect : 끝말잇기에 맞지 않는 단어가 나오기 전까지의 단어를 담을 배열
끝말잇기를 시작했을 때 끝말잇기에 맞는 단어인지 아닌지 비교할 필요가 없음으로
미리 connect에 words[0]을 담아주었습니다.
for문은 words배열의 길이만큼 반복문으로 돌려주었습니다.
- prev : 이전 단어(word[i-1])의 마지막 문자
- now : 현재 단어(word[i])의 첫 번째 문자
- nowTrue : connect에 현재 단어와 같은 단어가 있는지 -> 이전에 등장했던 단어인지 확인
prev === now 이고 nowTrue === -1이면 connect배열에 words[i]를 담아주었습니다.
2단계. 탈락자가 있을 경우 [번호, 차례]를 없을 경우 [0, 0]을 return해주기
// 버전1
if(connect.length === words.length) return [0,0];
else{
let a = connect.length % n +1;
let b = Math.floor(connect.length / n)+1;
return [a, b]
}
// 버전2
return connect.length === words.length ? [0, 0] : [connect.length % n +1, Math.floor(connect.length / n)+1]
버전 1,2는 같은 의미의 코드이고 쓰는 방식만 다르게 쓴 코드입니다.
이해하기 쉽게 버전 1로 설명하겠습니다.
connect.length === words.length이면 탈락자가 없다는 말이므로 reutrn [0,0]을 해주었고
connect.length === words.length가 아닐 경우 탈락자가 있다는 말이므로 번호와 차례를 구해주었습니다.
번호는 n번씩 돌아가면서 하기 때문에 connect.length % n을 해주었습니다.
여기서 +1을 해준 이유는 connect에서는 끝말잇기에 맞는 단어만 담아주었기 때문에 connect.length % n만 해주면 탈락자가 아니게 됨으로 +1을 해주었습니다.
차례도 번호와 비슷하게 connect.length /n을 해주었습니다. connect.length /n만 하면 소수점이 나올 수 있어서 Math.floor()을 해주었고 번호화 똑같은 이유로 +1을 해주었습니다.
여기까지 프로그래머스 영어 끝말잇기 해결방안에 대해 설명해보았습니다.