본문 바로가기
활동/이노베이션 캠프

[테스트] 230622 알고리즘 테스트 풀이 - Chapter 2

by gardenii 2023. 6. 23.

1. 하 문제 - 문자열 뒤집어서 순서대로 더하기

function solution(n) {
  let nums = String(n).split("").reverse();
  let sum = 0;
  let result = "";

  nums.forEach((e, i) => {
    result += e;
    sum += Number(e);
    if (i < nums.length - 1) result += "+";
    else result += "=";
  });

  return result + sum;
}
console.log(solution(718253));

로직

1. 입력받은 숫자를 문자열로 바꾸어 문자 하나별로 나눠주고, reverse를 사용해 문자열을 앞뒤로 뒤집어 준 뒤 nums라는 새로운 배열로 저장합니다.
2. 덧셈 결과를 저장할 sum과 결과를 저장할 빈 문자열 result를 만들어줍니다.
3. nums를 forEach를 이용해 하나씩 순회하면서, result에는 요소 하나씩을 더해주고 sum에는 요소를 숫자로 변환한 값을 더해줍니다.
4. forEach의 현재 요소 인덱스 i가 nums 배열의 마지막 전 요소보다 작다면 result에 + 문자를 넣어주고, i가 마지막 요소라면 = 를 넣어줍니다.
5. result와 sum을 더한 값을 반환합니다.

2. 중 문제 - 정삼각형 별 찍기

function solution(star) {
  let result = "";
  const starNum = star * 2 - 1;

  for (let i = 1; i <= star; i++) {
    const spaceCount = star - i;
    const starCount = i * 2 - 1; 

    for (let j = 0; j < starNum; j++) {
      if (j < spaceCount || j >= starCount + spaceCount) result += " ";
      else result += "*";
    }
    result += "\n";
  }

  return console.log(result);
}

로직

1. 결과값을 담아줄 result 배열을 선언합니다.
2. starNum 변수에 줄 별로 출력될 수 있는 별의 최대 수를 구해 넣어줍니다. 이는 star값에서 2를 곱한 것에서 1을 뺀 값입니다. 줄이 하나씩 늘 때 마다 별의 최대 수는 2씩 증가합니다. 
3. 우선 줄 수만큼 바깥 for문을 돌려줍니다. 시작 수는 1입니다.
4. 줄 당 공백 수를 저장할 spaceCount를 선언합니다. 줄 당 앞 뒤의 공백 수는 줄 수에서 - i를 한 값입니다. 
5. 줄 당 별표 수를 저장할 starCount를 선언합니다. 줄 당 별표 수는 해당 줄 i * 2 - 1 입니다. 줄이 하나씩 늘 때 마다 별 수는 2씩 증가합니다.
6. 내부 for문을 통해 별의 최대 수 만큼 반복해주는데, 
7. j가 줄 당 공백 수보다 작거나 줄 당 공백 수와 줄 당 별표 수를 더한 값보다 같거나 클 때는 result에 공백을 넣어주고
8. 아니라면 별표를 result에 넣어줍니다.
9. 내부 for문이 끝날때마다 개행문자를 넣어주어 줄바꿈을 해줍니다.
10. 리턴값으로 result를 콘솔로 출력해줍니다. 

추가 코드

function solution20(n) {
  let str = "";
  for (let i = 0; i < n; i++)
    str += " ".repeat(n - (1 + i)) + "*".repeat(1 + i * 2) + "\n";
  return console.log(str);
}

3. 상 문제 - 이차원 배열의 원소 상하좌우 큰 값 찾기

function solution(arr1) {
  let answer = [];

  for (let i = 0; i < arr1.length; i++) {
    let result = [];
    for (let j = 0; j < arr1.length; j++) {
      let current = arr1[i][j];

      let up = i - 1 > -1 ? arr1[i - 1][j] : 0;
      let right = j + 1 < arr1.length ? arr1[i][j + 1] : 0;
      let down = i + 1 < arr1.length ? arr1[i + 1][j] : 0;
      let left = j - 1 > -1 ? arr1[i][j - 1] : 0;

      let biggest = [current, up, right, down, left].sort((a, b) => b - a);

      if (biggest[0] === current && biggest[0] > biggest[1]) result.push("*");
      else result.push(current);
    }
    answer.push(result.join(" "));
  }
  console.log(answer.join("\n"));
}

로직

1. 정답을 넣어줄 빈 배열 answer를 선언해줍니다.

2. 주어진 이차원 배열의 요소 하나하나를 순회하기 위해 이중 for문을 사용합니다. 이 때 주어진 행과 열이 같으므로 for문은 내부 외부 둘 다 주어진 배열의 길이만큼 반복합니다.

3. 외부 for문에 내부 for문에서 생성될 각 행들을 저장할 result 배열을 선언합니다.

4. 내부 for문 안에서 현재 원소의 위치를 의미하는 current를 선언하고 현재 위치 [i][j]를 저장합니다.

5. 문제에서 상하좌우 원소에서 유효한 값만 비교한다고 하였으므로, 각 상하좌우 변수에 삼항연산자를 사용하여 위치에 따른 인덱스 값이 배열에 존재하는지 확인하고, 존재한다면 각 변수에 넣어주고 아니라면 0을 넣어줍니다.

6. 여기서 유효한 인덱스 값은 -1 보다 크고, 배열의 총 길이인 5보다 작아야 합니다. 

7. 변수에 상하좌우 값을 모두 저장해주었다면, sort()를 통해 현재원소, 상하좌우 원소를 내림차순으로 정렬한 배열을 만들어줍니다.

8. 생성된 배열의 첫 요소는 가장 큰 값이므로 biggest[0] 과 현재 원소 값이 같고, 또한 현재 요소와 상하좌우가 가장 크면서 같은 값이 존재할 때는 현재 요소를 유지해야 하므로 가장 큰 값이 다음 큰 값보다 클 때, result 배열에 "*"을 넣어줍니다.

9. 아니라면 현재 값을 유지해야 하므로 result 배열에 현재 요소를 넣어줍니다.

10. 내부 for문이 끝나면 정답 배열을 넣어줄 answer배열에 만들어진 result배열을 공백 문자로 join하여 문자열 상태의 원소로 push해줍니다. 

11. 모든 과정이 끝나면 answer배열에 생성된 result 행들을 개행 문자로 join하여 반환해줍니다.