본문 바로가기
개발/알고리즘 풀기

TIL 230412 _소수찾기, 실패율, 체육복, 최대공약수와 최소공배수, K번째 수, 나머지가 1이 되는 수 찾기, 폰켓몬

by 코딩하는짱구 2023. 4. 13.
반응형

수리력때문에 너무 힘들다....

 

✅문제 

-소수 찾기 

//소수 찾기
//1부터 입력받은 숫자 n 사이에 있는 소수의 개수를 반환하는 함수, solution을 만들어 보세요.
//소수는 1과 자기 자신으로만 나누어지는 수를 의미합니다.(1은 소수가 아닙니다.)

✍문제풀이

1. 나의 접근방식 및 실패한 코드

//접근방식: 1~n을 돌면서 요소가 소수인지 체크
//그럴려면 우선 1~n을 배열화 해야함
//배열을 만들었으면 그 요소들이 소수인지 확인한다.
//요소가 소수가 맞다면 answer의 카운트를 올려준다

var n = 10; //result = 4

function solution(n) {
  answer = 0;
  var nums = [];
  for (var i = 1; i < n + 1; i++) {
    nums.push(i);
  }

  for (var i = 0; i < nums.length; i++) {
    if (nums[i] === 1) {
      return false;
    } else if (nums[i] === 2) {
      return true;
    } else {
      for (let j = 2; j < nums[j]; j++)
        if (nums[i] % 1 === 0) {
          return false;
        }
    }
  }
  return true;
}

console.log(solution(n));

//위와 같이 하니까 false만 나옴..그렇다면

//소수의 개념이 뭔가? 자기 자신과 1 빼고는 나누어 지지 않는 수 이다.

// var n = 10; //result = 4 (2,3,5,7)

// function solution(n) {
//   var answer = 0;
//   var arr = new Array(n + 1).fill(true); //1부터 10까지 배열화 해준 후 모두 true 값으로 바꾼다
//   //해당 코드는 n이 10일 때, 길이가 11이고 모든 요소가 true인 배열 arr을 생성합니다.
//배열의 인덱스는 0부터 n까지 총 n+1개이며, 인덱스 0은 사용되지 않습니다. 따라서 인덱스 1부터 n까지의 요소는 모두 true로 초기화됩니다.
//즉, arr은 다음과 같은 배열입니다.

//0번째 요소는 왜 사용되지 않는거야? 약속인거야?
//네, 배열의 0번째 인덱스가 비어있는 것은 자바스크립트에서 일반적인 규칙 중 하나입니다. 이것은 C언어와 같은 몇몇 프로그래밍 언어에서도 마찬가지입니다.

// 이 규칙은 초기 컴퓨터 언어에서부터 유래하며, 이전에는 컴퓨터 메모리의 첫 번째 바이트(8비트)가 주소 0을 가리키도록 규정되어 있었습니다. 이에 따라 배열의 인덱스가 0부터 시작하게 되었고, 이후에 이러한 규칙이 프로그래밍 언어에서도 적용되었습니다.

// 따라서 자바스크립트에서도 배열의 인덱스가 0부터 시작하는 규칙이 적용되고, 배열의 0번째 인덱스는 요소를 저장하지 않는 것이 일반적입니다.

//이렇게 [true],[true],..인 1~10의 배열이 생성되고,

function solution(n) {
  var answer = 0;
  var arr = new Array(n + 1).fill(true);
  for (let i = 2; i <= n; ++i) {
    // 1은 건너뛴다, 어차피 소수가 아니므로
    if (arr[i] === false) {
      continue;
    }
    for (let k = i * 2; k <= n; k += i) {
      arr[k] = false;
    }
  }
  for (let i = 2; i <= n; ++i) {
    if (arr[i] === true) {
      answer++;
    }
  }

  return answer;
}

console.log(solution(n));

// //무슨말인지 모르겠음..넘어가자

2. 문제파악 및  해결한 코드

//숫자를 객체화시키기

var n = 10;

function solution(n) {
  const s = new Set(); // 여기까진 빈 객체
  for (let i = 1; i <= n; i += 2) {
    s.add(i); //객체에 홀수들을 넣어준다, 근데 1이 포함되어있으니
  }
  s.delete(1); //1은 빼주고
  s.add(2); //2는 넣어준다,
  ///s={2,3,5,7,9}

  for (let i = 2; i <= n; i++) {
    //얘는 아예 새로 만든 숫자;s 아님! 2,3,4,5,6,7,8...

    if (s.has(i)) {
      //i있으면, true니까 for문으로 들어감//
      for (let x = 3 * 2; x <= n; x += i) {
        //{2,3,5,7}
        s.delete(x);
      }
    }
  }
  return s.size;
  //length는 안되는 이유가 set() {3,5,7,2} 로 객체로 나오기때문에
} //객체 = > .size, .has, .delete, .add / 배열 => .length

console.log(solution(10));
console.log(solution(5));

 

 

 

 

 

✅문제 

-실패율

// 실패율은 다음과 같이 정의한다.
// 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수
// 전체 스테이지의 개수 N, 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열 stages가 매개변수로 주어질 때, 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열을 return 하도록 solution 함수를 완성하라.

✍문제풀이

1. 나의 접근방식 및 실패한 코드

//접근방법 : 배열의 길이는 사용자수, 각 스테이지를 배열화 한 후에 각 배열을 비교하여 총스테이지 배열에 값을줌. 그걸 내림차순으로 다시 정렬

//실패율은 어떻게 구할것인가?
//stage 1의 실패율 : 1/8, 즉 1 / 총 인덱스 수
//stage 2의 실패율 : 3/7, 즉 2의 값을 가진 요소 수 / 총인덱스에서 1을 뺀 수
//stage 3의 실패율 : 2/4, 즉 3의 값을 가진 요소 수 /총 인덱스에서 1,2을 뺀 수
//...

// function solution(n, stages) {
//   var answer = [];
//   var totalStage = []; //[1,2,3,4,5]
//   for (var i = 1; i <= n; i++) { //[2,1,2,6,2,4,3,3]
//     totalStage.push(i);
//   }

//   var fail = [];
//   for(let i =0; i<stages.length; i++){
//    if(stages[i] == 1){
//     stages[i] /
//    }
//   }

//   return answer;
// }
// console.log(solution(n, stages));

2. 문제파악 및  해결한 코드

//다른 접근 방법
//filter 함수를 이용하니 간략하고 이해도 훨씬 쉬워졌다!!
//스테이지에 도달한 사람수와 머무르는 사람(클리어 하지 못한 사람)을 각각 변수로 지정해 그 수를 뽑아주고 나눈 수를 배열로..

var n = 5; //총스테이지
var stages = [2, 1, 2, 6, 2, 4, 3, 3];
function solution(n, stages) {
  answer = [];
  for (let i = 1; i <= n; i++) {
    const reach = stages.filter((x) => x >= i).length; //length를 붙여주어 길이로 반환 시킨다. 즉 i=1일때 해당 값은 1,2,2,2,3,4,4,6 이므로 배열의 길이인 8을 반환한다.
    //도달한 토탈 사람, i=1 1,2,2,2,3,4,4,6, i=2 2,2,2,3,3,4,6, i=3 3,3,4,6, i=4 4,6, i=5 6,
    let curr = stages.filter((x) => x === i).length;
    //현재 머무르는 사람, i=1 1, i=2 2,2,2, i=3 3,3, i=4 4, i=5작동안함, i=6 6
    //i=요소로 넣어라, 즉 stages 배열의 길이와 같은 new 배열을 만들어라.
    answer.push([i, curr / reach]); //이렇게 스테이지값에 따른 실패율이 나온다.
  }
  answer.sort((a, b) => b[1] - a[1]); //우리는 배열중 실패율 값, 즉 인덱스의 두번째 값을 비교해야되기 때문에
  return answer.map((x) => x[0]); // 그리고 표시는 스테이지 번호만,
  //즉 요소(x)의 첫번째 값만
}
console.log(solution(n, stages));

 

 

 

 

 

✅문제 

-체육복

//전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.

✍문제풀이

1. 나의 접근방식 및 실패한 코드

/접근; reserve의 값은 어떻게 도출되나?
// capa는 reserve의 요소 +1, -1
//즉 reserve가 1일 때 2; 3일때 2,4; 5일때 4,6;
//총 2,2,4,4,6이 되고 여기서 중복값을 제거한 최종capa 2,4,6이다.
//그 capa안에 lost의 요소가 다 포함되면, lost와 reserve를 합친다.

//1. reserve의 각 요소의 -1,+1 값을 구한다.

// var n = 4;
// var lost = [2, 4];
// var reserve = [1, 3, 5];

// function solution(reserve) {
//   var capa = [];
//   for (let i = 0; i < reserve.length; i++) {
//     capa.push(reserve[i] + 1, reserve[i] - 1);
//     const uniqueArr = [...new Set(capa)];
//     answer = uniqueArr; //여기까지 중복값을 제거한 capa [0,2,4,6]구함
//   }
//   for ()
//   return answer;
// }
// console.log(solution(reserve));

//코드를 이렇게 짜다보니 체육복도 잃어버리고 여분의 체육복도 동시에 있는 경우, 그리고 1일 경우 2만 도출해야되는데 그것도 헷갈리고.. 아예 다시 접근하기로 했다.

// var n = 5;
// var lost = [2, 4];
// var reserve = [1, 2, 5];

// function solution(n, lost, reserve) {
//   var answer = 0;

//   let has = new Array(n).fill(1); //전체 학생수가 가지고 있는 유니폼을 1로 초기화 시킴 1로 초기화시킨 이유는 나중에 if 문에서 has[i] === 0인놈들을 구분할 수 없다.
//   for (let i = 0; i < lost.length; i++) {
//     has[lost[i] - 1]--; //잃어버린 학생, i=0일 경우 2: 0,4: 0 i=1 2: 0,4: 0
//   }

//   for (let i = 0; i < reserve.length; i++) {
//     has[reserve[i] - 1]++; //여벌이 있는 학생 , i 가 2까지 돌면 전부 체육복 3개씩 생김
//   }

//   for (let i = 0; i < has.length; i++) {
//     if (has[i] === 0) {
//       if (has[i - 1] === 2) {
//         has[i]++;
//         has[i - 1]--; //좌 학생이 2일경우 i(없는애)에게 +1, 좌학생은 -1
//       } else if (has[i + 1] === 2) {
//         has[i]++;
//         has[i + 1]--;
//       }
//     }
//     if (has[i] >= 1) {
//       answer++;
//     }
//   }
//   return answer;
// }

// console.log(solution(n, lost, reserve)); //완성

//has[lost[i] -1 ]--; 부분이 이해가 안감.

2. 문제파악 및  해결한 코드

var n = 4;
var lost = [2, 4];
var reserve = [1, 2, 5];

function solution(n, lost, reserve) {
  var answer = 0;

  let has = new Array(n).fill(1); //[1,1,1,1]
  for (let i = 0; i < lost.length; i++) {
    has[lost[i] - 1]--; //lost[i]=2일때 has 열에서 1 lost[i]=4 has 열에서 3 //lost[i]의 요소는 1,2,3,4,5 숫자 그 자체이기때문에 그 숫자는 has 배열에서 요소값에서 1뺀 자리에 있다.
  } //[여기까지 1,0,0,1]이된다. 잃어버린놈 계산 완,

  for (let i = 0; i < reserve.length; i++) {
    has[reserve[i] - 1]++;
  } //i=0일때 1번의 값 [2], i=1일 때 2의 값은 1, i=3일 때 5의 값은 [2]
  //여기까지 [2,1,0,2]

  for (let i = 0; i < has.length; i++) {
    if (has[i] === 0) {
      if (has[i - 1] === 2) {
        has[i]++;
        has[i - 1]--;
      } else if (has[i + 1] === 2) {
        has[i]++;
        has[i + 1]--;
      }
    }
    if (has[i] >= 1) {
      answer++;
    }
  }
  return answer;
}

console.log(solution(n, lost, reserve));

 

 

 

 

✅문제 

-최대공약수와 최소공배수

✍문제풀이

1. 나의 접근방식 및 실패한 코드

function solution(x, y) {
  const gcd = (x, y) => (x % y === 0 ? y : gcd(y, x % y)); //최대공약수 / 나누었을때 나머지 0
  const lcm = (x, y) => (x * y) / gcd(x, y); // 최소공배수 / 공통된 배수중 제일 작은 값

  return [gcd(x, y), lcm(x, y)];
}

console.log(solution(3, 12));
console.log(solution(2, 5));

2. 문제파악 및  해결한 코드

 

 

 

 

 

✅문제 

-K번째 수 

✍문제풀이

1. 나의 접근방식 및 실패한 코드

//접근방법: 문자열을 주어진 순서로 자르고, 오름차순 정리, 배열의 k번째 숫자 뽑기
//for 는 i부터 j까지 돌아야함
//commands0 = i ; commands1 = j; commands 2 = k

2. 문제파악 및  해결한 코드

//힌트
//let [start, end, index] = commands[i]로 설정가능
// for문을 돌려서 array값을 start부터 end로 잘라주는 배열을 만든 후
// answer배열에 넣고
// 주의사항 : 문제에서 제시한 자르는 index값을 유의해야 함

//[2, 5, 3],
//[1, 5, 2, 6, 3, 7, 4], i = 2, j = 5, k = 3이라면

// array의 2번째부터 5번째까지 자르면 [5, 2, 6, 3]
function solution(array, commands) {
  let answer = [];
  for (let i = 0; i < commands.length; i++) {
    let [start, end, index] = commands[i]; //start는< array.length 만큼, end
    let nums = array.slice(start - 1, end); //
    nums.sort((a, b) => a - b);
    answer.push(nums[index]); //index를 그냥 줘버리면 우리가 만들어놓은 nums인덱스의 순서와 맞지 않아서 -1 해줘야함.
  }
  return answer;
}

console.log(
  solution(
    [1, 5, 2, 6, 3, 7, 4],
    [
      [2, 5, 3],
      [4, 4, 1],
      [1, 7, 3],
    ]
  )
);

 

 

 

 

 

✅문제 

-나머지가 1이 되는 수 찾기

//자연수 n이 매개변수로 주어집니다. n을 x로 나눈 나머지가 1이 되도록 하는 가장 작은 자연수 x를 //return 하도록 solution 함수를 완성해주세요. 답이 항상 존재함은 증명될 수 있습니다.

✍문제풀이

1. 나의 접근방식 및 실패한 코드

2. 문제파악 및  해결한 코드

// 0<i <= n
function solution(n) {
  for (let i = 1; i <= n; i++) {
    if (n % i === 1) {
      return i;
    }
  }
}
console.log(solution(10));
console.log(solution(12));

 

 

 

 

 

✅문제 

-나머지가 1이 되는 수 찾기

//당신은 최대한 다양한 종류의 폰켓몬을 가지길 원하기 때문에, 최대한 많은 종류의 폰켓몬을 포함해서 N/2마리를 선택하려 합니다. N마리 폰켓몬의 종류 번호가 담긴 배열 nums가 매개변수로 주어질 때, N/2마리의 폰켓몬을 선택하는 방법 중, 가장 많은 종류의 폰켓몬을 선택하는 방법을 찾아, 그때의 폰켓몬 종류 번호의 개수를 return 하도록 solution 함수를 완성해주세요.

✍문제풀이

어렵게 생각하면 한없이 어려워지는.. 그러나 나에겐 종류의수>선택할 수 있는 갯수의 공식을 파악 하는데도 오래걸렸다.

1. 나의 접근방식 및 실패한 코드


//ex) [3,1,2,3] 일때 두개를 선택할 수 있는 경우의수
//3,1; 3,2; 3,3; 1,2; 1,3; 2,3
//에서 가질 수 있는 '종류 수'의 최댓값은 2
//같은 숫자가 나오면 제외시켜야함

//접근방식: nums안에서 N가지 종류를 파악한다.
//nums가 6이라고 종류가 6이아님!
//만약 [1,2,3,3]이라면 ...
//중복된 포켓몬을 선택했을때 종류의 수와 연관이 없는 것을 파악
//ex)[1,1,2,2,2,3,3,1] 서로 다른 숫자의 경우의수 알아볼꺼니까 중복값 없애고 계산해야함
//서로 다른 수가 뭔지 파악해야되니까??
//ex) [1,2,3] 결국 종류의 수를 구해야하는 것
//선택하는 방법을 일단 변수로 지정해야되나?

2. 문제파악 및  해결한 코드

var nums = [3, 3, 3, 2, 2, 2, 2, 2, 2, 3]; // result = 2

function solution(nums) {
  const max = nums.length / 2;
  const arr = [...new Set(nums)];
  return arr.length > max ? max : arr.length;
}

console.log(solution(nums));

//간단하네..
//한마디로 내가 고를수 있는 숫자보다 선택지가 더 많으면 최대는 내가 고를 수 있는 숫자일꺼고;
//그게 아니면 선택지의 갯수(중복된 값이 없어진 값)
반응형