[프로그래머스] 완주하지 못한 선수(JavaScript) 풀이

안녕하세요. 오늘은 프로그래머스 사이트의 "완주하지 못한 선수" 문제를
풀이하도록 하겠습니다.! 부족한 부분이 많으니 양해 바랍니다.!

출처: 프로그래머스 코딩 테스트 연습, https://programmers.co.kr/learn/challenges
문제: 프로그래머스 코딩테스트 연습 - 완주하지 못한 선수

[문제 설명]

수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.

마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

[제한사항]

마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
completion의 길이는 participant의 길이보다 1 작습니다.
참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
참가자 중에는 동명이인이 있을 수 있습니다.

[입출력 예]

participantcompletionreturn
["leo", "kiki", "eden"]["eden", "kiki"]"leo"
["marina", "josipa", "nikola", "vinko", "filipa"]["josipa", "filipa", "marina", "nikola"]"vinko"
["mislav", "stanko", "mislav", "ana"]["stanko", "ana", "mislav"]"mislav"

[예제 설명]

예제 #1

"leo"는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.

예제 #2

"vinko"는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.

예제 #3

"mislav"는 참여자 명단에는 두 명이 있지만, 완주자 명단에는 한 명밖에 없기 때문에 한명은 완주하지 못했습니다.

[풀이]

  1. 우선 참여자 명단과 완주자 명단 배열을 정렬합니다.
  2. 참여자 명단에서 완주자를 확인합니다.
  3. 각 명단은 정렬되어있기 때문에 명단을 확인하다보면 달라지는 부분이 생깁니다. 그때 참여자를 return

[소스코드]

1. for문 사용

const solution = (participant, completion) => {
	participant.sort(); //1. 우선 참여자명단과 완주자 명단 배열을 정렵합니다.
    	completion.sort();
  	// 2.참여자명단에서 완주자를 확인합니다.
  	for(let i=0; len=participant.length; i<len; i++) {
      		// 명단을 확인하다가 달라지는 부분에서 return 해줍니다.
    		if(participant[i] !== completion[i]) { 
            		return participant[i] 
        	}
    	} 
}

위와 같은 코드로 테스트를 통과한 모습입니다.

아래에는 구글링을 하며 다른 방법이 없을까 하며 혼자 끄적이다 완성한 다른 방식의 소스코드입니다.

2. reduce 사용

아래와 같은 방식으로 접근하게 된 이유는
참여자 명단과 완주자 명단은 결국 겹치게 되는데 ..
참여자는 1명이상이기 때문에 명단을 합쳐놓고 보면 결국 홀수로 남는 사람이 완주하지 못한 사람이라고 생각하게 되어 코드를 작성하였습니다.

const solution = (participant,completion) => {
    let concatList = participant.concat(completion); //명단을 합칩니다.  
    let list = concatList.reduce((a,c,i) => {
        a[c] = (a[c]) ? a[c] + 1 : 1
        return a
    },{}); // 통합된 명단에서 참여자와 완주자의 숫자를 카운트합니다
  	   // 참여자 명단,완주자 명단에 다 존재한다면 {이름 : 2} 
  	   //그렇지 않다면 {이름 : 1} 이런식으로 홀수와 짝수를 리턴하게됩니다.
  	   // 통합된 명단에서 이름이 홀수로 존재한다면 완주하지 못한사람이 됩니다.
    
    for (const k in list) { 
        if(list[k]%2 != 0) { 
          // {이름:1,이름2:2} 이 형식의 리스트에서 홀수인 수를 찾아 리턴 시킵니다.
            return k;
        }
    }
}

이 코드 또한 테스트에 통과가 된걸 보실 수 있습니다.
어떤 이유에서인지는 조금 더 공부해봐야겠지만 속도가 조금 더 빨라졌습니다...

[마치며]

알고리즘 문제를 풀며 느끼는 것은 관련 함수도 많이 알아야겠지만,
무엇 보다 문제를 분석하는 능력이 중요한 것 같습니다.

좋은 웹페이지 즐겨찾기