[TIL] 211018
📝 오늘 한 것
-
프로그래머스 문제 풀이 - 완주하지 못한 선수 / 두 정수 사이의 합 / 평균 구하기 / 짝수와 홀수 / 체육복
-
Math.abs() / filter()를 이용해 합집합, 교집합, 차집합 구하는 법
📚 배운 것
1. 프로그래머스 문제 풀이
1) Level 1 문제 풀이
(1) 완주하지 못한 선수
프로그래머스 문제 풀이 - 완주하지 못한 선수 / 두 정수 사이의 합 / 평균 구하기 / 짝수와 홀수 / 체육복
Math.abs() / filter()를 이용해 합집합, 교집합, 차집합 구하는 법
1. 프로그래머스 문제 풀이
1) Level 1 문제 풀이
(1) 완주하지 못한 선수
🔎 옛날에 작성했던 풀이
- 정확도 테스트만 통과하고 효율성 테스트는 0점 맞았던 답안...
function solution(participant, completion) {
for (let i = 0; i < completion.length; i++) { // 순회
var index = participant.indexOf(completion[i]); // 선형 검색
participant.splice(index, 1); // 삭제
}
var answer = participant.toString();
return answer;
}
🔎 수정한 풀이
- sort()를 이용해 두 배열을 정렬한다.
- for 루프를 이용해 각 배열의 i번째 요소가 서로 같은지를 확인한다.
- 다른 것을 찾았다면, 그 요소를 변수 answer에 할당해 반환한다.
function solution(participant, completion) {
var answer = '';
participant.sort();
completion.sort();
for (let i = 0; i < participant.length; i++) {
if (participant[i] !== completion[i]) {
answer = participant[i];
break;
}
}
return answer;
}
🔎 다른 사람의 풀이 1
- pop()을 이용해 두 배열의 끝에서 제거한 요소들끼리 비교한 후, 다르다면 이를 반환한다.
function solution (participant, completion) {
participant.sort();
completion.sort();
while (participant.length) {
let participant_pop = participant.pop();
if (participant_pop !== completion.pop()) {
return participant_pop;
}
}
}
🔎 다른 사람의 풀이 2
forEach()
와 해시 테이블(Hash Table)
이용
- participant 배열을 해시 테이블로 만든다
- p 배열의 요소를 key로 하고, 그 value는 1로 한다.
- 만약 (p 배열의 요소가 중복되어) p 배열의 요소를 key로 하는 value가 이미 존재한다면, 그 value를 1 증가시킨다.
- completion 배열의 요소를 key로 하여 읽어온 value를 1 감소시킨다. ( = p 배열과 c 배열에 중복되는 요소를 key로 하는 value를 1 감소시킨다.)
- for in 루프를 이용해 해시 테이블의 value가 1 이상인 key를 찾아 최종적으로 그 key를 리턴한다.
function solution(participant, completion) {
let hash = [];
participant.forEach(name => {
hash[name] = hash[name] ? hash[name] + 1 : 1
})
completion.forEach(name => {
hash[name] = hash[name] - 1
})
for (var name in hash) {
if (hash[name] >= 1) {
return name
}
}
}
(2) 두 정수 사이의 합
🔎 처음 작성한 풀이
- 정확도 테스트는 통과했고 효율성 테스트는 없었지만 효율성이 안 좋은 풀이다
function solution(a, b) {
const nums = [];
if (a < b) {
for (let i = a; i <= b; i++) {
nums.push(i);
}
} else if (a > b) {
for (let i = b; i <= a; i++) {
nums.push(i);
}
} else {
return a;
}
return nums.reduce((prev, curr) => prev + curr, 0);
}
🔎 수정한 풀이
- Math.min()과 Math.max() 사용
- reduce() 대신 sum 변수를 이용
function solution(a, b) {
if (a === b) {
return a;
}
let sum = Math.min(a, b);
for (let i = Math.min(a, b) + 1; i <= Math.max(a, b); i++) {
sum = sum + i;
}
return sum;
}
🔎 다른 사람의 풀이
-
Math.abs()
이용주어진 숫자의
절대값
을 반환한다
ex) console.log(Math.abs(4 - 9)); // 5
function solution(a, b) {
return (a + b) * (Math.abs(b - a) + 1) / 2;
}
(3) 평균 구하기
🔎 내가 작성한 풀이
function solution(arr) {
return arr.reduce((prev, curr) => prev + curr, 0) / arr.length;
}
(4) 짝수와 홀수
🔎 내가 작성한 풀이
function solution(num) {
if (num % 2 === 0) {
return 'Even';
} else {
return 'Odd';
}
}
🔎 다른 사람의 풀이
- 조건부 삼항 연산자 이용
function solution(num) {
return num % 2 === 0 ? 'Even' : 'Odd';
}
(5) 체육복
🔎 처음 작성한 풀이
-
각각 lost와 reserve에서 체육복 여벌을 가지고 있으면서 동시에 한 벌을 도난당한 학생들 즉, lost와 reserve의 교집합을 제거한 후, lost와 reserve 배열에 담긴 요소(학생들 번호)들을 조건을 고려해 비교하고자 했다.
-
테스트 케이스는 통과했으나, 실제 채점 시 정확도 테스트에서 55점 맞은 답안...이었는데 다시 하니까 85점 나온다. 뭐지? 어쨌든 틀린 풀이다.
function solution(n, lost, reserve) {
var answer = 0;
const lostCount = lost.length;
const reserveCount = reserve.length;
const intersection = [];
for (let i = 0; i < lost.length; i++) {
for (let j = 0; j < reserve.length; j++) {
if (lost[i] === reserve[j]) {
intersection.push(lost[i]);
lost.splice(i, 1);
reserve.splice(j, 1);
break;
}
}
}
let lentCount = 0;
for (let i = 0; i < reserve.length; i++) {
for (let j = 0; j < lost.length; j++) {
if (reserve[i] === lost[j] - 1 || reserve[i] === lost[j] + 1) {
lentCount++;
lost.splice(j , 1);
break;
}
}
}
const rest = n - (lostCount + reserveCount - intersection.length);
answer = rest + reserveCount + lentCount;
return answer;
}
🔎 두 번째 작성한 풀이
-
테스트 케이스를 하나씩 추가해서 오류를 찾았다. 교집합을 구하는 for 루프에서 splice를 이용해 lost 배열의 중간 요소를 계속 제거하는 부분이 문제였다. 바깥 루프가 다음 루프를 돌 때 i는 이전에 비해 똑같이 1이 증가했지만, 실제 lost 배열에서는 이전 요소의 다음 요소가 아니라 다다음 요소가 잡히게 된다. 이는 이전 루프에서 splice에 의해 그 루프에서 잡혔던 요소를 제거했기 때문이다.
-
또한, splice로 인해 lost 배열과 reserve 배열을 제거했어도 lentCount를 증가시키는 중첩 루프에서 사용되는 lost 배열과 reserve 배열은 당연하게도 solution 함수의 매개변수로 전달된 배열들 그대로였기 때문에 의도했던 대로 비교가 되지 않았다.
-
각각 lost 배열과 reserve 배열에서 교집합을 제거하는 데 중첩 루프를 사용하니까 블록 스코프 안에서만 변화가 적용돼서 다음 코드에서 이어서 쓸 수가 없었다. 다른 방법이 있나 검색해보다 신세계 발견. [javascript] 배열 값 중복제거, 배열합치기 참고
-
맞을 줄 알았는데 90점이 나왔다. 뭐가 문제일까.
function solution(n, lost, reserve) {
var answer = 0;
const lostCount = lost.length;
const reserveCount = reserve.length;
// lost + reserve
const sum = lost.concat(reserve);
// 교집합
const intersection = sum.filter((item, index) => sum.indexOf(item) !== index);
// 차집합 : lost - (lost ∩ reserve)
const restLost = lost.filter(x => !intersection.includes(x));
// 차집합 : reserve - (lost ∩ reserve)
const restReserve = reserve.filter(x => !intersection.includes(x));
// 체육복을 빌린 학생 수
let lentCount = 0;
for (let i = 0; i < restReserve.length; i++) {
for (let j = 0; j < restLost.length; j++) {
if (restReserve[i] === restLost[j] - 1 || restReserve[i] === restLost[j] + 1) {
lentCount++;
restLost.splice(j , 1);
break;
}
}
}
// 본인 체육복만 가져와서 본인이 입는 학생 수 (도난x, 여별x)
const rest = n - (lostCount + reserveCount - intersection.length);
// '전체 학생 수 n - 체육복을 못 빌린 학생 수'와 같다
answer = rest + reserveCount + lentCount;
return answer;
}
🔎 세 번째 작성한 풀이
-
맨 처음에 lost 배열과 reserve 배열을 오름차순으로 정렬해주는 코드를 추가했다.
-
드디어 100점이다.
function solution(n, lost, reserve) {
lost.sort((a, b) => a - b);
reserve.sort((a, b) => a - b);
const sum = lost.concat(reserve);
const intersection = sum.filter((item, index) => sum.indexOf(item) !== index);
const restLost = lost.filter(x => !intersection.includes(x));
const restReserve = reserve.filter(x => !intersection.includes(x));
const lostCount = lost.length;
const reserveCount = reserve.length;
let lentCount = 0;
for (let i = 0; i < restReserve.length; i++) {
for (let j = 0; j < restLost.length; j++) {
if (restReserve[i] === restLost[j] - 1 || restReserve[i] === restLost[j] + 1) {
lentCount++;
restLost.splice(j , 1);
break;
}
}
}
const rest = n - (lostCount + reserveCount - intersection.length);
return rest + reserveCount + lentCount;
}
✨ 내일 할 것
- 프로그래머스 문제 풀이
Author And Source
이 문제에 관하여([TIL] 211018), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@leesyong/TIL-211018
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Author And Source
이 문제에 관하여([TIL] 211018), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@leesyong/TIL-211018저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)