[알고리즘]프로그래머스 0단계 뽀개기(Day22)

HIHI JIN·2023년 4월 11일

알고리즘

목록 보기
25/29
post-thumbnail

Day 22

유한소수 판별하기

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

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

//내 코드
function solution(a, b) {
    //2~b까지의 최대공약수 구하기
    let num=0;
    for(let i=2; i<b; i++){
        if(a%i===0 && b%i===0){
            num = i;
        }
    }
    //최대공약수로 분모 나눠서 새로운숫자에 담기
    //최대공약수가 없다면 새로운 숫자에 b 담기
    let newNum = 0;
    if(num!==0) {
        newNum = b/num;
    }
    else newNum = b;
    
    //newNum이 2로 나누어떨어지면 계속 2로 나누기
    //newNum이 5로 나누어떨어지면 계속 5로 나누기
    //마지막에 newNum=1이라면 유한소수가 된다.
    while(newNum%2===0){
        newNum = newNum/2;
    }
    while(newNum%5===0){
        newNum = newNum/5;
    }
    return newNum===1 ? 1:2;
}

//다른 사람 코드
function solution(a, b) {
    let n = 1;
  //최대공약수 구하기 a와 b중 작은 수까지
  //a가 b보다 작다면 굳이 b까지 반복할 필요가 없다.
    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;   
}

//다른 사람 코드
function solution(a, b) {
    let tmpB = b
    while (tmpB % 2 === 0) tmpB /= 2
    while (tmpB % 5 === 0) tmpB /= 5
    if (a % tmpB === 0) tmpB = 1
    return tmpB === 1 ? 1 : 2
}
//b가 2로 나누어떨어지면 계속 2로 나누고,
//또 b가 5로 나누어떨어지면 계속 5로 나눈다.
//a가 b랑 나눴을 때 떨어지면 당연히 정수이므로 유한소수!
//아니라면 b가 2와 5로 모두 나눠져 마지막에 1이되면 유한소수!

저주의 숫자3

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

//내 코드
function solution(n) {
    let a=0;
    for(let i=1; i<=n; i++){ //n까지 반복
        a++;//a를 n까지 더하고
        while(a%3===0 || String(a).includes("3")){a++;}
        //3의배수가 아닌 경우와 3이 들어가지 않는 경우까지 반복
    }
    return a;
}
//0~200까지의 숫자들의 나열에서 3과관련된 숫자 모두 빼고 n 번째 숫자 구하기
//두번째 방법
//1부터 200까지의 숫자를 가진 배열만들고, 3과 관련된거 filter
//배열의 n-1인덱스의 값구하기
//(배열의 시작은 0이므로 1부터 시작하는 기준으로 15번째숫자를 구하는 것은,
//0부터 시작하는 14번째 숫자를 구하는 것과 같다.)
/*
let result = Array.from({length:200},(a,b)=>b+1)
        .filter(a => a%3!==0 && !String(a).includes("3"));
    return result[n-1];
*/

//다른 사람 코드
function solution(n) {
  return [...Array(n * 3)]
    .map((_, i) => i + 1)
    .filter((num) => num % 3 !== 0 && !num.toString().includes("3"))[n - 1];
}
//array를 만들때, 200까지 할 필요없고
//[...Array(n*3)] 3의 배수만큼 빼야하므로 3배더있으면된다.
//map으로도 index+1을 할 수 있다.

평행

점 네 개의 좌표를 담은 이차원 배열 dots가 다음과 같이 매개변수로 주어집니다.
[[x1, y1], [x2, y2], [x3, y3], [x4, y4]]
주어진 네 개의 점을 두 개씩 이었을 때, 두 직선이 평행이 되는 경우가 있으면 1을 없으면 0을 return 하도록 solution 함수를 완성해보세요.

//내 코드
function solution(dots) {
    let arr = [];
    // y좌표의 차이 / x좌표의 차이 = 기울기
    // 기울기가 같다면 평행
    //[a-b, c-d],[a-c, b-d],[a-d, b-c]를 비교해서 배열안의 기울기가 서로 같은게 하나라도 있다면 1리턴
    let ab = Math.abs(dots[0][1]-dots[1][1]) / Math.abs(dots[0][0]-dots[1][0])
    let cd = Math.abs(dots[2][1]-dots[3][1]) / Math.abs(dots[2][0]-dots[3][0])
    
    let ac = Math.abs(dots[0][1]-dots[2][1]) / Math.abs(dots[0][0]-dots[2][0])
    let bd = Math.abs(dots[1][1]-dots[3][1]) / Math.abs(dots[1][0]-dots[3][0])
    
    let ad = Math.abs(dots[0][1]-dots[3][1]) / Math.abs(dots[0][0]-dots[3][0])
    let bc = Math.abs(dots[1][1]-dots[2][1]) / Math.abs(dots[1][0]-dots[2][0])

    arr = [ab-cd, ac-bd, ad-bc];
    //[ab-cd],[ac-bd],[ad-bc] 0이 하나라도 있으면 1리턴 없으면 0리턴
    if(arr.includes(0)) return 1;
    else return 0;
}

//다른 사람 코드 : 나랑 비슷한 코드지만 기울기 구하는 함수를 따로 뺐고,
//나는 배열로 다 감싸서 나중에 기울기가 같은지 비교했는데,
//이 코드는 기울기를 바로 비교해서 같으면 1리턴
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) {
    // 선분들이 놓일 공간
  let lineMap = new Array(200).fill(0);

    //각 line의 0번째요소와 1번째요소 변수에 담기
  for (let i = 0; i < 3; i++) {
    let left = lines[i][0];
    let right = lines[i][1];

      //음수일 경우를 대비하여 각left요소에 100을 더한 lineMap의 인덱스값에 1씩 더한다.
    for (let j = left; j < right; j++) {
      lineMap[j + 100] += 1;
    }
  }

    //lineMap의 요소가 2이상인것만 필터링해서 길이구하기
    //ex.[[0, 5], [3, 9], [1, 10]]
    //lineMap[i] === lineMap[100]=1, lineMap[101]=2...
  return lineMap.filter((v,idx)=> v>1).length;
}


//다른 사람 코드
function solution(lines) {
    let min = Math.min(...lines.flat());
    let max = Math.max(...lines.flat());
  //min~max까지 모두 0으로 채운 배열 생성
    let arr = Array(max-min+1).fill(0);

    for (let line of lines) {
        line.sort((a,b)=>a-b);//작은것들 순대로 정렬
        if (min < 0) { //음수라면
            line[0]+=Math.abs(min)//제일작은수만큼 더해준다
            line[1]+=Math.abs(min)
        }//각 line의 길이까지 line인덱스의 값을 1씩 더해준다
      //겹쳐지는 부분은 1보다 클것이다.
        for (let i = line[0]; i < line[1]; i++) arr[i]++;
    }

    return arr.filter(v=>v>1).length;
}
profile
신입 프론트엔드 웹 개발자입니다.

0개의 댓글