Language/JavaScript

코딩테스트 연습 ~10 JavaScript

Tarel 2022. 9. 24. 18:54

 

지난번에 올린 코딩테스트 연습의 연장이다.

 

문제설명 -> 제한 조건  -> 최초 답안 -> 개선 답안 -> 다른사람이 작성한 모범답안

 

순서대로 진행한다.


문제설명

두 정수 a, b가 주어졌을 때 a와 b 사이에 속한 모든 정수의 합을 리턴하는 함수, solution을 완성하세요.
예를 들어 a = 3, b = 5인 경우, 3 + 4 + 5 = 12이므로 12를 리턴합니다.

 

제한 조건

a와 b가 같은 경우는 둘 중 아무 수나 리턴하세요.
a와 b는 -10,000,000 이상 10,000,000 이하인 정수입니다.
a와 b의 대소관계는 정해져있지 않습니다.

 

최초 답안

function solution(a, b) {   
    if (a > b){
        let c = a-b;
        let d = b
        for (i = 0; i <c; i++){
            d = d+1;
            b = b+d;
        }        
        return b;
    }
    if (a < b){
        let c = b-a;
        let d = a
        for (i = 0; i <c; i++){
            d = d+1;
            a = a+d;
        }
        return a;        
    }
    if(a=b) return a;
}

길다....

 

개선 답안

 

 

타인이 작성한 모범답안

function solution(a, b){
    return (a+b)*(Math.abs(b-a)+1)/2;
}

 

모범답안을 볼 때마다 느끼는 거지만 이러한 수학적 계산이 필요한 문제에선

Math와 삼항연산자의 영향력이 크게 미치는 것 같다.

지금까지 나는 사실상 4칙연산 하나만 가지고 푸는 격이었기에

Math에 대한 공부의 필요성을 느끼게 된다.

 

 

 


문제설명

문자열 s를 숫자로 변환한 결과를 반환하는 함수, solution을 완성하세요.

예를들어 str이 "1234"이면 1234를 반환하고, "-1234"이면 -1234를 반환하면 됩니다.
str은 부호(+,-)와 숫자로만 구성되어 있고, 잘못된 값이 입력되는 경우는 없습니다.

 

 

제한 조건

  • s의 길이는 1 이상 5이하입니다.
  • s의 맨앞에는 부호(+, -)가 올 수 있습니다.
  • s는 부호와 숫자로만 이루어져있습니다.
  • s는 "0"으로 시작하지 않습니다.

최초 답안

function solution(s) {
    return parseInt(s);
}

개선 답안

 

타인이 작성한 모범답안

function solution(s) {
    return s/1;
}

형 변환 명령없이 그저 1로 나누라는 명령 하나만으로 자연스럽게 형변환을 했다.


문제설명

0부터 9까지의 숫자 중 일부가 들어있는 정수 배열 numbers가 매개변수로 주어집니다. numbers에서 찾을 수 없는 0부터 9까지의 숫자를 모두 찾아 더한 수를 return 하도록 solution 함수를 완성해주세요.

 

입출력 예 #1
5, 9가 numbers에 없으므로, 5 + 9 = 14를 return 해야 합니다.

 

제한 조건

1 ≤ numbers의 길이 ≤ 9
0 ≤ numbers의 모든 원소 ≤ 9
numbers의 모든 원소는 서로 다릅니다.

최초 답안

function solution(numbers) {
    let result = 0;
    for (i = 0; i < 10; i++){
        if (numbers.includes(i)){  
        }else{
            result += i
        }        
    }
    return result;
}

.includes()

괄호안의 파라미터를 포함하는지에 대한 여부를 묻는다.

개선 답안

 

타인이 작성한 모범답안

function solution(numbers) {
    return 45 - numbers.reduce((cur, acc) => cur + acc, 0);
}

여기서 45는 0에서 9까지의 합으로 보인다.

acc와 cur은 변수명이 바뀌었다고 하는데 좀 더 알아봐야겠다.


문제설명

어떤 정수들이 있습니다. 이 정수들의 절댓값을 차례대로 담은 정수 배열 absolutes와 이 정수들의 부호를 차례대로 담은 불리언 배열 signs가 매개변수로 주어집니다. 실제 정수들의 합을 구하여 return 하도록 solution 함수를 완성해주세요.

 

입출력 예 #1
signs가 [true,false,true] 이므로, 실제 수들의 값은 각각 4, -7, 12입니다.
따라서 세 수의 합인 9를 return 해야 합니다.

 

제한 조건

absolutes의 길이는 1 이상 1,000 이하입니다.
absolutes의 모든 수는 각각 1 이상 1,000 이하입니다.
signs의 길이는 absolutes의 길이와 같습니다.
signs[i] 가 참이면 absolutes[i] 의 실제 정수가 양수임을, 그렇지 않으면 음수임을 의미합니다.

 

최초 답안

function solution(absolutes, signs) {    
    const l = absolutes.length;
    let a = 0;    
    for (i = 0 ; i<l; i++){
        (signs[i]==true ? a += absolutes[i] : a -= absolutes[i])
    } 
    return a;
}

삼항 연산자를 사용해 보았다.

확실히 코드가 줄었다.

 

개선 답안

 

타인이 작성한 모범답안

function solution(absolutes, signs) {
    return absolutes.reduce((acc, val, i) => acc + (val * (signs[i] ? 1 : -1)), 0);
}

이번엔 화살표 함수가 사용된 것을 볼 수 있다.


문제설명

정수를 담고 있는 배열 arr의 평균값을 return하는 함수, solution을 완성해보세요.

 

제한 조건

arr은 길이 1 이상, 100 이하인 배열입니다.
arr의 원소는 -10,000 이상 10,000 이하인 정수입니다.

최초 답안

function solution(arr) {
    let a = 0;
    let b = 0;
    for(let i = 0; i < arr.length ; i++){
        a += arr[i]
        console.log(a)
        b = a/arr.length
    }
    return b
}

길다.... 정말로...

개선 답안

타인이 작성한 모범답안

function average(arr){
  return arr.reduce((a, b) => a + b) / arr.length;
}

문제설명

프로그래머스 모바일은 개인정보 보호를 위해 고지서를 보낼 때 고객들의 전화번호의 일부를 가립니다.
전화번호가 문자열 phone_number로 주어졌을 때, 전화번호의 뒷 4자리를 제외한 나머지 숫자를 전부 *으로 가린 문자열을 리턴하는 함수, solution을 완성해주세요.

 

제한 조건

phone_number는 길이 4 이상, 20이하인 문자열입니다.

최초 답안

function solution(phone_number) {
    const leg = phone_number.length - 4;
    let a = ""
    let b = phone_number.substring(leg, phone_number.length)
    let answer = ""
    for(let i = 0 ; i < leg ; i++){
        a = a + "*"
    }
    answer = a + b
    return  answer;
}

 

 

꽤나 어려웠다.

스트링을 조작하는 메소드에 대해 잘 모르다보니 꽤 오랜시간 고민한거 같다.

 

그나저나 이쯤되니 내가 너무 조건문과 반복문에 의지하는 코딩을 하고 있는게 아닌가 싶은 생각이 든다.

개선 답안

 

타인이 작성한 모범답안

 

function hide_numbers(phone_number) {
  return phone_number.replace(/\d(?=\d{4})/g, "*");
}

이건 또 뭔 내용일까....

사람들 반응을 보니 정규식이라는거 같은데... 좀 더 나중에 알아도 될 법한 내용이지 않을까 싶다.

 

 

 

function hide_numbers(phone_number){
  var result = "*".repeat(phone_number.length - 4) + phone_number.slice(-4);
  return result;
}

이쯤되면 자괴감이 들기 시작한다.

 

왜이리 다들 짧고 간단하게 문제를 푸는가

 

 


문제설명

행렬의 덧셈은 행과 열의 크기가 같은 두 행렬의 같은 행, 같은 열의 값을 서로 더한 결과가 됩니다. 2개의 행렬 arr1과 arr2를 입력받아, 행렬 덧셈의 결과를 반환하는 함수, solution을 완성해주세요.

 

제한 조건

행렬 arr1, arr2의 행과 열의 길이는 500을 넘지 않습니다.

 

최초 답안

function solution(arr1, arr2) {    
    const array = []
    
    for(i=0; i<arr1.length; i++){
    let arr = []
        for(j=0; j<arr2.length; j++){            
            let a = 0;
            a = arr1[i][j]+arr2[i][j]
            if (isNaN(a)==true) {
                continue;
            }
            arr.push(a)
        }
        array.push(arr)
        arr = []
    }    
    return (array);
}

처음으로 오답이 났다.

테스트를 통과했고

테스트 케이스에 더러운 값을 추가했음에도 불구하고

막상 채점을 하자 반 정도에서 탈락해고 오답처리 당했다.

 

문제는 대체 어디가 문제인지 모르겠다는 것이다. 

개선 답안

function solution(arr1, arr2) {       
    const array = []  
    for(i=0; i<arr1.length; i++){
    let arr = []        
        for(j=0; j<arr2[i].length; j++){            
            arr.push(arr1[i][j]+arr2[i][j])
        }
        array.push(arr)
        arr = []
    }    
    return (array);
}

그리하여 개선한 답안

차이점이라면 let a를 쓰는 것 대신에 그냥 array에 직접 푸쉬를 해주는 형태로 바꾸면서 자연스럽게 NaN을 판별하는

if문이 사라졌다.

 

그러나 이건 그저 코드길이 몇개 줄여주는 정도에서 끝이고 중요한건 아니다

 

가장 중요한건 바로 두 번째 for문의 조건문에서 [i]가 추가된 것이다.

 

arr2 행렬에서 행의 번호의 길이를 가져오는 것이다.

 

즉 테스트케이스에선 행의 길이에서 차이가 있었던 부분이 있던 모양이다.

 

타인이 작성한 모범답안

function solution(arr1,arr2){
    return arr1.map((a,i) => a.map((b, j) => b + arr2[i][j]));
}

 

......

이쯤되면 나는 코딩에 재능이 없는 건가 싶은 생각만 든다.

 

대체 저 map이라는 명령은 또 뭐란 말인가.

 


정리

Math

map

.reduce를 포함한 텍스트 조작명령

 

이렇게 3가지에 대해서 제대로 공부를 하고

 

삼항연산자

화살표함수

이 두가지 또한 익숙해질 필요가 있음을 느꼈다.