작전명! 코딩테스트 대비하기 I(with codeSignal)

Haizel·2024년 3월 28일
1

🧬 알고리즘 풀이

목록 보기
53/53
post-thumbnail

프로젝트를 마무리하고, 본격적인 취업 준비를 시작하였다. 약 한 주 반동안 서류를 작성하고 운이 좋게도 곧바로 몇군데에서 면접 및 코테를 보게 되었다.

그래서 부트캠프를 하느라 잊고 있던 코테의 감을 깨우기 위해! 코테 준비를 해보려고 한다.
해당 코딩 테스트가 codeSignal에서 코딩테스트를 진행하기 때문에, 해당 플랫폼에서 연습 문제를 풀어보기로 했다.

codeSignal에 대해 잠시 소개하자면, 국내에선 프로그래머스 백준에 비해 다소 생소한 코딩 플랫폼이지만 실리콘밸리에서는 꽤나 유명한 코딩테스트 플랫폼이라고 한다.

연습 문제를 푸는 방법은 다음과 같다.

1. codeSignal에서 Arcade에 들어간다.

2. 원하는 코스를 선택한다. 처음 플랫폼을 이용하는 경우 Intro를 추천한다.

3. 아래처럼 여러 단계가 있고 순서대로 문제를 풀면 된다.

🔥 주의할 점!
각 단계별 문제는 차례대로 풀어야 한다.
즉, n번째 문제가 잘 풀리지 않는다고, n+1번째 문제로 뛰어넘기 할 수 없다 ☠️


1️⃣ The Journey Begins.

1. add

🔎 문제 해석

두 숫자의 합을 반환하는 함수를 작성하세요.

👩🏻‍💻 Success Code

function solution(param1, param2) {
    return param1 + param2;
}

2. centuryFromYear

🔎 문제 해석

  • 연도가 주어지면 해당 연도가 속한 세기를 반환합니다.
  • 1세기는 100년이 되는 해부터 100년이 되는 해까지, 2세기는 101년이 되는 해부터 200년이 되는 해까지 등입니다.

👩🏻‍💻 Success Code

function solution(year) {
    return Math.ceil(year/100);
}

3.checkPalindrome

🔎 문제 해석

  • 주어진 단어가 palindrome, 즉 거꾸로 읽어도 똑같은지, 확인하는 함수를 작성하세요.

👩🏻‍💻 Success Code

function solution(inputString) {
    const reverseStr = inputString.split("").reverse().join("");
    return inputString === reverseStr;
}

2️⃣ Edge of the Ocean

4. adjacentElementsProduct

🔎 문제 해석

정수의 배열이 주어졌을 때, 인접한 요소의 곱 중 가장 큰 곱을 갖는 요소의 쌍을 리턴하는 함수를 작성하세요.

👩🏻‍💻 Success Code

function solution(arr) {
    let maxDobble = 0;
    
    for (let i = 0; i < arr.length - 1; i++) {
        const currentDobble = arr[i] * arr[i + 1];
        if (maxDobble === 0) {
            maxDobble = currentDobble;
        }
        maxDobble = maxDobble > currentDobble ? maxDobble : currentDobble;
    }
    
    return maxDobble;
}

5. shapeArea

🔎 문제 해석

  • n-interesting 다각형의 면적을 찾는 문제
  • n-interesting 다각형은 n-interesting 다각형에 n-interesting 다각형을 그 둘레에 나란히 추가하여 만든다.
  • n-interesting 다각형의 면적을 구하는 공식은 다음과 같다.

🛠️ Test code

InputOutput
25
313

👩🏻‍💻 Success Code

function solution(n) {
    return n*n + (n-1)*(n-1);
}

6. Make Array Consecutive 2

🔎 문제 해석

  • 요소의 값인 정수인 배열이 주어졌을 때, 각 요소의 값이 정확이 1씩 증가하도록하려면 몇개의 요소가 최소 개수를 알아내는 함수를 작성하세요.

🛠️ Test code

InputOutput
[6, 2, 3, 8]3

✏️ 수도 코드

  • 1씩 커지는 배열을 만들려면 최소값과 최고값을 뺀 수의 +1을 한 값과 전체 배열의 length와 일치해야한다.

👩🏻‍💻 Success Code

function solution(statues) {
    const [minN, maxN] = [Math.min(...statues), Math.max(...statues)];
    const coudBeValue = maxN - minN + 1;
    
    return coudBeValue - statues.length;
}

7.almostIncreasingSequence

🔎 문제 해석

  • 정수로 이루어진 배열이 주어졌을 때, 최대 하나의 요소만 제거하여 1씩 증가하는 수열을 만들 수 있는지 확인하는 함수를 작성하세요.

✏️ 수도 코드

  1. removed 변수를 사용하여 제거된 원소의 수를 추적한다. (초기값 0)
  2. 반복문을 돌면서 아래 현재 요소(sequence[i])가 이전 요소(sequence[i-1])보다 작거나 같은 경우 다음을 수행한다. → removed 되는 조건을 확인
    a. removed 변수의 값을 1 증가 → 현재 원소가 조건을 만족하지 않아 제거됨을 의미
    b. 또한 현재 요소의 다음 요소(sequence[i+1])가 이전 요소(sequence[i-1])보다 작거나 같은 경우, 바로 false를 반환 → 이미 최대 한번이라는 기준을 위반했기 때문에
    c. 반복문을 돌면서 removed 변수의 값이 1을 초과한다면, 바로 false를 반환 → 마찬가지로 이미 최대 한번이라는 기준을 위반했기 때문에
  3. 반복문을 모두 실행한 후, true 반환

👩🏻‍💻 Success Code

function solution(sequence) {
    let removed = 0;
    
    for(let i = 0; i < sequence.length; i++) {
        if (sequence[i] <= sequence[i - 1]) {
            removed++;
            if (sequence[i] <= sequence[i-2] && sequence[i+1] <= sequence[i-1]) {
                return false;
            }
            // removed 1개 이하이면 true (= 1개만 제거했으면)
            if (removed > 1) return false;
        }
    }
    return true;
}

8.matrixElementsSum

👻 문제 해석

  • 각 값이 방의 비용을 나타내는 직사각형 정수 행렬인 매트릭스가 주어지면, 비용이 0 이상인 방의 비용을 모두 합산하는 함수를 작성하세요.

👩🏻‍💻 Success Code

function solution(matrix) {
    let totalPrice = 0; 
    
    for(let col = 0; col < matrix[0].length; col++) {
        for (let row = 0; row < matrix.length; row++) {
            if(matrix[row][col] === 0) {
                break;
            } else {
                totalPrice += matrix[row][col];
            }
        }
    }
    return totalPrice;
}

3️⃣ Smooth Sailing

9. All Longest Strings

🔎 문제 해석

  • 가장 길이가 긴 문자열을 모두 반환하는 함수를 작성하세요.

🛠️ Test code

InputOutput
["aba", "aa", "ad", "vcd", "aba"]["aba", "vcd", "aba"]

👩🏻‍💻 Success Code

function solution(arr) {
    const lengArr = arr.map(v => v.length)
    const maxLen = Math.max(...lengArr);
    const resultArr = arr.filter(v => v.length === maxLen)
    
    return resultArr;
    
}

10.commonCharacterCount

🔎 문제 해석

  • 두 문자열 s1과 s2에서 공통된 문자의 개수를 찾는 함수를 작성하세요.

✏️ 수도 코드

  1. 문자열에서 각 문자마다의 개수를 세는 함수인 getCharCount를 s1과 s2 각각 호출하여, 각 문자열의 문자별 등장 횟수를 세는 객체 형태를 만든다.
  2. 공통된 문자의 총 개수를 저장할 변수, commonChars를 0으로 초기화한다.
  3. s1Counts 객체의 키에 대해 반복문을 수행한다.
    a. 만약 현재 문자가 s2Counts 객체에도 존재하면 (문자열에 공통으로 등장하는 문자라면) → 두 문자열 중 해당 문자의 등장 횟수가 더 적은 쪽의 값(Math.min(s1Counts[char], s2Counts[char]))을 commonChars에 더한다.
  4. 반복문이 종료되면 공통된 문자의 총 개수를 나타내는 commonChars를 반환한다.

👩🏻‍💻 Success Code

//* 문자열에서 각 문자마다의 개수를 세는 함수
function getCharCount(s) {
    const result = [...s].reduce((acc, char) => {
    acc[char] = (acc[char] || 0) + 1;
    return acc;
    }, {});
    
    return result;
}

function solution(s1, s2) {
    const s1Counts = getCharCount(s1);
    const s2Counts = getCharCount(s2);
    let commonChars = 0;
    
    Object.keys(s1Counts).forEach(char => {
        // 만약 s2Counts에도 있으면
        if(s2Counts[char]) {
            // value 중 작은 값을 더한다.
            commonChars += Math.min(s1Counts[char], s2Counts[char]);
        }
    })
    return commonChars;
}

11. isLucky

🔎 문제 해석

  • 티켓 번호가 "행운의 번호"인지 아닌지를 판별하는 함수를 작성하세요.
  • 티켓 번호는 짝수 개의 숫자로 구성되며, 숫자들의 첫 번째 절반 합과 두 번째 절반 합이 같을 때 행운의 번호로 간주한다.

✏️ 수도 코드

  1. n의 자리수를 구해 자리수의 절반을 뜻하는 수를 변수, halfN에 할당한다.
  2. 반복문을 돌면서 현재 인덱스(i)가 halfN보다 작으면 firstSum에, 크거나 같으면 secondSum에 현재 값을 더한다.
  3. 두 값을 비교해 같다면 true, 다르다면 false를 반환한다.

👩🏻‍💻 Success Code

function solution(n) {
    const stringN = String(n);
    let [firstSum, secondSum] = [0, 0];  
    
    for(let i = 0; i < stringN.length; i++) {
    const halfN = stringN.length / 2;
        if (i < halfN) {
        firstSum += Number(stringN[i]);
        }
        else {
            secondSum += Number(stringN[i]);
        }
    }
    return firstSum === secondSum;
}

12. Sort by Height

🔎 문제 해석

  • 배열이 주어졌을 때, 나무를 제외한 사람들을 키 순으로 재배치하는 함수를 작성하세요.
  • 나무는 -1로 표현되며, 나무의 위치는 이동시킬 수 없다.

✏️ 수도 코드

  1. 사람들의 키만 추춘해 새로운 배열을 만들고 오름차순으로 정렬한다.
  2. 원본 배열을 순회하면서, 나무(-1)가 아닌 위치에 정렬된 키를 배치한다.

👩🏻‍💻 Success Code

function solution(a) {
    const people = a.filter(v =>  v !== -1).sort((a, b) => a - b);
    return a.map(value => value !== -1 ? people.shift() : value);
}

13. reverseInParentheses

🔎 문제 해석

  • 문자열 내의 괄호(및 중첩된 괄호) 안에 있는 문자들을 역순으로 만드는 함수를 작성하세요.

✏️ 수도 코드

  1. 가장 마지막 '('를 찾는다. (가장 안쪽 괄호 처리를 위해)
  2. start '('에 해당하는 ')'를 찾는다.
  3. 괄호 안의 문자열을 역순으로 뒤집는다.
  4. 원래 문자열에서 해당 괄호 부분을 뒤집은 문자열로 교체한다.

👩🏻‍💻 Success Code

function solution(input) {
    while(input.includes("(")) {
        let start = input.lastIndexOf("(");
        let end = input.indexOf(")", start);
        let reverseInput = input.substring(start + 1, end).split('').reverse().join('');
        input = `${input.slice(0, start)}${reverseInput}${input.slice(end + 1)}`
    }
    return input;
}

4️⃣ Exploring the Waters

14. alternatingSums

🔎 문제 해석

  • 사람들의 몸무게가 담긴 배열이 주어질 때, 다음 규칙에 따라 2팀으로 분류하여 각 팀의 무게를 합산한 배열을 반환하는 함수를 작성하세요.
  • 규칙 : 첫 번째 사람은 팀 1, 두 번째 사람은 팀 2, 세 번째는 다시 팀 1, 네 번째는 팀 2로..를 반복합니다.

🛠️ Test code

InputOutput
[50, 60, 60, 45, 70][180, 105]

👩🏻‍💻 Success Code

function solution(a) {
    let [odd, even] = [0, 0];
    
    for(let i = 0; i < a.length; i++) {
        if (i % 2 === 1) {
            odd += a[i];
        } else {
            even += a[i];
        }
    }
    return [even, odd];
}

15. Add Border

🔎 문제 해석

🛠️ Test code

InputOutput
["abc","ded"]]["****", "*abc*", "*ded*", "****"]

✏️ 수도 코드

  1. 각 문자열의 길이를 기준으로 위, 아래 테두리를 만든다.
  2. 배열의 각 요소 앞 뒤로 '*'를 추가한다.
  3. 1번과 2번을 합친 배열을 만들고 리턴한다.

👩🏻‍💻 Success Code

function solution(picture) {
    const border = '*'.repeat(picture[0].length + 2);
    const addBorderToPicture = picture.map(letter => `*${letter}*`);
    const borderedPicture = [border, ...addBorderToPicture, border];
    
    return borderedPicture
}

16. Are Similar?

🔎 문제 해석

  • 두 배열이 주어질 때, 최대 한 쌍의 원소를 서로 바꿔 같은 배열이 된다면 유사배열이 된다.
  • 주어진 두 배열, a와 b가 위 조건을 만족하는지 판별하는 함수를 작성하세요.

✏️ 수도 코드

  1. 두 배열의 길이가 다르면 바로 false를 반환한다.
  2. a 배열과 b 배열에서 값이 다른 원소들의 인덱스를 찾아 diffIndexes 배열에 저장한다.
  3. true가 되는 2가지 조건을 확인한다. (OR)
    a. diffIndexes의 길이가 0이면 배열이 이미 같으므로 true를 반환한다.
    b. 길이가 2이며 해당 인덱스에 있는 값들이 서로 교차하여 일치한다면 true를 반환한다.
  4. 위 조건을 충족하지 않으면 false를 반환한다.

👩🏻‍💻 Success Code

function solution(a, b) {
   // 
   if (a.length !== b.length) return false;
   
   // 
   const diffIndexes = a.map((value, i) => value !== b[i] ? i : -1).filter(index => index !== -1);
   if (diffIndexes.length === 0) return true;
   if (diffIndexes.length === 2) {
       if (a[diffIndexes[0]] === b[diffIndexes[1]] && a[diffIndexes[1]] === b[diffIndexes[0]]) return true;
   }
   return false;
}

profile
한입 크기로 베어먹는 개발지식 🍰

0개의 댓글