[코딩테스트]프로그래머스 - 영어 끝말잇기

Adela·2020년 6월 3일
0

프로그래머스

목록 보기
26/30
post-thumbnail

영어 끝말잇기

문제 설명

1부터 n까지 번호가 붙어있는 n명의 사람이 영어 끝말잇기를 하고 있습니다. 영어 끝말잇기는 다음과 같은 규칙으로 진행됩니다.

  1. 1번부터 번호 순서대로 한 사람씩 차례대로 단어를 말합니다.
  2. 마지막 사람이 단어를 말한 다음에는 다시 1번부터 시작합니다.
  3. 앞사람이 말한 단어의 마지막 문자로 시작하는 단어를 말해야 합니다.
  4. 이전에 등장했던 단어는 사용할 수 없습니다.
  5. 한 글자인 단어는 인정되지 않습니다.

다음은 3명이 끝말잇기를 하는 상황을 나타냅니다.

tank → kick → know → wheel → land → dream → mother → robot → tank

위 끝말잇기는 다음과 같이 진행됩니다.

  • 1번 사람이 자신의 첫 번째 차례에 tank를 말합니다.
  • 2번 사람이 자신의 첫 번째 차례에 kick을 말합니다.
  • 3번 사람이 자신의 첫 번째 차례에 know를 말합니다.
  • 1번 사람이 자신의 두 번째 차례에 wheel을 말합니다.
  • (계속 진행)

끝말잇기를 계속 진행해 나가다 보면, 3번 사람이 자신의 세 번째 차례에 말한 tank 라는 단어는 이전에 등장했던 단어이므로 탈락하게 됩니다.

사람의 수 n과 사람들이 순서대로 말한 단어 words 가 매개변수로 주어질 때, 가장 먼저 탈락하는 사람의 번호와 그 사람이 자신의 몇 번째 차례에 탈락하는지를 구해서 return 하도록 solution 함수를 완성해주세요.

제한 사항

  • 끝말잇기에 참여하는 사람의 수 n은 2 이상 10 이하의 자연수입니다.
  • words는 끝말잇기에 사용한 단어들이 순서대로 들어있는 배열이며, 길이는 n 이상 100 이하입니다.
  • 단어의 길이는 2 이상 50 이하입니다.
  • 모든 단어는 알파벳 소문자로만 이루어져 있습니다.
  • 끝말잇기에 사용되는 단어의 뜻(의미)은 신경 쓰지 않으셔도 됩니다.
  • 정답은 [ 번호, 차례 ] 형태로 return 해주세요.
  • 만약 주어진 단어들로 탈락자가 생기지 않는다면, [0, 0]을 return 해주세요.

입출력 예

n words result
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]
2 ["hello", "one", "even", "never", "now", "world", "draw"] [1,3]

입출력 예 설명

입출력 예 #1

3명의 사람이 끝말잇기에 참여하고 있습니다.

1번 사람 : tank, wheel, mother
2번 사람 : kick, land, robot
3번 사람 : know, dream, tank

와 같은 순서로 말을 하게 되며, 3번 사람이 자신의 세 번째 차례에 말한 tank라는 단어가 1번 사람이 자신의 첫 번째 차례에 말한 tank와 같으므로 3번 사람이 자신의 세 번째 차례로 말을 할 때 처음 탈락자가 나오게 됩니다.

입출력 예 #2

5명의 사람이 끝말잇기에 참여하고 있습니다.

1번 사람 : hello, recognize, gather
2번 사람 : observe, encourage, refer
3번 사람 : effect, ensure, reference
4번 사람 : take, establish, estimate
5번 사람 : either, hang, executive

와 같은 순서로 말을 하게 되며, 이 경우는 주어진 단어로만으로는 탈락자가 발생하지 않습니다. 따라서 [0, 0]을 return하면 됩니다.

입출력 예 #3

2명의 사람이 끝말잇기에 참여하고 있습니다.

1번 사람 : hello, even, now, draw
2번 사람 : one, never, world

와 같은 순서로 말을 하게 되며, 1번 사람이 자신의 세 번째 차례에 'r'로 시작하는 단어 대신, n으로 시작하는 now를 말했기 때문에 이때 처음 탈락자가 나오게 됩니다.

해결한 나의 코드

function solution(n, words){
  var answer = []
  var temp = []
  var check = -1
  for(var i=0; i<words.length; i++){
    if(temp.some(e=> e.word === words[i]){
       check = 1
    }
    if(i>0 && words[i][0] !== temp[i-1].word[temp[i-1].word.length-1]){
      check = 1
    }
    temp.push({word: words[i], num: (i+1)%n, check: check})
    
    if(temp[i].check === 1){
      if(temp[i].num === 0){
        answer.push(n, Math.ceil((i+1)/n))
      } else {
        answer.push(temp[i].num, Math.ceil((i+1/n)))
      }
      break
    }
  }
  if(answer.length === 0){
    answer = [0,0]
  }
  return answer
}

나의 알고리즘

  1. 누가 무슨 말을 했는지 객체화해서 저장한다.
    1-1. 예를들어 ["tank", "kick", "know", "wheel", "land", "dream", "mother", "robot", "tank"]가 입력되었다면, {단어: tank, 누구: 1번사람} 이런 식으로 저장한다.
    1-2. 배열의 index % 사람 수를 하여 수를 반복해서 누구에 저장한다.
    ※ n번째 사람은 0으로 저장된다는 것을 유념한다.
  2. 가장 먼저 탈락한 사람을 check한다.
    2-1. 탈락할 수 있는 경우의 수는
    ① 앞에 있는 단어 또 말하기
    ② 끝말과 이어지지 않는 단어 말하기
    2-2. 따라서 만약 탈락자라면 {단어: tank, 누구: 1번사람, 체크: 체크됨}
    2-3. 탈락자가 아니라면 {단어: tank, 누구: 1번사람, 체크: 체크안됨}
    이런 식으로 저장한다.
  3. 탈락자가 나오면 반복문을 break하고 answer = [누구, 몇번째] 으로 반환한다.
    3-1. 몇번째인지 어떻게 알 수 있나? 해당 index+1 / 사람 수를 하고 소수점 올림하면 몇번째 차례인지 구할 수 있다.
    누구 = 0인 사람은 n번째 사람이니까, 누구가 0일때와 아닐때를 나눠 answer에 push 한다.
  4. 탈락자가 나오지 않았다면 answer = [0,0] 으로 반환한다.

맨 처음엔

  1. 이전에 말한 단어를 또 말했나 확인 → 있으면 check
  2. (그런 사람 없으면) 앞단어 끝 문자랑 잘 이어지는 단어인지 확인 → 아니면 check
  3. (탈락자가 없으면) → [0,0] return

이렇게 생각했다.

그런데 문제는, 만약 ["tank", "kick", "know", "wheel", "land", "dream", "mother", "bot", "tank"] 이 들어오면, "bot"을 말한 사람이 가장 먼저 탈락하므로 이 사람을 반환해야 하는데, "tank"를 반환해버리게 되는 문제가 발생했다.
즉, 최초 탈락자를 구하기 위해선 1과 2의 과정이 동시에 진행되어야 하는 것이다. 이 부분을 건드려줬더니 바로 통과했다.

테스트 케이스를 통과시키는 것에서 그치는 것이 아닌 예외사항을 전체적으로 아우를 수 있는 코드를 짜내려가는 것을 목표로 연습하자 !

profile
개발 공부하는 심리학도

0개의 댓글