코딩테스트 연습하기

January·2022년 9월 15일
0

Frontend

목록 보기
20/31

Lv1

홀수 짝수 조건문

// 내 답안
function solution(num) {
    let answer = '';
    if(num%2 === 0) {
        answer = 'Even'
    } else {
        answer = 'Odd'
    }
    return answer;
}

나머지 연산을 완전히 알지 못하고 사용했다.

// 다른 사람 답안
function evenOrOdd(num) {
  return num % 2 ? "Odd" : "Even";
}

삼항연산자를 사용해서 깔끔하고 짝수인 경우 true가, 홀수인 경우 false가 나온다

자리수 덧셈

// 내 답안
function solution(n) {
    var answer = 0;
    let numStr = n.toString()
    for(let i = 0; i < numStr.length; i++) {
        answer = answer + parseInt(numStr[i])
    }
    return answer;
}

문자열은 자리수 계산이 가능하다. 숫자.length

// 다른 사람 답안
function solution(n){
    return (n+"").split("").reduce((acc, curr) => acc + parseInt(curr), 0)
}

숫자+문자 연산을 하면 문자열이 반환된다. split으로 쪼개주고 reduce로 전부 더해준다. 초기값 0, 누적값 curr. 상당히 깔끔하게 느껴진다.

약수 구하기

// 내 답안
function solution(n) {
    var answer = 0;
    let calc = 1
    while(calc <= n) {
        if(n % calc === 0) {
            answer = answer + calc
        }
        calc++
    }
    return answer;
}

나머지가 0일때 약수이니까 반복문을 돌려준다.

/// 다른 사람 답안
function solution(num) {
    let sum = 0;
    for (let i = 1; i <= num; i++) {
        if (num % i === 0) sum += i
    }
    return sum
}

왜 for문에 종료식을 매개변수로 할 생각을 못했지. 사실상 똑같은 거지만 for문이 더 깔끔하고 익숙해서 좋아보인다.

평균 구하기

// 내 답안
function solution(arr) {
    var answer = 0;
    for(let i = 0; i < arr.length; i++) {
        answer = answer + arr[i]
    }
    answer = answer / arr.length
    return answer;
}

제일 쉬웠다

// 다른 사람 답안
function average(array){
  return array.reduce((a, b) => a + b) / array.length;
}

대박이넹..reduce 메서드를 익숙하게 써보질 못해서 생각을 못했던거 같다. 한 데이터에 반복적인 연산에는 reduce를 기억하자

정수 제곱근 판별

// 내 답안
function solution(n) {
    var answer = 0;
    let a = Math.sqrt(n)
    Number.isInteger(a) ? answer = (a + 1) * (a + 1) : answer = -1
    return answer;
}

내가 알고있는 실력에서는 문제 해결이 가능하지만 처리시간이 길어서 탈락이다. 처음보는 메서드를 사용해야했다. Math.sqrt(n) 제곱근을 구한다. 음수일 경우 NaN을 반환한다. Number.isInteger(a)은 정수인지 불린데이터로 반환한다. n의 제곱근이 양수인 실수가 반환되는 경우를 생각해서 넣었다.

// 다른 사람 답안
function solution(n) {
    return Math.sqrt(n) === parseInt(Math.sqrt(n)) ? (Math.sqrt(n) + 1) ** 2 : -1
}

제곱근이 정수면 딱 맞아 떨어지는거니까 정수와의 비교를 했다. 짱깔끔..

자연수 뒤집어 배열 만들기

// 내 답안
function solution(n) {
    var answer = [];
    let a = (n+"").split("").reverse();
    for(let i = 0; i < a.length;  i++) {
        const b = Number(a[i])
        answer.push(b)
    }
    return answer;
}

뒤집어서 for문으로 하나하나 타입을 변환시켜줬는데 코드 작성하면서도 뭔가 안좋은 방법이라는 생각을 했다.

// 다른 사람 답안
function solution(n) {
    return (n+"").split("").reverse().map(v => parseInt(v));
}

이거지. 왜 map 메서드를 생각하지 못했을까 깔끔하다.

'p'와 'y' 찾기

// 내 답안
function solution(s){
    var answer = true;
    let a = s.toUpperCase()
    let b = a.split("").filter(item => item === 'P')
    let c = a.split("").filter(item => item === 'Y')
    let d = b.length === c.length ? true : false
    answer = b && c === 0 ? true : d
    return answer;
}

모두 대문자 변경하고 쪼개서 배열 메서드를 사용했는데 삼항연산자가 연달아 동작해서 좋은 코드는 아닌듯 하다

// 다른 사람 답안
function solution(s){
    return s.toUpperCase().split("P").length === s.toUpperCase().split("Y").length;
}

와우 불린데이터만 내놓으면 되니까 비교연산자로 한줄에 끝내버리네 아주 좋은거 같습니다

정수 내림차순으로 정리하기

// 내 답안
function solution(n) {
    var answer = 0;
    let a = (n+"").split("")
    answer = Number(a.sort((next, pre) => pre - next ).join(""))
    return answer;
}

sort 메서드만 안다면 쉽게 풀 수 있다.

// 다른 사람 답안
function solution(n) {
  const newN = n + "";
  const newArr = newN
    .split("")
    .sort()
    .reverse()
    .join("");

  return +newArr;
}

sort에 콜백을 사용하지 않고서 오름차순을 리버스해줬는데 그렇지 않는 코드와는 큰 차이가 없지 않나라는 생각이 든다. 가독성, 실행속도 등 복잡한 코드를 짜야할때에 필요한 능력을 겸비해야겠다

하샤드 수

// 내 답안
function solution(x) {
    var answer = true;
    let a = (x+"").split("")
    let b = 0
    for(let i = 0; i < a.length; i++) {
        b = b + Number(a[i])
    }
    if(x % b === 0) answer = true
    else answer = false
    return answer;
}

나름 쉬웠던거 같다. 자리수로 쪼개주고 숫자로 변환후 더해주고 인수로 나눠줬을때 딱 맞아 떨어지는것만 찾으면 됐어서 풀만했다.
그런데 답을 불린타입으로 내는건데 굳이 조건문으로 필터를 안해도 됐던거였다.

// 다른 사람 답안
function Harshad(n){
  return !(n % (n + "").split("").reduce((a, b) => +b + +a ));
}

나머지가 0일때 부정연산자를 쓰면 true이다. 0이 아닐때는 false가 나오기때문에 문제에서부터 부정연산을 사용하라고 알려준것처럼 깔끔하게 코드가 나오게된거같다.

문자열을 정수로 바꾸기

// 내 답안
function solution(s) {
    var answer = 0;
    answer = parseInt(Number(s))
    return answer;
}

문자열을 숫자로 바꾸고 정수로 변환해준다

// 다른 사람 답안 1
function strToInt(str){
  return str/1
}

// 다른 사람 답안 2
function strToInt(str){
  return  +str;
}

문자열과 숫자열의 사칙연산은 숫자가 나오게 된다...

나머지가 1이 되는 수

// 내 답안
function solution(n) {
    var answer = 0;
    for(let x = 1; x < n; x++) {
        if(n%x === 1) return answer = x
    }
    return answer;
}

n의 값이 3 ~ 1,000,000이였는데 문제를 잘못이해해서 for문을 돌릴때 x을 3부터 시작했다. 그래서 정답이 틀렸는데..정확히 이해하고 코딩하자!

// 다른 사람 답안
function solution(n, x = 1) {    
    while (x++) {
        if (n % x === 1) {
            return x;
        }
    }    
}

for of, while을 써보도록 하자!

x만큼 간격이 있는 n개의 숫자

// 내 답안
function solution(x, n) {
    var answer = [];
    let a = 0
    for(let i = 0; i < n; i++) {
        a = a + x
        answer.push(a)
    }
    return answer;
}

push로 넣어주는데 뭔가 단순하지 못하게 코드를 짰다. 곱셈을 했으면 됐는데

// 다른 사람 답안 1
function solution(x, n) {
    var answer = [];
    for (let i = 1; i <= n; i++) {
        answer.push(x*i)
    }
    return answer;
}

// 다른 사람 답안 2
function solution(x, n) {
    return Array(n).fill(x).map((v, i) => (i + 1) * v)
}

1번 답안이 내가 하고자 했던 방향이랑 동일하다. 2번 답안은 n개를 x로 배열을 채우고 map으로...짱이다

콜라츠 추측

// 내 답안
function solution(num) {
    var answer = 0; 
    let a = num
    if(num === 1) return answer = 0
    for(let i = 1; i <= 500; i++) {
        a = a%2 ?  a * 3 + 1 : a / 2
        if(a === 1) return answer = i
        else answer = -1
    }
    return answer;
}

매개변수의 재할당을 지양해야한다. 매개변수를 담는 변수를 선언해줬다

// 다른 사람 답안
function collatz(num) {
    var answer = 0;
    while(num !=1 && answer !=500){
        num%2==0 ? num = num/2 : num = num*3 +1;
    answer++;
  }
    return num == 1 ? answer : -1;
}

while 조건문은 꽤 매력적인거 같다.

두 정수 사이의 합

// 내 답안
function solution(a, b) {
    let answer = 0;
    if(a === b) return answer = a
    if(a < b) {
        let x = a
        while(x <= b) {
            answer = answer + x
            x++
        }
    }
    else {
        let y = b
        while(y <= a) {
            answer = answer + y
            y++
        }
    }

    return answer;
}

내가 하고 싶던 로직은 밑에있는 로직인데..공부 더 하자

// 다른 사람 답안
function adder(a, b){
    var result = (a<b)?a:b;
    while(a!=b){
      result += (a<b)?++a:++b;
    }    
    return result;
}

서울에서 김서방 찾기

// 내 답안
function solution(seoul) {
    let location = null
    var answer = "";
    location = seoul.findIndex(item => item === "Kim")
    return answer = `김서방은 ${location}에 있다`;
}

굳이 findIndex로 함수 판별을 할 필요가 있을까 싶다.

//
function findKim(seoul){
  var idx = seoul.indexOf('Kim');
  return "김서방은 " + idx + "에 있다";
}

조금 더 간결하게 indexOf로 간단한 로직으로 돌리는게 훨씬 좋을 듯 하다

핸드폰 번호 가리기

// 내 답안
function solution(phone_number) {
    var answer = '';
    let a = phone_number.length - 4
    let b = phone_number.split("")
    let i = 0
    while(i < a) {
        b[i] = "*"
        i++
    }
    answer = b.join("")
    return answer;
}

문자를 찾아 바꾸는 것보다 문자의 순서를 기준으로 뒤에 4자리 빼고 모두 바꿔야겠다는 생각을 했다. 매개변수를 활용해서 만지작 거리기가 뭔가 답답했다.

// 다른 사람 답안
function hide_numbers(s){
  var result = "*".repeat(s.length - 4) + s.slice(-4);
  return result;
}

이 코드처럼 아에 매개변수는 부가적인 재료로만 쓰고 새롭게 내가 답을 만들어내는식도 좋은 방법인거 같다. slice 인수에 음수를 붙이면 반대부터 시작한다.

제일 작은 수 제거하기

// 내 답안
function solution(arr) {
    let answer = [...arr]
    if(arr.length === 1) return answer = [-1]
    let a = [...arr]
    let b = a.sort((x,y) => x-y)[0]
    answer.splice(arr.indexOf(b),1)
    return answer;
}

깊은 복사를 2번하고 최소값을 간접적으로 구했다는 게 아쉽다

// 다른 사람 답안
function solution(arr) {
    arr.splice(arr.indexOf(Math.min(...arr)),1);
    if(arr.length<1)return[-1];
    return arr;
}

Math.min을 사용해서 인덱스값을 구하고 지워주는 게 너무 좋다. 이런 문제에는 math 내장메서드를 잘 활용해보자

카카오 기출 Lv1

비밀지도

한시간 넘게 풀어봐도 답이 안나온다. 답이 안나온다는 의미는 마구잡이로는 해결할 수 있겠지만 질좋은 코드를 짜기위한 답이 안나온다는 의미다. for문 안에 for문이 있는것이 싫고 더나은 방법이 있는거 같은데 그게 내 머릿속에서 떠오르질 않는다.

그래서 답안지를 찾아봤다.

function solution(n, arr1, arr2) {
    return arr1.map((v,i)=>(v|arr2[i]).toString(2).padStart(n,'0').replace(/1|0/g, a => +a ? '#' : ' '));
}

OR 연산자, padStart 메서드, replace 정규식과 콜백 모두 낯설다...

OR연산자와 index값으로 변수 2개가 동시에 이뤄지도록 하고 padStart는 n개의 자리수가 되도록 '0'을 채워준다.

해설

숫자 문자열과 영단어

// 내 답안
function solution(s) {
    var answer = s;
    let num = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
    let i = 0
    while(i < num.length) {
        if(s.includes(num[i])) {
            let a = new RegExp(num[i], "g")
            answer = answer.replace(a, num.indexOf(num[i]))
        } 
        i++
    }
    return Number(answer);
}

영단어가 있는지 찾아서 있다면 num 배열 인덱스 번호로 바꾸는 로직을 짰는데 만약 같은 영단어가 2개 이상 있다면?에서 문제가 생겼다. 그래서 replace 정규식을 써봤는데 변수가 읽히지 않아서 변수가 읽히도록 RegExp를 썼다..뭔가 돌아돌아 해결한 느낌을 많이 받았다

// 다른 사람 답안 1
function solution(s) {
    let numbers = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
    var answer = s;

    for(let i=0; i< numbers.length; i++) {
        let arr = answer.split(numbers[i]);
        answer = arr.join(i);
    }

    return Number(answer);
}

// 다른 사람 답안 2
function solution(s) {
    s = s.replace(/zero/gi, 0)
    .replace(/one/gi, 1)
    .replace(/two/gi, 2)
    .replace(/three/gi, 3)
    .replace(/four/gi, 4)
    .replace(/five/gi, 5)
    .replace(/six/gi, 6)
    .replace(/seven/gi, 7)
    .replace(/eight/gi, 8)
    .replace(/nine/gi, 9)
    return parseInt(s);
}

너무 어렵게 생각하지 말자!

Lv2

카카오 기출 Lv2

주차 요금 계산

function solution(fees, records) {
    const parkingTime = {};
    records.forEach(r => {
        let [time, id, type] = r.split(' ');
        let [h, m] = time.split(':');
        time = (h * 1) * 60 + (m * 1);
        if (!parkingTime[id]) parkingTime[id] = 0;
        if (type === 'IN') parkingTime[id] += (1439 - time);
        if (type === 'OUT') parkingTime[id] -= (1439 - time);
    });
    const answer = [];
    for (let [car, time] of Object.entries(parkingTime)) {
        if (time <= fees[0]) time = fees[1];
        else time = Math.ceil((time - fees[0]) / fees[2]) * fees[3] + fees[1]
        answer.push([car, time]);
    }
    return answer.sort((a, b) => a[0] - b[0]).map(v => v[1]);
}
// 차량번호 오름차순으로 청구요금 담아 배열로 리턴

// 청구요금 구하기
// 기본요금 fee[1] + ( 주차시간 - 기본시간fee[0] ) / fee[2] * fee[3] 

// 기본시간이내 : 기본요금 
// 출차 시간 max = 23:59
// 분 단위는 올림

// 주차시간 구하기 
// records.forEach(r => r.split(' ')

// log 객체에 {차번호: 시간} 저장
// IN 이면 + (24시간(분) - 입차시간)
// OUT이면 -(1430 - 출차시간)
// 24시간 = 1440분

// ex) 05:34 (05 * 60) + 34 = 334

0개의 댓글