본 캠프

뉴스 피드 프로젝트. (2)

Iruka913 2024. 11. 18. 21:01

신나는 알고리즘 풀이 시간. 

두 정수 X, Y의 임의의 자리에서 공통으로 나타나는 정수 k(0 ≤ k ≤ 9)들을 이용하여 만들 수 있는 가장 큰 정수를 두 수의 짝꿍이라 합니다(단, 공통으로 나타나는 정수 중 서로 짝지을 수 있는 숫자만 사용합니다). X, Y의 짝꿍이 존재하지 않으면, 짝꿍은 -1입니다. X, Y의 짝꿍이 0으로만 구성되어 있다면, 짝꿍은 0입니다.

예를 들어, X = 3403이고 Y = 13203이라면, X와 Y의 짝꿍은 X와 Y에서 공통으로 나타나는 3, 0, 3으로 만들 수 있는 가장 큰 정수인 330입니다. 다른 예시로 X = 5525이고 Y = 1255이면 X와 Y의 짝꿍은 X와 Y에서 공통으로 나타나는 2, 5, 5로 만들 수 있는 가장 큰 정수인 552입니다(X에는 5가 3개, Y에는 5가 2개 나타나므로 남는 5 한 개는 짝 지을 수 없습니다.)
두 정수 X, Y가 주어졌을 때, X, Y의 짝꿍을 return하는 solution 함수를 완성해주세요.

 

나의 답(시간 초과)

function solution(X, Y) {
  let answer = ''
  let xArray = X.split('')
  let yArray = Y.split('')
  const commonArray = []
  for(let i = 0; i<xArray.length; i++) {
    if(yArray.includes(xArray[i])) {
      commonArray.push(xArray[i])
      const spliceIndex = yArray.findIndex((element) => element === xArray[i])
      yArray.splice(spliceIndex, 1)
    }
  }
  commonArray.sort((a, b) => b - a)
  answer = commonArray.join('')
  if(answer === '') {
    answer = '-1'
  }
  if(Number(answer) === 0) {
    answer = '0'
  }
  return answer;
}

 

로직은 얼추 맞는데, 시간 초과가 걸려서 몇 개인가의 문제가 오답 처리 되었다. 

function solution(X, Y) {
  const xCount = Array(10).fill(0); // X의 숫자 빈도
  const yCount = Array(10).fill(0); // Y의 숫자 빈도

  // X와 Y의 숫자 빈도 계산
  for (const digit of X) {
    xCount[digit]++;
  }
  for (const digit of Y) {
    yCount[digit]++;
  }

  const commonArray = [];
  // 공통 숫자의 최소 빈도만큼 결과에 추가
  for (let i = 9; i >= 0; i--) {
    const commonCount = Math.min(xCount[i], yCount[i]);
    if (commonCount > 0) {
      commonArray.push(String(i).repeat(commonCount));
    }
  }

  const answer = commonArray.join('');
  if (answer === '') {
    return '-1'; // 공통 숫자가 없을 때
  }
  if (Number(answer) === 0) {
    return '0'; // 결과가 0으로만 구성되어 있을 때
  }
  return answer;
}

 

이건 gpt의 답이다. 

 

for (const digit of X) {
  xCount[digit]++;
}

 

xCount는 X의 숫자의 빈도며, digit은 문자열 X의 각 문자다.

따라서, xCount[digit]++는 해당 숫자의 빈도를 1씩 증가시킨다. 

 

예를 들어서, X가 3403이라면? 

 

 

이렇게 설정된다. 

 

0은 한 번 나왔고, 3은 두번, 4는 1번 나왔기 때문에 저런 결과값이 나오게 되었다.

 

이렇게 Y의 빈도수도 똑같이 구한 다음, Math.min(xCount[i], yCount[i])를 사용해 두 배열에서 공통으로 등장한 숫자의 개수를 구한다. 그리고 이것이 0보다 클 경우에 commonArray에 추가하여, 공통된 값을 추가해준다. 

 

그 다음 이렇게 구한 값을 join으로 합쳐주면 정답이 된다. 

개인 프로젝트 / 로그인, 회원가입의 구현. 

이번에 로그인과 회원 가입 페이지를 맡게 되었다. 그렇게 되면서 자연스럽게 supabase의 auth 항목도 이것저것 건드리게 되었다. 

 

먼저, 

 

 

confirm 이메일 부분을 이렇게 체크 해제해야지, 회원 가입 시에 에러가 뜨지 않으며, 복수 시도했을 때 이메일 제한에 걸리지 않게 된다. 이 부분을 다음에는 꼭 체크하도록 하자. 

 

내가 회원가입 때 쓴 로직은 이렇다. 

 

const onSubmitHandler = async (e) => {
    e.preventDefault()
    if (!isAgreed) {
      alert('체크 박스를 확인해주세요.')
      return
    }
    const formData = new FormData(e.target)
    const nickname = formData.get('nickname').trim()
    const email = formData.get('email').trim()
    const password = formData.get('password').trim()
    if (!nickname || !email || !password) {
      alert('모든 필드를 입력해주세요.')
      return
    }
    try {
      const { data, error } = await supabase.auth.signUp({
        email,
        password,
      })
      if (error) throw error
      alert('회원가입에 성공했습니다!')
    } catch (error) {
      console.log('회원가입 실패:', error)
    }
    try {
      const { data, error } = await supabase
        .from('user')
        .insert([{ email, nickname }])
        .select()
      if (error) throw error
    } catch (error) {
      console.log( error)
    }
    e.target.reset()
    setIsAgreed(false)
  }

 

먼저 form이 submit되었을 경우, 간단한 validation 체크를 해준 다음, 회원가입 로직으로 넘어간다.

 

회원가입에선 try catch를 통해 에러를 판별하였다. 회원가입이 완료될 시, table에도 해당 정보를 넘겨줄 필요가 있었으므로, supabase의 insert로직을 써서 form으로 받아왔던 데이터를 table에 추가할 수 있도록 손을 써 두었다. 

 

const signUpHandler = () => {
    nav('/signup')
  }
  const loginHandler = async (e) => {
    e.preventDefault()
    const formData = new FormData(e.target)
    const email = formData.get('email').trim()
    const password = formData.get('password').trim()
    if (!email || !password) {
      alert('모든 필드를 입력해주세요.')
      return
    }
    try {
      const { data, error } = await supabase.auth.signInWithPassword({
        email,
        password,
      })
      if (error) throw error
      alert('로그인 성공!')
      nav('/')
    } catch (error) {
      console.log('로그인 실패!:', error)
    }
  }

 

다음은 로그인 로직이다. 아직은 미완성이긴 한데, 로그인 시에 로컬 스토리지에 키와 토큰이 제공되는 걸 확인할 수 있었다. 

 

 

이렇게 로컬 스토리지에 받아온 데이터를 기반으로, 로그인 여부를 판별하는 로직을 홈페이지, 마이페이지, 마이포스트에서 구현해주면 될 듯 하다.