20230217 TIL
지금까지 풀었던 코딩테스트 다시 처음부터 풀어보는데... 역시 아직도 햇갈리는 부분들이 조금씩 있는 것 같다ㅠ 뭔가 문법이 바로바로 생각나지 않는달까... 완전히 내걸로 만들려면 오늘 다시 한번 복습을 해야겠다!!
☆다시 체크해야할 문법★
1. filter() : 해당 함수의 반환 값을 true로 만드는 요소를 찾는다
보통 [배열].filter(변수 => 변수의 조건) 혹은 [배열].filter(함수) 형태로 사용한다. 아래의 경우 [ { id: 1, name: 'John' }, { id: 2, name: 'Pete' } ] 를 출력한다.
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
let someUsers = users.filter(item => item.id < 3);
console.log(someUsers)
2. map() : 배열을 변형시키거나 요소를 재 정렬해준다
보통 [배열].map(변수 => 출력할 조건) 혹은 [배열].map(함수) 형태로 사용한다. 아래의 경우 [ 2, 8, 18, 32 ]를 출력한다.
const array1 = [1, 4, 9, 16];
const map1 = array1.map(x => x * 2);
console.log(map1);
코딩 테스트 풀이 (1) 완주하지 못한 선수
수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.
입력값 participant = ["mislav", "stanko", "mislav", "ana"], completion = ["stanko", "ana", "mislav"]
출력값 "mislav"
문제 점
이번 문제는 시간효율성 검사도 했기 때문에 시간 효율성 검사를 통과하지 못해서 실패하는 경우가 많았다. 우리 팀의 답안도 시간효율성을 통과하지 못했는데 이유는 사실 모르겠으나 모든 조건을 따로따로 체크한것이 문제였던 것 같다.
우리팀 답안
function solution1(participant, completion) {
var answer = '';
let set = new Set(participant)
// console.log("set",set)
let arr = [...set]
if (arr.length == participant.length) {
// console.log("arr",arr)
return participant.filter(x => !completion.includes(x)).join('')
} else {
for (const element of completion) {
const index = participant.indexOf(element);
if (index !== -1) {
participant.splice(index, 1); // remove element from result
}
}
return participant.join('');
}
}
시간효율성 검사를 통과하기 위해서는 최대한 간단한 방법으로 체크할 수 있어야 할 것같다...
해결 방안
완주한 사람의 목록과 참가한 사람의 목록을 함께 확인하면서 한명씩 골라내야했다. 완주한 사람의 목록에도 동명이인이 있을지도 모르기 때문에 일단 완주한 사람 목록을 객체 {사람이름:인원수}의 형태로 만들어주면 된다고 한다.
for (let i = 0; i < completion.length; i++) {
if (!key.has(completion[i])) {
key.set(completion[i], 1)
} else {
key.set(completion[i], key.get(completion[i]) + 1)
}
이때 생성되는 객체는 key ={ 'stanko' => 1, 'ana' => 1, 'mislav' => 1 } 형태가 된다. 그 후 참가한 사람 수만큼 반복문을 돌려서 해당 값이 1인지 확인하고 값을 1씩 지워간다. 그러다가 해당값이 1이 아니라 0인 경우 즉, 이미 이전에 한번 지웠던 경우는 완주하지 못한 동명이인으로 판단할 수 있다.
알아야할 것
Set.prototype.has() : set 객체에 주어진 요소가 존재하는지 여부를 판별
new Set() 은 자료형에 관계없이 객체를 생성한다. 아래의 경우 true를 반환한다.
const set1 = new Set([1, 2, 3, 4, 5]);
console.log(set1.has(1));
.add() 객체에 값추가 .delete() 값 삭제 .size() 배열의 length 처럼 값의 갯수 확인
handler.get() : 속성 값을 가져올 수 있다.
♪ 또 다른 해결법
위의 코딩이 최선의 방법인 줄 알았지만 더 간결하게 체크할 수 있는 방법이 있었다 두개의 배열을 각각 정렬을 해준 후 인덱스의 해당값을 비교하면서 체크하면 동명이인도 바로 체크할 수 있다고 한다.
for (let i =0;i<participant.length;i++){
if(participant[i] != completion[i]){
answer = participant[i]
return answer
}
}
위의 경우 두개의 리스트에서 같은자리에 있는 참가자와 완주한 선수의 이름을 비교해서 다른경우에만 리턴을 해주기 때문에 더 간단하게 작성할 수 있는 것 같다.
코딩 테스트 풀이 (2)
1937년 Collatz란 사람에 의해 제기된 이 추측은, 주어진 수가 1이 될 때까지 다음 작업을 반복하면, 모든 수를 1로 만들 수 있다는 추측입니다. 작업은 다음과 같습니다.
1-1. 입력된 수가 짝수라면 2로 나눕니다.
1-2. 입력된 수가 홀수라면 3을 곱하고 1을 더합니다.
2. 결과로 나온 수에 같은 작업을 1이 될 때까지 반복합니다.
예를 들어, 주어진 수가 6이라면 6 → 3 → 10 → 5 → 16 → 8 → 4 → 2 → 1 이 되어 총 8번 만에 1이 됩니다. 위 작업을 몇 번이나 반복해야 하는지 반환하는 함수, solution을 완성해 주세요. 단, 주어진 수가 1인 경우에는 0을, 작업을 500번 반복할 때까지 1이 되지 않는다면 –1을 반환해 주세요.
입력 값 16
출력 값 4
문제 점
지금까지 풀었던 문제든을 다 반복하는 횟수가 정해져 있는 경우였는데 이번에는 프로그램이 실행되는 동안 반복이 몇번 되는지를 찾아야 하는 문제였다. 처음에는 for 반복문과 if 조건문을 사용해서 작성하려고 했으나 for안에 if안에 또 for가 들어가는 복잡하고 이상한 코드가 되었다... 심지어 틀림..ㅎ
해결 방안
반복 횟수를 정하지 않고 어떤 조건을 만족하는 동안 반복을 해주는 while을 사용하면 된다!!
let i =0
while (num!=1){
//위에 있는 조건을 적으면 된다
i++
}
입력받은 num이 1이 되기 전까지 계속 반복을 실행할 수 있다. 그리고 반복하는 횟수를 체크해야 하기 때문에 while의 가장 마지막에 i를 하나씩 더해주면 된다!! 완전 간단!! 완전 신세계!! while문이 끝나면 그 때 조건문으로 횟수를 체크해서 반복 횟수를 리턴할 지 -1을 리턴할 지 정해주면 된다!
알아야할 것
while 반복문 : 조건이 참인동안 반복문의 코드가 실행된다.
let i = 0;
while (i < 3) { // 0, 1, 2가 출력됩니다.
console.log( i );
i++;
}
☆오늘 새로 알게 된 메소드★
Math.abs(숫자) : 주어진 숫자의 절대값을 반환
Math.abs('-1'); //1
Math.max(숫자1,숫자2...) : 입력값으로 받은 0개 이상의 숫자 중 가장 큰 숫자 반환
Math.max(10, 20); //20
Math.min(숫자1,숫자2...) : 입력값으로 받은 0개 이상의 숫자 중 가장 작은 숫자 반환
var x = 10, y = -20;
var z = Math.min(x, y);
Math.pow(밑값, 지수) : 주어진 밑 값을 주어진 지수값으로 거듭제곱한 숫자 값 반환
Math.pow(7, 2); //49
Math.sqrt(숫자) : 주어진 숫자에 루트를 씌운 값 반환
Math.sqrt(9); //3
Math.round(숫자) :입력값을 반올림한 값과 가장 가까운 정수 반환
Math.round( 20.49) //20