[TIL] 230522

먼지·2023년 5월 22일
0

TIL

목록 보기
54/57
post-thumbnail

프로그래머스 코테입문 Day 22 dp, 수학, 조건문, 배열

저주의 숫자 3

문제 설명

3x 마을 사람들은 3을 저주의 숫자라고 생각하기 때문에 3의 배수와 숫자 3을 사용하지 않습니다. 3x 마을 사람들의 숫자는 다음과 같습니다.

정수 n이 매개변수로 주어질 때, n을 3x 마을에서 사용하는 숫자로 바꿔 return하도록 solution 함수를 완성해주세요.

function solution(n) {
    let answer = 0;
    for(let i=1; i<=n; i++) {
        answer++
        while(String(answer).includes('3') || answer%3 === 0) {
            answer++
        }
    }
    return answer;
}

평행

풀지못해서 다른 사람 풀이 가져옴 ㅜㅜ 이번 주에 저 코드를 이해해야겠따

문제 설명
점 네 개의 좌표를 담은 이차원 배열 dots가 다음과 같이 매개변수로 주어집니다.

  • [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]
    주어진 네 개의 점을 두 개씩 이었을 때, 두 직선이 평행이 되는 경우가 있으면 1을 없으면 0을 return 하도록 solution 함수를 완성해보세요.
function solution(dots) {
  const getInclination = ([[x1, y1], [x2, y2]]) => (x2 !== x1 ? (y2 - y1) / (x2 - x1) : Infinity);
  const isParallel = (line1, line2) => getInclination(line1) === getInclination(line2);

  return dots.some(dot => {
    const line1 = [dots[0], dot];
    const line2 = dots.filter(dot => !line1.includes(dot));
    return isParallel(line1, line2);
  }) ? 1 : 0;
}

// 2
function solution(dots) {
    if (calculateSlope(dots[0], dots[1]) === calculateSlope(dots[2], dots[3]))
        return 1;
    if (calculateSlope(dots[0], dots[2]) === calculateSlope(dots[1], dots[3]))
        return 1;
    if (calculateSlope(dots[0], dots[3]) === calculateSlope(dots[1], dots[2]))
        return 1;
    return 0;
}

function calculateSlope(arr1, arr2) {
    return (arr2[1] - arr1[1]) / (arr2[0] - arr1[0]);
}

겹치는 선분의 길이

문제 설명
선분 3개가 평행하게 놓여 있습니다. 세 선분의 시작과 끝 좌표가 [[start, end], [start, end], [start, end]] 형태로 들어있는 2차원 배열 lines가 매개변수로 주어질 때, 두 개 이상의 선분이 겹치는 부분의 길이를 return 하도록 solution 함수를 완성해보세요.

lines가 [[0, 2], [-3, -1], [-2, 1]]일 때 그림으로 나타내면 다음과 같습니다.

선분이 두 개 이상 겹친 곳은 [-2, -1], [0, 1]로 길이 2만큼 겹쳐있습니다.

function solution(lines) {
    const start = lines.map(v => v[0]);
    const end = lines.map(v => v[1]);
    let count = 0;
    let answer = 0;
    for(let i = Math.min(...start); i <= Math.max(...end); i++){
        for(let j = 0; j < lines.length; j++){
            if(i >= start[j] && i < end[j]) count++;
        }
        if(count >= 2) answer++
        count = 0;
    }
    return answer;
}

// 다른 사람의 풀이
// start와 end에 해당하는 공간을 모두 채운 후에 두번 이상 채워진 건 겹쳐진 것이므로 그것의 갯수를 구한다!?
function solution(lines) {
    let line = new Array(200).fill(0);

    lines.forEach(([a, b]) => {
        for(; a < b; a++) line[a+100]++;
    });

    return line.reduce((a, c) =>  c > 1 ? a + 1 : a, 0)
}

유한소수 판별하기

문제 설명
소수점 아래 숫자가 계속되지 않고 유한개인 소수를 유한소수라고 합니다. 분수를 소수로 고칠 때 유한소수로 나타낼 수 있는 분수인지 판별하려고 합니다. 유한소수가 되기 위한 분수의 조건은 다음과 같습니다.

  • 기약분수로 나타내었을 때, 분모의 소인수가 2와 5만 존재해야 합니다.
    두 정수 a와 b가 매개변수로 주어질 때, a/b가 유한소수이면 1을, 무한소수라면 2를 return하도록 solution 함수를 완성해주세요.
function solution(a, b) {
     return Number((a/b).toFixed(10)) == a/b ? 1 : 2
}

// 다른 사람의 풀이
function solution(a, b) {
    let n = 1;
    for (let i = 1; i <= Math.min(a,b); i++) {
        if (a%i===0 && b%i===0) n = i;
    }

    b/=n;
    while (b%2===0) b/=2;
    while (b%5===0) b/=5;

    return b === 1 ? 1 : 2;   
}

리액트 공식문서 State: A Component's Memory

  • React에선 "use"로 시작하는 다른 함수를 훅(hook)이라고 부름
  • 훅은 React가 렌더링 중일 때만 사용할 수 있는 특별한 함수로 이를 통해 다양한 React 기능을 "연결"할 수 있게 해줌
  • Pitfall
    - 훅은 "컴포넌트 최상위 레벨 top level"(최상의 컴포넌트 x) 또는 "커스텀 훅"에서만 호출할 수 있음. 조건문, 반복문 또는 기타 중첩된 함수 내부에선 호출 불가능
  • useState를 호출하는 것은, 리액트에게 이 컴포넌트가 무언가를 기억하라 말하는 것
    - 컴포넌트가 렌더링 사이 일부 정보를 "기억"해야 할 때 state 변수를 사용함
  • 서로 연관이 없는 경우 여러 개의 state 변수를 갖는 것이 좋음.
  • 두 개의 state 변수를 자주 함께 변경하는 경우엔 두 변수를 하나로 합치는 것이 좋을 수 있음.
    - 예를 들어, 필드가 많은 폼의 경우 객체를 값으로 하는 하나의 state 변수를 사용하는 것!
  • 내부적으로 useState가 어떻게 작동하는지에 대한 아이디어
// index.js
let componentHooks = [];
let currentHookIndex = 0;

// How useState works inside React (simplified).
function useState(initialState) {
  let pair = componentHooks[currentHookIndex];
  if (pair) {
    // This is not the first render,
    // so the state pair already exists.
    // Return it and prepare for next Hook call.
    currentHookIndex++;
    return pair;
  }

  // This is the first time we're rendering,
  // so create a state pair and store it.
  pair = [initialState, setState];

  function setState(nextState) {
    // When the user requests a state change,
    // put the new value into the pair.
    pair[0] = nextState;
    updateDOM();
  }

  // Store the pair for future renders
  // and prepare for the next Hook call.
  componentHooks[currentHookIndex] = pair;
  currentHookIndex++;
  return pair;
}

function Gallery() {
  // Each useState() call will get the next pair.
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  function handleNextClick() {
    setIndex(index + 1);
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  // This example doesn't use React, so
  // return an output object instead of JSX.
  return {
    onNextClick: handleNextClick,
    onMoreClick: handleMoreClick,
    header: `${sculpture.name} by ${sculpture.artist}`,
    counter: `${index + 1} of ${sculptureList.length}`,
    more: `${showMore ? 'Hide' : 'Show'} details`,
    description: showMore ? sculpture.description : null,
    imageSrc: sculpture.url,
    imageAlt: sculpture.alt
  };
}

function updateDOM() {
  // Reset the current Hook index
  // before rendering the component.
  currentHookIndex = 0;
  let output = Gallery();

  // Update the DOM to match the output.
  // This is the part React does for you.
  nextButton.onclick = output.onNextClick;
  header.textContent = output.header;
  moreButton.onclick = output.onMoreClick;
  moreButton.textContent = output.more;
  image.src = output.imageSrc;
  image.alt = output.imageAlt;
  if (output.description !== null) {
    description.textContent = output.description;
    description.style.display = '';
  } else {
    description.style.display = 'none';
  }
}

let nextButton = document.getElementById('nextButton');
let header = document.getElementById('header');
let moreButton = document.getElementById('moreButton');
let description = document.getElementById('description');
let image = document.getElementById('image');
let sculptureList = [{
  name: 'Homenaje a la Neurocirugía',
  artist: 'Marta Colvin Andrade',
  description: 'Although Colvin is predominantly known for abstract themes that allude to pre-Hispanic symbols, this gigantic sculpture, an homage to neurosurgery, is one of her most recognizable public art pieces.',
  url: 'https://i.imgur.com/Mx7dA2Y.jpg',
  alt: 'A bronze statue of two crossed hands delicately holding a human brain in their fingertips.'  
}, ...];

// Make UI match the initial state.
updateDOM();
  • state 변수는 둘 이상 가질 수 있음. 내부적으로 React는 이를 순서대로 일치시킴
  • State is isolated and private
    - state는 화면의 컴포넌트 인스턴스에 지역적임 = 동일한 컴포넌트를 두 군데에서 렌더링 하면 각 사본은 완전히 격리된 state를 갖게 됨. 이 중 하나를 변경해도 다른 컴포넌트엔 영향을 미치지 않음
    • props와 달리 state는 이를 선언하는 컴포넌트 외에는 완전히 비공개이며, 부모 컴포넌트는 이를 변경할 수 없습니다.
  • 두 컴포넌트의 state를 동기화하려면 어떻게 해야 할까?
    - 자식 컴포넌트에서 state를 제거하고 가장 가까운 공유 부모 컴포넌트에 추가하는 것

Try out some challenges

import { useState } from 'react';
import { sculptureList } from './data.js';

export default function Gallery() {
  const [index, setIndex] = useState(0);
  const [showMore, setShowMore] = useState(false);

  let hasPrev = index > 0;
  let hasNext = index < sculptureList.length - 1;

  function handlePrevClick() {
    if (hasPrev) {
      setIndex(index - 1);
    }
  }

  function handleNextClick() {
    if (hasNext) {
      setIndex(index + 1);
    }
  }

  function handleMoreClick() {
    setShowMore(!showMore);
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button
        onClick={handlePrevClick}
        disabled={!hasPrev}
      >
        Previous
      </button>
      <button
        onClick={handleNextClick}
        disabled={!hasNext}
      >
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i> 
        by {sculpture.artist}
      </h2>
      <h3>  
        ({index + 1} of {sculptureList.length})
      </h3>
      <button onClick={handleMoreClick}>
        {showMore ? 'Hide' : 'Show'} details
      </button>
      {showMore && <p>{sculpture.description}</p>}
      <img 
        src={sculpture.url} 
        alt={sculpture.alt}
      />
    </>
  );
}
  1. Remove unnecessary state
// App.js
import { useState } from 'react';

export default function FeedbackForm() {
  function handleClick() {
    const name = prompt('What is your name?');
    alert(`Hello, ${name}!`);
  }

  return (
    <button onClick={handleClick}>
      Greet
    </button>
  );
}

state 변수는 컴포넌트의 리렌더링 사이에 정보를 유지하는 데만 필요합니다. 단일 이벤트 핸들러 내에서는 일반 변수로도 충분합니다. 일반 변수가 잘 작동할 때는 state 변수를 도입하지 마세요.

회고

아침에 Next.js 13이랑 테스트 혼자 공부하려다 뭐부터 시작해야 할지 막막해서 중간에 포기하구,, 공식문서 영어공부하면서 읽느라 오래 걸리고 코테풀고 팀 프로젝트 진행을 위해 디코에 팀원들 초대하고 인사 나누고 주제 정했다!!

아까 탐토님이랑 내가 지금껏 해온 고민인 "이게 맞나..? 뭘 해야 하지? 뭐가 올바른 방법이지?" 에 대해 얘기를 나눴다.

  • 처음할 땐 이게 맞는지 고민이 드는 질문을 하나씩 적기
  • 올바르게 하려고 하지 말기
  • 뭘 해야 하는지 모르겠다 = 이게 맞는 건지 모르겠다

결론

  • "관찰"을 잘 해야 함.
    - 관찰하는 법을 배우지 않으면 스스로 판단을 못하고 자꾸 남에게 검사를 받으려 하고,
    • 남도 정답을 아는 게 아니라 끝이 없음.
  • 나의 부족함과 실수를 받아들이고 하나씩 시도해보고, 궁금하거나 모르겠으면 질문
    - 실수를 못 받아들이고 아무 것도 안 하면 취업 안 됨..^^
    • 질문하는 게 두렵고 창피하고 미안하고.. 부담스러워서 혼자 끙끙 앓는 거에 익숙해졌었다ㅜㅜ 이젠 최대한 혼자 해결해보려고 하고 그래도 안 되면 꼭 물어봐야겠다
  • 편한 길인데 낯설어서 어렵다고 착각 -> 매일 조금씩 연습해라
  • 회사 간다고 많이 배우는 게 아님. 잘 관찰하고 개선하려 의식적으로 노력해야 성장

나의 궁극적인 문제는 "왜?" 라는 생각없이 공부해온 것. 이것말고도 많지만! 그동안 공부나 코딩을 할 때 내 주관보다는 뭐가 정답이지? 뭐가 완벽한 방법일까? 무언가 문제가 생기면 혼자 생각하기보다는 무조건 구글링하거나 주변에 잘한다고 생각하는 사람들의 코드만 따라하다 왜 그렇게 작성하는지 이해도 못하고 그러니 자꾸 포기하게 되고 혼란스러웠다ㅜㅜ

정말 고쳐야 할 게 많다. 이미 늦었다 생각해서 불안하고 조급하고 궁극적인 문제를 찾아 고치는 것이 먼저인지도 모르고 취업에 급급해 무조건 많이, 새롭고 인기 많은 기술을 배우거나, 배워야 한다니까.. 이런 외부 자극에만 집중한 채 오랜 시간을 허비했다.

많은 문제들을 더 늦기 전에 바로잡아야겠다. 스스로 생각하고 누군가에게 도움을 요청하는 것을 두려워하지 말기! 영어 공부도 기술 공부도 코딩도 다 첨부터 잘하려고 아등바등 힘 빼지 말고 일단 시도해야겠다. 완벽주의 k-정병에서 벗어나자 😂

profile
꾸준히 자유롭게 즐겁게

0개의 댓글