오늘의 스터디 문제 목록
점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.
전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.
function solution(n, lost, reserve) {
// 전체 학생 n, 도난당함 lost, 기부학생번호 reserve
// 여벌을 가지고 있는 학생이 도난당하면 빌려줄 수 없으므로
// lost와 reserve에 동시에 존재하면 reserve에 해당 학생 번호를 지워줌
// 1. lost와 reserve 둘 다 번호가 있으면 reserve에서 제거해 줘야 됨
// 여벌을 가졌지만 도난당한 학생을 제외한 배열을 다시 reserve에 재할당
reserve = reserve.filter((ele) => !lost.includes(ele));
// 2. 여벌을 가지지도 않고 도난당하지도 않은 학생과 여벌을 가진 학생들은
// 체육수업을 들을 수 있으므로 도난당한 학생의 수만 전체 학생 수에 - 해 준다
let result = n - lost.length;
// 3. 이미 체육복은 받은 학생이 여벌을 가진 학생에게 또 받으면 안 되기 때문에
// 받을 수 있는 학생들을 모두 push 후 set으로 중복 제거
// 그리고 중복제거한 배열의 길이를 result와 더한다.
let arr = [];
for (let i = 0; i < reserve.length; i++) {
for (let j = 0; j < lost.length; j++) {
if (reserve[i] - 1 === lost[j]) {
arr.push(lost[j]);
if (reserve[i] + 1 === lost[j]) {
arr.push(lost[j]);
}
}
}
}
// arr 중복 제거
const uniqueArr = [...new Set(arr)];
result += uniqueArr.length;
return result;
}
function solution(n, lost, reserve) {
//lost와 reserve 둘 다 번호가 있으면 reserve과 lost에서 제거해 줘야 됨
// 여벌을 가진 사람 중 도난당한 학생 빼줌
reserve = reserve.filter((ele) => !lost.includes(ele));
// 도난당한 사람 중에서 여벌을 가졌다면 빼줌
lost = lost.filter((ele) => !reserve.includes(ele));
for (let i = 0; i < reserve.length; i++) {
for (let j = 0; j < lost.length; j++) {
// 앞, 뒤 번호 학생한테 줄 수 있으면 해당 학생은 0으로 바꾼다
if (reserve[i] - 1 === lost[j] || reserve[i] + 1 === lost[j]) {
lost[j] = 0;
break;
}
}
}
// 도난당한 학생들의 배열에서 받을 수 있는 학생들은 0으로 바뀌었으므로
// 전체 학생 n에 체육복을 받지 못한 학생/ 0이 아닌 학생의 명 수를 구해서 빼준다
return n - lost.filter((ele) => ele !== 0).length;
}
function solution(n, lost, reserve) {
// 전체 학생이 각자 가진 체육복 수를 1로 설정한다.
const uniform = Array(n).fill(1); // 1 1 1 1 1
// 도난당한 학생들의 체육복 수를 0으로 설정, 인덱스로 접근하기 때문에 학생 번호 - 1로 해야 됨
lost.map((lost) => {
uniform[lost - 1] = 0;
});
// 여벌을 가진 학생들은 +1 해 준다.
reserve.map((reserve) => {
uniform[reserve - 1] += 1;
}); // 1 0 2 0 1
for (let i = 0; i < n; i++) {
// 체육복이 0개인 학생이 앞의 학생한테 체육복을 받으면.
// 그 학생의 체육복 수를 +1로 하고 앞의 학생은 2개에서 하나를 줬기 때문에 -1을 해 준다.
if (uniform[i] === 0 && uniform[i - 1] === 2) {
uniform[i] += 1; // 1 0 1 1 1
uniform[i - 1] -= 1;
}
// 체육복이 0개인 학생이 뒤의 학생한테 체육복을 받으면.
// 그 학생의 체육복 수를 +1로 하고 앞의 학생은 2개에서 하나를 줬기 때문에 -1을 해 준다.
else if (uniform[i] === 0 && uniform[i + 1] === 2) {
uniform[i] += 1;
uniform[i + 1] -= 1;
}
}
// 가진 체육복이 1개 이상인 학생들의 수를 리턴
return uniform.filter((ele) => ele > 0).length; // 1 0 1 1 1 => 4
}
//! 1. lost와 reserve 겹치는 요소 제거
for (let i = 0; i < lost.length; ) {
if (reserve.includes(lost[i])) {
reserve.splice(reserve.indexOf(lost[i]), 1);
lost.splice(i, 1);
} else i++;
}
수웅이는 매달 주어진 음식을 빨리 먹는 푸드 파이트 대회를 개최합니다. 이 대회에서 선수들은 1대 1로 대결하며, 매 대결마다 음식의 종류와 양이 바뀝니다. 대결은 준비된 음식들을 일렬로 배치한 뒤, 한 선수는 제일 왼쪽에 있는 음식부터 오른쪽으로, 다른 선수는 제일 오른쪽에 있는 음식부터 왼쪽으로 순서대로 먹는 방식으로 진행됩니다. 중앙에는 물을 배치하고, 물을 먼저 먹는 선수가 승리하게 됩니다.
이때, 대회의 공정성을 위해 두 선수가 먹는 음식의 종류와 양이 같아야 하며, 음식을 먹는 순서도 같아야 합니다. 또한, 이번 대회부터는 칼로리가 낮은 음식을 먼저 먹을 수 있게 배치하여 선수들이 음식을 더 잘 먹을 수 있게 하려고 합니다. 이번 대회를 위해 수웅이는 음식을 주문했는데, 대회의 조건을 고려하지 않고 음식을 주문하여 몇 개의 음식은 대회에 사용하지 못하게 되었습니다.
예를 들어, 3가지의 음식이 준비되어 있으며, 칼로리가 적은 순서대로 1번 음식을 3개, 2번 음식을 4개, 3번 음식을 6개 준비했으며, 물을 편의상 0번 음식이라고 칭한다면, 두 선수는 1번 음식 1개, 2번 음식 2개, 3번 음식 3개씩을 먹게 되므로 음식의 배치는 "1223330333221"이 됩니다. 따라서 1번 음식 1개는 대회에 사용하지 못합니다.
수웅이가 준비한 음식의 양을 칼로리가 적은 순서대로 나타내는 정수 배열 food가 주어졌을 때, 대회를 위한 음식의 배치를 나타내는 문자열을 return 하는 solution 함수를 완성해주세요.
function solution(food) {
// (선수1) 1 2 2 3 3 3 물 3 3 3 2 2 1 (선수2)
// [...선수1의 음식 배치, 0, ...선수 2의 음식 배치]으로 합치고 join('')
// 1. 선수1의 음식 배치 구해서 선수2 때 그대로 활용해 reverse만 시켜 주기
// 2. map을 이용해 각 요소의 나누기 2로 나온 몫으로 변환한다. => 각 선수에게 줄 수 있는 음식양
// [1, 3, 4, 6] => [0, 1, 2, 3] 물, 첫번째음식, 두번째음식, 세번째음식
// 3. 배열의 인덱스 === 음식 순서이므로 음식의 양만큼 인덱스가 반복되면서 새로운 배열에 push
food = food.map((ele) => {
return (ele = Math.floor(ele / 2));
});
// 선수 1 음식 배치
let arr1 = [];
for (let i = 0; i < food.length; i++) {
// [0, 1, 2, 3]
if (!!food[i]) { // 들어온 음식의 수가 0이라면 false이므로 실행하지 않음
for (let j = 1; j <= food[i]; j++) {
arr1.push(i); // 배열의 인덱스 === 음식 순서
}
}
}
// 선수2의 음식 배치, 선수1의 음식 배치 활용
let arr2 = [...arr1];
arr2.reverse();
const result = [...arr1, 0, ...arr2];
return result.join('');
}
function solution(food) {
food.reverse()
let str = "0"
food.forEach((element,index) => {
const foodCount = Math.floor(element/2);
const foodStr = String(food.length-(index+1)).repeat(foodCount);
str = foodStr+str+foodStr
});
return str
}
function solution(food) {
let tmp = [0];
//[1, 7, 1, 2]
for(let i=food.length; i>=1; i--){ //3번인덱스->2번인덱스->1번인덱스
if(food[i] >= 2){
food[i] = Math.floor(food[i]/2); //[1, 7, 1, ☑️1] 로 변경됨
let repeatStr = String(i).repeat(food[i]); //인덱스 3을 '3'으로바꾸고 ☑️1 만큼반복해서 문자열변수에 저장
tmp.unshift(repeatStr) //언쉬프트,푸시하면 tmp는 ['3',0,'3'] 이 된다. 이걸반복.
tmp.push(repeatStr)
}
else continue;
}
return tmp.join('');
}
수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.
function solution(participant, completion) {
// 처음 filter와 includes를 사용하여 차집합을 구해 풀려고 했으나 동명이인이 있는 경우가 있어 사용하지 못함
// 마라톤에 참여한 선수의 이름이 담긴 배열 participant
// 완주한 선수들의 이름이 담긴 배열 completion
// 참여 선수와 완주 선수 정렬 후, 서로의 인덱스가 같지 않으면 해당 인덱스 값을 리턴
participant.sort();
completion.sort();
let idx = 0;
while (participant[idx] === completion[idx]) {
idx++;
}
return participant[idx];
}
solution(["leo", "leo", "kiki", "eden"], ["leo", "eden", "kiki"]);
function solution(participant, completion) {
const obj = {};
for (let el of participant) {
if (el in obj) obj[el]++;
else obj[el] = 1;
}
for (let el of completion) {
if (obj[el] === 1) delete obj[el];
else obj[el]--;
}
return Object.keys(obj)[0];
}
내가 풀었던 걸 다시 보니까 코드도 좀 더럽고 특히 의사코드도 주절주절 쓸데없는 말을 많이 적어 놓은 것 같다 ㅋㅋㅋ 간결하게 작성하려고 쪼끔만 더 노력해 보자...! 그리고 부뜩 (생각보다 문제가 어렵지 않아서 그랬나?) 코딩 실력이 아주 조금 늘었다는 기분이 들었다....! 아무렇지도 않게 filter와 map을 사용하려는 모습에 첨엔 이해도 못했는데..... 많이 성장했구나 싶었다 앞으로도 파이팅이야 ~~