728x90

문제


https://programmers.co.kr/learn/courses/30/lessons/12924?language=javascript 

 

코딩테스트 연습 - 숫자의 표현

Finn은 요즘 수학공부에 빠져 있습니다. 수학 공부를 하던 Finn은 자연수 n을 연속한 자연수들로 표현 하는 방법이 여러개라는 사실을 알게 되었습니다. 예를들어 15는 다음과 같이 4가지로 표현 할

programmers.co.kr

 

코드


function solution(n) {
  let answer = 0; //정답이 될 변수
  let i = 1; //1부터 n까지 하나씩 오르는 변수
  while (i <= n) {
    let j = i; //현재 i를 copy
    let copy = n; //n을 copy
    while (copy > 0) {
      //copy 즉, n이 양수일 동안
      copy = copy - j; //연속된 수 j를 하나씩 빼주기
      j++; //ex) 15 = 15-1 -> 14 = 14-2 -> 12 = 12-3 -> 9 = 9-4 ...
    }
    i++; //i를 +1 해줘서 다음 수부터 연속되는 수에대해서 또 찾기
    if (copy === 0) answer++;
    //두번째 while문을 통해서 나온 copy가 0이라면 연속된 j 수들의 덧셈에 의해 0으로 떨어진 것이니 정답 +1
    else continue; //0으로 떨어지지 않았다면 i로 시작된 연속된 수는 n을 만들 수 없다는 의미니까 그냥 continue
  }
  return answer;
}

 

후기


  • 문제 유형이 적혀있진 않았지만 그리디 알고리즘을 생각하며 풀어보았다
  • i, j, n, copy 등 여러 변수들이 짧은 코드안에 복잡하게 등장했는데 각 쓰임새만 안 헷갈리면 쉽게 풀 수 있는 문제였다
  • 하지만 좀 더 효율적인 방법이 있을 것 같다..
728x90

문제


https://www.acmicpc.net/problem/1436

 

1436번: 영화감독 숌

666은 종말을 나타내는 숫자라고 한다. 따라서, 많은 블록버스터 영화에서는 666이 들어간 제목을 많이 사용한다. 영화감독 숌은 세상의 종말 이라는 시리즈 영화의 감독이다. 조지 루카스는 스타

www.acmicpc.net

 

코드


//실버5 영화감독 숌
const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
let input = fs.readFileSync(filePath).toString().trim().split("\r\n");

let end = 665; //종말의 수 처음인 666직전의 수로 초기화
input = input.shift(); //몇 번째 종말의 수를 찾을지

//input이 0이 아닐때까지
while (input > 0) {
  end++; //665에서 +1 씩 늘리면서
  if (String(end).includes("666")) input--; //"666"을 포함하는지 체크
}
console.log(end); //n번째 종말의 수 출력

 

후기


  • 나는 맨처음 이문제 접근을 규칙을찾자! 하고 규칙을 찾으려 했고.. 규칙같은 규칙을 찾았을 땐 실버5맞아이거? 왜이리어려워 했는데 이렇게 간단한 방법이 있었다.. 다른 분들의 풀이를 보고 역시 완전탐색은 어렵기도하고 또 단순히 생각해야 답이 나오는 것 같기도 하다
728x90

문제


https://www.acmicpc.net/problem/1018

 

1018번: 체스판 다시 칠하기

첫째 줄에 N과 M이 주어진다. N과 M은 8보다 크거나 같고, 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 보드의 각 행의 상태가 주어진다. B는 검은색이며, W는 흰색이다.

www.acmicpc.net

 

코드


//실버5 체스판 다시 칠하기
const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
let input = fs.readFileSync(filePath).toString().trim().split("\r\n");

//검정색이 맨처음 오는 경우
const blackFirst = [
  "BWBWBWBW",
  "WBWBWBWB",
  "BWBWBWBW",
  "WBWBWBWB",
  "BWBWBWBW",
  "WBWBWBWB",
  "BWBWBWBW",
  "WBWBWBWB",
];

//하얀색이 맨처음 오는 경우
const whiteFirst = [
  "WBWBWBWB",
  "BWBWBWBW",
  "WBWBWBWB",
  "BWBWBWBW",
  "WBWBWBWB",
  "BWBWBWBW",
  "WBWBWBWB",
  "BWBWBWBW",
];

const NM = input
  .shift()
  .split(" ")
  .map((i) => parseInt(i));
const N = NM.shift(); //세로길이(y축)
const M = NM.shift(); //가로길이(x축)
let arr = [];

function blackFirstPaint(y, x) {
  let count = 0; //몇 번이 바뀌는지 count할 변수

  //8x8행렬의 크기에 한해서 미리 선언해놓은 8x8 행렬과 같지 않은 부분은 count++
  for (let i = y; i < y + 8; i++) {
    for (let j = x; j < x + 8; j++) {
      if (input[i][j] !== blackFirst[i - y][j - x]) count++;
    }
  }
  return count;
}

function whiteFirstPaint(y, x) {
  let count = 0; //몇 번이 바뀌는지 count할 변수

  //8x8행렬의 크기에 한해서 미리 선언해놓은 8x8 행렬과 같지 않은 부분은 count++
  for (let i = y; i < y + 8; i++) {
    for (let j = x; j < x + 8; j++) {
      if (input[i][j] !== whiteFirst[i - y][j - x]) count++;
    }
  }
  return count;
}

//8x8모양이 체스판의 가로, 세로를 넘지않는 모든 경우에 대해
// i : y축(N), j : x축(M)
for (let i = 0; i + 7 < N; i++) {
  for (let j = 0; j + 7 < M; j++) {
    arr.push(blackFirstPaint(i, j)); //모든 경우의 수에 대해 count를 세본다
    arr.push(whiteFirstPaint(i, j));
  }
}
console.log(Math.min(...arr)); //모든 경우의 수 중에서 가장 작은 값을 return

 

후기


  • 정답이되는 체스판을 미리 선언해놓고 완전탐색을 통해 하나하나 비교하며 count++을 하였다
  • 다른 분들의 코드에 비해 그리 시간이나 메모리가 많이 잡아먹지는 않으나 좀 더 효율적인 방법이 있을 것 같긴하다
728x90

문제


https://www.acmicpc.net/problem/10820

 

10820번: 문자열 분석

문자열 N개가 주어진다. 이때, 문자열에 포함되어 있는 소문자, 대문자, 숫자, 공백의 개수를 구하는 프로그램을 작성하시오. 각 문자열은 알파벳 소문자, 대문자, 숫자, 공백으로만 이루어져 있

www.acmicpc.net

 

코드


//브론즈2 문자열 분석
const fs = require("fs");
const filePath = process.platform === "linux" ? "/dev/stdin" : "./input.txt";
let input = fs.readFileSync(filePath).toString().split("\r\n");
//다른 문제들과달리 input에 trim()을 빼주는 이유는 trim() 함수를 통해 빈 문자열이 없어지기 때문이다. 입력값으로 (의도적으로)빈 문자열이 들어온다면 trim()이 자동으로 없애주는 상황을 막아야 한다.

//빈 문자열이 주어졌을 경우에 대한 예외처리
let except = input.filter((str) => str.length < 1);
if (except.length) input.splice(input.indexOf(except[0]), 1);

//각 문자열에 대해 전체문자열 길이에서 정규식을 이용하여 각 조건에맞는 길이 빼주기
input.forEach((str) => {
  let lower = str.length - str.replace(/[a-z]/g, "").length;
  let upper = str.length - str.replace(/[A-Z]/g, "").length;
  let num = str.length - str.replace(/\d/g, "").length;
  let blank = str.length - str.replace(/\ /g, "").length;

  console.log(lower, upper, num, blank); //number형으로 각각 출력
});

 

후기


 

JS | trim() : 문자열 공백 제거

간단해보여도 알고리즘 문제를 풀 때 꼭 필요한 trim() 소개

velog.io

+ Recent posts