스터디 기록 19

유아현·2022년 12월 23일
0

Study

목록 보기
20/27
post-thumbnail

문제 목록

❤️‍🔥 피보나치 수

function solution(n) {
  // 1. num만큼 for문을 돌린다.
  // 2. 피보나치 배열을 만든다.
  // 3. 배열의 마지막 요소를 1234567로 나눈 나머지를 구한다.

  let first = 0;
  let second = 1;
  let sum = 0;
  let arr = [0, 1];
  ㅁ;

  //! 피보나치 배열을 만든 후, 마지막 요소로 1234567로 나눈 몫을 리턴
  for (let i = 1; i < n; i++) {
    sum = first + (second % 1234567);
    first = second % 1234567;
    second = sum;
    arr.push(sum % 1234567);
  }
  console.log(arr);
  console.log(arr.at(-1));
  result = arr.at(-1) % 1234567;
  console.log(result);
  return result;
}

solution(3);

arr에 피보나치로 구한 수들을 push를 그냥 sum을 넣어 줬더니 큰 숫자의 연산 처리 때문에 시간 초과가 났었다... 그래서 push 해 줄 때 애초에 1234567로 나눈 수를 넣어서 리턴해 주었다 근데 지금 보니 result에 또 나누어줄 필요는 없엇는데.... 1234567보다 큰 수가 들어올 일이 없어서 통과가 됐었나 보다!

function solution(num) {
  const fib = [0n, 1n];
  for (let i = 2; i <= num; i++) {
    fib.push(fib.at(-1) + fib.at(-2));
  }
  return Number(fib[num] % 1234567n);
}

민혁님의 코드, 위에서 내가 언급했던 것과 같이 큰 숫자 연산 처리에 대한 해답을 민혁님이 들고 오셨다 ㅎㅎ BigInt를 통해서 최대치 2^53 - 1보다 큰 정소를 표혈할 수 있는 내장 객체라고 한다. BigInt를 사용하기 위해서는 정수 뒤에 n을 붙이거나 BigInt()를 호출해서 사용하면 된다.

[BigInt]

// 사용 방법 1 | 정수 리터럴 뒤에 n 붙이기
const BiggerInt = 954321564721231n;

// 사용 방법 2 | BigInt() 호출
const BiggerInt = Bigint(954321564721231);


// 참고 | BigInt의 typeof 판별 시, bigint로 나온다는 점도 기억하자.
typeof 1n === 'bigint'; // true
typeof BigInt('1') === 'string' // false;

❤️‍🔥 다음 큰 숫자

🤔 실패 코드(시간 초과)

function solution(n) {
  //? 1. n 다음 큰 숫자는 n보다 커야한다
  //? 2. n 다음 큰 숫자와 n은 2진수 변환 시 1의 갯수가 같다
  //? 1, 2를 만족하는 가장 작은 수
  //! n을 돌리면서 조건 만족하면 바로 리턴

  //? 처음 자연수 n의 2진수 변환 시 1의 갯수
  const nBinaryCnt = n.toString(2).match(/[1]/g).length;
  console.log(nBinaryCnt)

  //? 다음 큰 숫자의 2진수 변환 시 1의 객수
  let nextNumBinaryCnt = 0;

  //? 다음 큰 수는 n보다 커야 하므로 n++ 시킨 값부터 시작
  n++;
  while(n){
    nextNumBinaryCnt = n.toString(2).match(/[1]/g).length; 
    //? 처음 자연수 n과 다음 큰 숫자의 2진수 변환 시 1의 갯수가 같으면 n 리턴
    if(nextNumBinaryCnt === nBinaryCnt){
      console.log(n)
      return n;
    }
    n++
  }
}

solution(15)

while문 안에서 정규식을 써서... 그런 줄 알았더니 효근님 코드를 보니 while문 내의 정규식과 match의 문제는 전혀 아니었다. 연산 처리를 몇 번 중간중간 추가 시켜 준 게 문제였다 내 코드에서 while문을 돌기 전에 n을 증감해 주고 돌게 해 주고 내부에서 while문을 실행하면서 안에서 또 증감문을 사용했다 그냥 처음에 증감 시켜 주는 식으로 해도 됐었는데... 앗콩 실수.... 그래서 나온 정답 코드!!

function solution(n) {
  //? 1. n 다음 큰 숫자는 n보다 커야한다
  //? 2. n 다음 큰 숫자와 n은 2진수 변환 시 1의 갯수가 같다
  //? 1, 2를 만족하는 가장 작은 수
  //! n을 돌리면서 조건 만족하면 바로 리턴

  //? 처음 자연수 n의 2진수 변환 시 1의 갯수
  const nBinaryCnt = n.toString(2).split("1").length;

  //? 다음 큰 숫자의 2진수 변환 시 1의 객수
  let nextNumBinaryCnt = 0;

  //? 다음 큰 수는 n보다 커야 하므로 n++ 시킨 값부터 시작
  while(n){
    n++
    nextNumBinaryCnt = n.toString(2).split("1").length; 
    //? 처음 자연수 n과 다음 큰 숫자의 2진수 변환 시 1의 갯수가 같으면 n 리턴
    if(nextNumBinaryCnt === nBinaryCnt){
      return n;
    }
  }
}

solution(78)

match 대신 split으로 바꿔 주고 while 안에서 n을 증감식을 해 준 식으로 고쳤더니 깔끔하게 통과 됐다!

❤️‍🔥 카펫

function solution(brown, yellow) {
  const sum = brown + yellow;
  // 노란색은 무조건 중앙
  //! 갈 갈 갈
  //! 갈 노 갈
  //! 갈 갈 갈

  // 가로, 세로 길이는 최소 3
  for (let height = 3; height <= brown; height++) {
    // yellow는 양옆 위아래 모두 brown이 테두리를 감싸고 있기 때문에
    // 노란색 카펫의 가로 세로 길이
    // 전체 가로 세로 길이 각각 -2 해서 곱한 게 yellow랑 같으면 가로, 세로 리턴
      if ((sum / height - 2) * (height - 2) === yellow) {
        console.log([sum/height, height])
          return [sum/height, height]
      }
  }
}

solution(10, 2)

이 문제는... 정답률이 68퍼나 되는데 나한테 왜 이렇게 어렵게 느껴졌는지,,, 정말이지 수학에 약한가보다......... 아닌가? 수학만이 문제는 아닌듯 ㅎㅎ 일단 보자마자 아 이건... 어떤 공식을 이용해서 풀어야한다는 것만은 분명히 인지하고 있었다 근데 전 수학 몬한단말이에여... 아무튼 그림도 여러번 그려보면서 이해한 결과 노란색은 무조건 가운데에 고정이고 가운데 노랑의 면적이 어떻게 배치되냐가 핵심이라고 생각했다. 노란색은 무조건 1 이상이므로 3 * 3 크기의 정사각형 카펫이 최소 크기라는 말로 이해했다. 그래서 최소 길이인 높이 3부터 시작해서 brown까지 돌리게 했고 갈색 노랑 모두 더한 값에 높이를 나누고 -2를 한 게 노랑의 가로, 높이에서 2를 때면 노랑의 면적이 나오겠다고 생각했다. 여기서 -2는 노랑을 감싸고 있는 양옆 위아래 갈색을 의미한다. 그렇게 해서 나온 면적이 매개변수로 받은 노랑과 같다면 해당 가로, 세로 크기를 리턴 시켜 주었다.

0개의 댓글