수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다. 마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.
function solution(participant, completion) {
participant.sort();
completion.sort();
for(let i = 0; i < participant.length; i++) {
if(participant[i] !== completion[i]) return participant[i];
}
}
완주하지 못한 선수는 단 한 명이다. 즉, completion과 participant 배열은 요소 하나를 제외하면 모두 같은 요소만을 가지고 있다. 또한 각 배열은 선수들의 이름str
만 포함하고 있기 때문에 두 배열 모두 오름차순으로 정렬해주었다.
두 배열 중 길이가 더 긴 partcipant 배열의 length를 기준으로 for문을 돌면서, 동일 인덱스에 위치한 값이 서로 다를 때의 값을 반환해주었다.
△△ 게임대회가 개최되었습니다. 이 대회는 N명이 참가하고, 토너먼트 형식으로 진행됩니다. N명의 참가자는 각각 1부터 N번을 차례대로 배정받습니다. 그리고, 1번↔2번, 3번↔4번, ... , N-1번↔N번의 참가자끼리 게임을 진행합니다. 각 게임에서 이긴 사람은 다음 라운드에 진출할 수 있습니다. 이때, 다음 라운드에 진출할 참가자의 번호는 다시 1번부터 N/2번을 차례대로 배정받습니다. 만약 1번↔2번 끼리 겨루는 게임에서 2번이 승리했다면 다음 라운드에서 1번을 부여받고, 3번↔4번에서 겨루는 게임에서 3번이 승리했다면 다음 라운드에서 2번을 부여받게 됩니다. 게임은 최종 한 명이 남을 때까지 진행됩니다.
이때, 처음 라운드에서 A번을 가진 참가자는 경쟁자로 생각하는 B번 참가자와 몇 번째 라운드에서 만나는지 궁금해졌습니다. 게임 참가자 수 N, 참가자 번호 A, 경쟁자 번호 B가 함수 solution의 매개변수로 주어질 때, 처음 라운드에서 A번을 가진 참가자는 경쟁자로 생각하는 B번 참가자와 몇 번째 라운드에서 만나는지 return 하는 solution 함수를 완성해 주세요. 단, A번 참가자와 B번 참가자는 서로 붙게 되기 전까지 항상 이긴다고 가정합니다.
function solution(n, a, b) {
let count = 0;
while(a !== b) {
a = Math.ceil(a / 2);
b = Math.ceil(b / 2);
count++;
}
return count;
}
a
선수와 b
선수는 무조건 이겨서 다음 라운드로 진출한다는 점을 생각하면서 풀이했다.
한 라운드에서 두 명의 선수가 경쟁하기 때문에 a
선수와 b
선수가 만날 때까지 while문을 돌며 각 선수 번호에 /2
를 해준다. 이때 선수 번호가 홀수인 경우를 대비해 Math.ceil을 사용해줘 다음 짝수로 변환해준다.
카오톡 오픈채팅방에서는 친구가 아닌 사람들과 대화를 할 수 있는데, 본래 닉네임이 아닌 가상의 닉네임을 사용하여 채팅방에 들어갈 수 있다.
신입사원인 김크루는 카카오톡 오픈 채팅방을 개설한 사람을 위해, 다양한 사람들이 들어오고, 나가는 것을 지켜볼 수 있는 관리자창을 만들기로 했다. 채팅방에 누군가 들어오면 다음 메시지가 출력된다.
"[닉네임]님이 들어왔습니다."
채팅방에서 누군가 나가면 다음 메시지가 출력된다.
"[닉네임]님이 나갔습니다."
채팅방에서 닉네임을 변경하는 방법은 다음과 같이 두 가지이다.
채팅방을 나간 후, 새로운 닉네임으로 다시 들어간다.
채팅방에서 닉네임을 변경한다.
닉네임을 변경할 때는 기존에 채팅방에 출력되어 있던 메시지의 닉네임도 전부 변경된다...(전체읽기)
record는 다음과 같은 문자열이 담긴 배열이며, 길이는 1 이상 100,000 이하이다.
다음은 record에 담긴 문자열에 대한 설명이다.
function solution(record) {
let answer = [],
inOutData = record.map(el => el.split(' '));
let userInfo = {};
for (let i = 0; i < inOutData.length; i++) {
if (inOutData[i].length === 3) userInfo[inOutData[i][1]] = inOutData[i][2];
}
for(let i = 0; i < inOutData.length; i++) {
if(inOutData[i][0] === 'Enter') answer.push(`${userInfo[inOutData[i][1]]}님이 들어왔습니다.`)
if(inOutData[i][0] === 'Leave') answer.push(`${userInfo[inOutData[i][1]]}님이 나갔습니다.`)
}
return answer;
}
코드가 수행해야하는 기능을 크게 두 개로 분류해서 접근했다.
매개변수 record 배열을 map 메서드를 통해 공백을 기준으로 나눠서 inOutData라는 이차원 배열을 만들었다.
이후 userInfo 라는 객체를 선언하고, inOutData를 순회하면서 inOutData[i]의 길이가 3일 때, 즉 Enter / Leave 이벤트가 발생했을 때를 기준으로 userInfo 객체 안에 ID, 닉네임 값을 업데이트 해주었다.
Change
를 참고할 필요 없다) 이후 다시 inOutData 배열을 순회하며, 각 요소의 첫 번째 값이 'Enter'인 경우 (즉, 유저가 채팅방에 입장했을 때) 해당 ID와 매칭되어 있는 닉네임 + 님이 들어왔습니다.
를 answer 배열에 담아주었고, 'Leave'인 경우 ID와 매칭되어 있는 닉네임 + 님이 나갔습니다.
를 answer 배열에 담아주었다.
// 첫 번째 코드에서 사용한 유저별 닉네임 업데이트 부분
for(let i = inOutData.length - 1; i >= 0; i--) {
for(let j = 0; j < i; j++) {
if(inOutData[j][1] === inOutData[i][1]) {
inOutData[j][2] = inOutData[i][2];
}
}
}