[코드테스트] 완주하지 못한 선수

이강민·2021년 11월 2일
0

[코드테스트]Javascript

목록 보기
12/39
post-thumbnail

완주하지 못한 선수

문제설명

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

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

제한사항

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

입출력 예

participant completion return
["leo", "kiki", "eden"] ["eden", "kiki"] "leo"
["marina", "josipa", "nikola", "vinko", "filipa"] ["josipa", "filipa", "marina", "nikola"] "vinko2"
["mislav", "stanko", "mislav", "ana"] ["stanko", "ana", "mislav"] "mislav"

나의 풀이

소수와 못지 않게 푸는데 꽤 난관이 있던 문제였다.
단순히 문제를 보았을 때 2개의 배열을 놓고 배열 중 겹치는 값을 제외하고 겹치지 않는 값을 출력하는 끝이였다. 어떻게 푸는지는 직관적으로 알 수 있었지만 역시 어떻게 코드를 풀어나가야 하는 지 고민이 되었다. 실제로 많은 시도가 있었지만 코드를 완전히 다르게 작성한 2가지 시도와 통과한 1가지 시도를 기술해 보겠다.

첫 번째 시도(실패)

먼저 participant라는 배열에 completion의 배열 값들이 어디 위치에 있는지 알기 위해
반복과 indexOf를 사용했다.
다음 그 위치들을 index에 옮겨 splice를 적용했다. result에 splice한 값을 담고
pop을 하여 배열에서 뺐다. 이렇게 하니 코드 실행까지는 되지만 일부 검증오류와 효율성에서 떨어져 시간이 초과되었다.
배열이 몇 명 없으면 문제 없지만 만명이 넘어가면 역시 for구문은 안되는 것 같다...

function solution(participant, completion) {
    let index = 0;
    let result;
    for (let i = 0; i < completion.length; i++) {
        index = participant.indexOf(completion[i])
        //console.log(index)
        result = participant.splice(index,1);
        //console.log(participant)
    }
    result = participant.pop();
  return console.log(result);

}

solution(participant, completion);

두 번째 시도(실패)

효율성에서 떨어진 나는 for구문을 사용하지 않고 작성해 보았다.
먼저 차 집합을 구하기 위해 filter를 사용하여 includes 되지 않는 값들을 걸러내었다.
그러니 문제는 동명이인이 생긴 것이다. 동명이인이 있을때 answer값이 length가 0이 되기 때문에 0 이상일 때만 값을 pop으로 뽑아내고 0일때 find로 그 값을 찾아냈다.
그러나 동명이인은 3명일 수 도 여러명일 수 도 있다는걸 효율성과 정확성 테스트에서 알 수 있었다....

unction solution(participant, completion){
    let answer = participant.filter(function(element){if(!completion.includes(element)){
        return element;
    }});
    if(answer.length > 0){
        answer = answer.pop();
    }
    if(answer.length === 0){
        answer = participant.find(function(element){if(completion.includes(element)){
            return element;
        }});
    }
    console.log(answer);
    return answer;
}
solution(participant, completion);

세번째 시도(통과)

마지막으로 그럼 다시 for구문을 사용했는데 먼저 2개의 배열을 동일하게 정렬시키고 정렬된 배열을 비교하여 다른 값이 나오면 곧바로 result에 담아버리고 for구문을 끝내면 시간초과는 되지 않을 것이다.

function solution(participant, completion){
    let result;
  //2개의 배열을 정렬하여 값을 비교하기 쉽게 만들었다. 
    participant = participant.sort();
    //console.log(participant);
    completion = completion.sort();
    //console.log(completion);
//가장 긴 배열만큼 반복시켜서 비교배열과 다른 값이 나오면 곧바로 return 시켜 for 구문을 종료하였다. 
    for (let i = 0; i < participant.length; i++) {
        if(completion[i] !== participant[i]){
          //result에 비교했을 때 다른 값이 담긴다. 
            return result = participant[i];
        }
    }
  //다른 값이 담긴 result를 출력한다. 
    return result;
}
//함수를 실행한다. 
solution(participant, completion)

다른 사람 풀이(고인물 플레이)

아래 풀이와 다르게 한 문장으로 작성한 고인물 중에 고인물이 있었지만 소름이 돋아 여기에 작성하기 힘들었다.🥱

이걸 보고 고인물이라 부르지 않는다면 무어라 말하랴.......
한줄에 모든걸 담아 인간이 난 이해하기 힘들었다.........🤔

var solution=(_,$)=>_.find(_=>!$[_]--,$.map(_=>$[_]=($[_]|0)+1))

그래도 2번 고인물은 이해할 수 있고 내가 될 수 있는 사람이 쓴 코드

내가 사용한 방법과 다른 점음 for in 구문을 사용하고 리턴 값을 궂이 다른 저장공간에 담지 않고 바로 출력했다는 점이 다르겠다.

//2번 고인물 
function solution(participant, completion) {
//2개의 배열을 정렬한다. 
    participant.sort();
    completion.sort();
//가장 긴 배열만큼 반복한다. 
    for(let i in participant) {
      //비교 배열과 다르면 곧바로 그 배열의 값을 리턴한다. 
        if(participant[i] !== completion[i]) return participant[i];
    }
}
profile
AllTimeDevelop

0개의 댓글

관련 채용 정보