프로그래머스 0단계 - 2진수 더하기

이종현·2024년 1월 5일
0

코딩테스트

목록 보기
6/24
post-thumbnail

문제 설명

이진수를 의미하는 두 개의 문자열 bin1과 bin2가 매개변수로 주어질 때, 두 이진수의 합을 return하도록 solution 함수를 완성해주세요.


제한사항

  • return 값은 이진수를 의미하는 문자열입니다.
  • 1 ≤ bin1bin2의 길이 ≤ 10
  • bin1과 bin2는 0과 1로만 이루어져 있습니다.
  • bin1과 bin2는 "0"을 제외하고 0으로 시작하지 않습니다.

입출력 예

bin1bin2result
"10""11""101"
"1001""1111""11000"

💡 문제 이해하기 → 접근 방법 → 코드 설계 → 코드 구현

1. 문제 이해하기

  • 이진수의 덧셈은 1 과 1을 더했을 때 10이 된다. 즉 1과 1을 더하면 가장 낮은 자리수는 0이되고 그 다음 자리수는 1과1을 더해서 올림된 1이 자리하게 되므로 최종적으로 10이 된다. 그럼 111 + 111은 1110이 된다.
  • 이진수의 값은 10자리를 넘지 않기 때문에 2^9의 값을 넘지 않는다.
  • 따라서 O(N^2)으로 문제를 풀어도 상관없다.

2. 접근 방법

  • 직관적으로 생각하기
    1. 두 개의 이진수 값을 십진수 값으로 바꿔서 더한뒤에 다시 그 십진수 값을 이진수로 변환하기
    2. 반복을 돌면서 진짜 이진수 처럼 덧셈하기? 반복은 두개의 이진수 중 가장 큰 수의 자리수만큼 반복하기

3. 코드 설계

  1. 첫 번째 방법
    • 문자열을 배열로 바꾼다음 reverse를 해서 위치를 변환한다.
    • 그 다음 for문으로 돌면서 순서대로 2^0 부터 2^n-1 까지 곱하면서 십진수를 구한다.
    • 두 개의 십진수를 더한다.
    • 십진수를 2로 나눈 나머지 값을 새로운 배열에 하나씩 담고 최종적으로 배열을 reverse해서 이진수를 구한다.
  2. 두 번째 방법
    • 정말 이진수의 덧셈을 하는 것처럼 각 자리수마다 발생하는 경우의 수에 대해서 숫자를 더하고 더한 수를 새로운 배열에 넣는다.
      • ‘0’ + ‘0’ 이면 ‘0’ 이고 ‘0’ + ‘1’ 이면 ‘1’ 이고 ‘1’ + ‘1’ 이면 ‘1’ 이면서 ‘1’을 그다음 자리수에 더할 수 있도록 한다.
    • 배열에 넣은 숫자를 join으로 최종적으로 문자열로 변환해서 답을 도출한다.

4. 코드 구현

두 번째 방법으로 일단 시도..

기본 테스트는 통과했으나, 최종적인 테스트는 통과하지 못했다. 테스트를 통과하지 못해서 두개의 숫자가 자리수가 다른 경우까지 고려해서 코드를 구현해봤으나, 역시 통과하지 못했다. 내 알고리즘이 커버하지 못하는 테스트 케이스가 있다는 것ㅜ

function solution(bin1, bin2) {
  const maxBinLength = Math.max(bin1.length, bin2.length)
  const bin1Arr = [...bin1].reverse()
  const bin2Arr = [...bin2].reverse()

  if (bin1Arr.length !== maxBinLength) {
    for (let i = 0; i < maxBinLength - bin1Arr.length; i++) {
      bin1Arr.push('0')
    }
  }

  if (bin2Arr.length !== maxBinLength) {
    for (let i = 0; i < maxBinLength - bin2Arr.length; i++) {
      bin2Arr.push('0')
    }
  }

  const resultArr = []
  let upNumber = '0'

  for (let i = 0; i < maxBinLength; i++) {
    console.log(Number(bin1Arr[i]) + Number(bin2Arr[i]) + Number(upNumber))
    if (Number(bin1Arr[i]) + Number(bin2Arr[i]) + Number(upNumber) === 0) {
      resultArr.push('0')
    } else if (
      Number(bin1Arr[i]) + Number(bin2Arr[i]) + Number(upNumber) ===
      1
    ) {
      console.log('11')
      resultArr.push('1')
    } else if (
      Number(bin1Arr[i]) + Number(bin2Arr[i]) + Number(upNumber) ===
      2
    ) {
      resultArr.push('0')
      upNumber = '1'
    } else if (
      Number(bin1Arr[i]) + Number(bin2Arr[i]) + Number(upNumber) ===
      3
    ) {
      resultArr.push('1')
      upNumber = '1'
    }
  }

  if (upNumber === '1') {
    resultArr.push('1')
  }

  return resultArr.reverse().join('')
}

그래서 다시 첫 번째 방법으로 시도했다.

이 방법은 크게 실패할 일이 없을 거라 생각했지만, ‘0’ + ‘0’ 일때의 경우의 수를 생각하지 못해서 마지막 즈음에 해당 조건을 넣어서 최종적으로 해결했다.

function solution(bin1, bin2) {
  const bin1Arr = [...bin1].reverse()
  let bin1Result = 0
  const bin2Arr = [...bin2].reverse()
  let bin2Result = 0

  for (let i = 0; i < bin1Arr.length; i++) {
    bin1Result += 2 ** i * Number(bin1Arr[i])
  }

  for (let i = 0; i < bin2Arr.length; i++) {
    bin2Result += 2 ** i * Number(bin2Arr[i])
  }

  const resultArr = []

  const sumResult = bin1Result + bin2Result
  let quotient = sumResult

  while (quotient !== 0) {
    resultArr.push(quotient % 2)
    quotient = Math.floor(quotient / 2)
  }

  if (bin1 === '0' && bin2 === '0') {
    resultArr.push('0')
  }

  return resultArr.reverse().join('')
}

다른 사람 풀이

parseInt로 2진수를 10진수로 변환한 다음에 더하고 최종적으로 toString으로 다시 2진수로 변환하는 코드..

function solution(bin1, bin2) {
  return (parseInt(bin1, 2) + parseInt(bin2, 2)).toString(2)
}

회고

이번건 바로 코드를 작성하기보다는 좀 더 생각해보고 접근하려고 노력했다. 하지만 그렇다고 해도 아직 생각하는 힘이 많이 부족한 것 같다.

profile
데이터리터러시를 중요하게 생각하는 프론트엔드 개발자

0개의 댓글