Algorithm

221027 [프로그래머스] :: 약수의 개수와 덧셈, 소수 만들기, 2개 이하로 다른 비트

kohi ☕ 2022. 10. 27. 23:12
약수의 개수와 덧셈
👾 문제 설명
두 정수 left와 right가 매개변수로 주어집니다. left부터 right까지의 모든 수들 중에서, 약수의 개수가 짝수인 수는 더하고, 약수의 개수가 홀수인 수는 뺀 수를 return 하도록 solution 함수를 완성해주세요.

👾 제한 사항
  • 1 ≤ left  right ≤ 1,000

 

👾 나의 답안

function solution(left, right) {
    let result = 0;

    for (let i = left; i <= right; i++) {
        if (divisors(i) % 2 == 0) {
            result += i;
        } else {
            result -= i;
        }
    }
    return result;

    function divisors(num) {
        let index = 1;
        let count = 0;

        while (index <= num) {
            if (num % index == 0) {
                count++;
            }
            index++;
        }
        return count;
    }
}

 

  • 약수의 개수를 구하는 함수 divisors를 만들고 호출해서 약수의 개수가 짝수면 더하고 홀수면 뺀다.

 

👾 다른 사람의 풀이

function solution(left, right) {
    var answer = 0;
    for (let i = left; i <= right; i++) {
        if (Number.isInteger(Math.sqrt(i))) {
            answer -= i;
        } else {
            answer += i;
        }
    }
    return answer;
}

 

  • 제곱근이 정수면 약수의 개수가 홀수다... 이런 거 볼 때마다 문과였던 게 분하고 원통함

 

소수 만들기
👾 문제 설명
주어진 숫자 중 3개의 수를 더했을 때 소수가 되는 경우의 개수를 구하려고 합니다. 숫자들이 들어있는 배열 nums가 매개변수로 주어질 때, nums에 있는 숫자들 중 서로 다른 3개를 골라 더했을 때 소수가 되는 경우의 개수를 return 하도록 solution 함수를 완성해주세요.

👾 제한 사항
  • nums에 들어있는 숫자의 개수는 3개 이상 50개 이하입니다.
  • nums의 각 원소는 1 이상 1,000 이하의 자연수이며, 중복된 숫자가 들어있지 않습니다.

 

👾 나의 답안

function solution(nums) {
    function isPrime(num) {
        if (num === 2) return true;

        for (let i = 2; i < num; i++) {
            if (num % i === 0) {
                return false;
            }
        }
        return true;
    }

    let count = 0;
    for (let i = 0; i < nums.length; i++) {
        for (let j = i + 1; j < nums.length; j++) {
            for (let k = j + 1; k < nums.length; k++) {
                if (isPrime(nums[i] + nums[j] + nums[k])) {
                    count++;
                }
            }
        }
    }
    return count;
}

 

  • 소수 판별 함수 isPrime을 호출해서 세 개의 값을 더한 값이 소수면 count++

 

2개 이하로 다른 비트

https://school.programmers.co.kr/learn/courses/30/lessons/77885

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

👾 제한 사항

  • 1 ≤ numbers의 길이 ≤ 100,000
  • 0 ≤ numbers의 모든 수 ≤ 1015

 

👾 나의 답안

function solution(numbers) {
    const result = [];
    numbers.forEach((el) => {
        if (el % 2 == 0) {
            result.push(el + 1);
        } else {
            const str = "0" + el.toString(2);
            const index = str.lastIndexOf("01");
            const bin = str.substring(0, index) + "10" + str.substring(index + 2, str.length);
            result.push(parseInt(bin, 2));
        }
    });
    return result;
}

 

  • 2진법으로 변환 시 짝수면 0으로 끝나니까 number에 1을 더해주면 됨. 여기까지 생각하니까 홀수인 경우도 뭔가 규칙이 있을 것 같은 느낌이 들어서 구글의 도움을 받음. 왠지 반복문으로 하나하나 돌리면 효율성 때문에 패스가 안 될 것 같았다.
  • 홀수인 경우 뒤에서부터 "01"을 찾아서 "10"으로 바꿔주면 된다고 함. 테스트 케이스 모두 깔끔하게 통과함

 

👾 다른 사람의 풀이

function solution(numbers) {
  var answer = [];
  let c;
  numbers.forEach(v => {
    if (v < 2 || v % 2 === 0) {
        answer.push(v+1);
    } else {
        let c = 2;
        while(true) {
            if ((v + 1) % (c * 2) === 0) {
                c = c * 2;
            } else {
                break;
            }
        };
        answer.push(v + (c / 2));
    }
  });
  return answer;
}

 

  • 코드 보면 접근 방식이 거의 다 비슷하던데 2진법 변환을 안 하고도 규칙성을 찾아내서 접근한 점이 좋았다.