스터디 기록 18

유아현·2022년 12월 19일
0

Study

목록 보기
19/27
post-thumbnail

문제 목록

❤️‍🔥 올바른 괄호

function solution(s) {
  const start = '(';
  const end = ')';

  //! 시작이 "("로 시작하지 않으면 바로 false 리턴
  if (s[0] !== start || s.length < 2 || s.at(-1) !== end) return false;

  let cnt = 0;

  //! '('일 때 cnt++
  //! else =>  cnt가  0이라면 앞에 '('가 없다는 것이므로 바로 false 리턴
  //!          cnt--
  for (let i = 0; i < s.length; i++) {
    if (s[i] === start) cnt++;
    else {
      if (!cnt) {
        return false;
      }
      cnt--;
    }
  }

  //? 최종적으로 cnt가 0이면 true;
  return cnt === 0 ? true : false;
}
solution('()())(()');

처음에 여는 괄호로 시작해서 닫는 괄호로만 끝나면 되는 줄 알았던 문제... 왜 이렇게 쉬운지 의문이 들 때는 항상 내가 문제 이해를 잘못했던 것,,,, 바로 수정해서 최종으로 나온 코드이다. 효율성 문제 때문에 처음 if문에서 처음이나 끝이 여는 괄호, 닫는 괄호로 끝나지 않으면 바로 false를 리턴 시켜 줬다.

❤️‍🔥 이진 변환 반복하기

function solution(s) {
  let cnt = 0;
  let zero = 0;

  //! 한 글자가 남을 때까지 실행
  while (s > 1) {
    let len = s.length;
    //? s의 모든 0을 제거
    s = s.replaceAll('0', '');
    //? 처음 들어온 s의 길이 - 0을 제거한 후의 s의 길이를 zero에 누적
    zero += len - s.length;
    //? s의 길이를 2진법으로 표현
    s = s.length.toString(2);
    //? 이진 변환 횟수 cnt
    cnt++;
  }

  return [cnt, zero];
}

solution('110010101001');

한 글자가 남을 때까지 반복하는 정의를 수행시켜 주었다 나와 다르게 정규식을 통해서 풀어내신 동원님 코드가 기억에 남아 남기도록 하겠다 ㅎㅎ

function solution(s) {
    var answer = [];
    let round = 0;      // 실행한 회차
    let countzero = 0;    // 제거할 모든 0의 개수    

    const take1 = /[1]/g              // s에서 '1'만 가져오기
    const take0 = /[0]/g              // s에서 '0'만 가져오기      

    let delzero = 0;    // 제거할 0의 개수
    let num1 = 0;    // 0제거 후 값의 길이

    while(s.length !== 1){                    
            round++; // 반복문이 돌 때마다 round를 더해주기
            //* Step1. 제거할 0의 개수 구하기            
            // tmp에 0이 있다면 0의 개수를 반환
            if(take0.test(s)){                     // tmp에 0이 있다면
                delzero = s.match(take0).length;   // tmp의 0의 개수를 반환
            }else{
                delzero = 0; // tmp에 0이 없다면 제거할 0의 개수 0개로 선언
            }
            countzero += delzero; // 0을 제거한 개수

            //* Step2. 이진법화 하기위한 1의 개수 구하기
            num1 = s.match(take1).length;   // 1의 개수를 반환

            //* Step3. 가져온 1의 개수를 이진법화로 변환하기             
            s = num1.toString(2); // 1의 개수를 이진법화                        
    } 
    answer.push(round, countzero);    
    return answer;
}

❤️‍🔥 숫자의 표현

function solution(n) {
  // 자기 자신은 무조건 포함이니까 cnt는 1부터 시작
  let cnt = 1;

  // n의 절반 이상의 수는 조합 시 n을 무조건 넘으니까  n/2
  for (let i = 1; i <= n / 2; i++) {
    let sum = i;
    for (let j = i + 1; j <= n; j++) {
      sum += j;
      if (sum === n) cnt++;
      else if (sum > n) break;
    }
  }
  return cnt;
}

solution(15);

접근을 어떻게 해야 될지 고민했던 문제이다. 하나씩 살펴보다가 하나씩 조합해 보는 식으로 풀었다. 이 문제 또한 효율성 때문에 n의 절반만 구해도 될 것 같아서 절반만 구하는 식으로 했는데 스터디 코드 리뷰를 하면서 홀수 약수의 개수로도 구할 수 있다는 걸 알게 되었다 이와 더불어 민혁님이 발표하시는 걸 보면서 대단하는 말바꼐,,,, 약수에 접근하신 것부터가 넘 멋지다.

function getDivisors(n) {
    const result = [];
    const sqrt = Math.sqrt(n);
    for (let i = 1; i < sqrt; i++) {
        if (n % i === 0) result.push(i, n / i);
    }
    if (Number.isInteger(sqrt)) result.push(sqrt);
    return result.sort((a, b) => a - b);
}

// global n
const n = 15

// 1 확인
function tmp(n) {
    const divisors = getDivisors(n);
    // 합 n/d x d개 = n
    const result = [];
    divisors.forEach(d => {
        let arr = [];
        let D = n / d;
        // 1. d odd
        // d odd, D odd
        // d=3, D=7, n =21 -> 6,7,8
        // d odd, D even
        // d=5, D=4, n=20 -> 2,3,4,5,6
        if (d % 2 === 1) {
            for (let i = -Math.floor(d / 2); i <= Math.floor(d / 2); i++) {
                if (D + i < 1) break;
                arr.push(D + i);
            }
        }
        if (arr.length !== 0) result.push(arr);
        arr = [];
        // d even, D even
        // d=, D=, n=, -> 
        // d even, D odd
        // d=2, D=9, n=18 -> 3,4,5,6
        if (D % 2 === 1) {
            for (let i = -d; i < d; i++) {
                if (Math.ceil(D / 2) + i < 1) break;
                arr.push(Math.ceil(D / 2 + i));
            }
        }
        if (arr.length !== 0) result.push(arr);
    });
    return result;
}
console.log(tmp(n));

// 결국 divisors의 d에는 eachSum(=n/d)이 할당된다
// -> 두가지 케이스 합치기

// 2
function solution2(n) {
    let cnt = 0;
    const divisors = getDivisors(n);
    divisors.forEach(d => {
        let D = n / d;
        if (d % 2 === 1) {
            if (D - Math.floor(d / 2) >= 1) cnt++;
            if (Math.ceil(d / 2) - D >= 1) cnt++;
        }
    });
    return cnt;
}
console.log(solution2(n));

// 조건문 분석
// 그래프
// 3
function solution(n) {
    const divisors = getDivisors(n);
    return divisors.filter(d => d % 2 === 1).length;
}
console.log(solution(n));

0개의 댓글