From 699ed097b4a15f9f095d5775e9d5f75f6a4e490a Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Mon, 29 Aug 2022 22:10:06 +0900 Subject: [PATCH 1/8] comment: Add comment --- ...3\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" | 1 + 1 file changed, 1 insertion(+) create mode 100644 ".github/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" diff --git "a/.github/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" "b/.github/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" new file mode 100644 index 0000000..09d4352 --- /dev/null +++ "b/.github/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" @@ -0,0 +1 @@ +// test From 5a291eb837cf8adae7264819b6edb984c162f760 Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Tue, 30 Aug 2022 07:50:08 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20Solved=20=EB=92=A4=EC=A7=91?= =?UTF-8?q?=EC=9D=80=EC=86=8C=EC=88=98=20[=EC=99=84=EC=A0=84=ED=83=90?= =?UTF-8?q?=EC=83=89]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...21\354\235\200\354\206\214\354\210\230.js" | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 "parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" diff --git "a/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" "b/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" new file mode 100644 index 0000000..cddd040 --- /dev/null +++ "b/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" @@ -0,0 +1,54 @@ +/* +[문제] +N개의 자연수가 입력되면 각 자연수를 뒤집은 후 소수이면 그 소수를 출력하는 프로그램을 작성하세요. + +예시) +* 32를 뒤집으면 23, 23은 소수. => 23 출력 +* 910 뒤집으면 19 => 첫 자리부터 연속된 0 무시 +*/ + +// 소수판별 알고리즘 +const isPrime = num => { + // 인자로 들어온 num === filteredArr에서 전달되는 각 배열의 숫자 n + // 1 이하일 경우 소수가 아니므로 false + if (num <= 1) return false; + + // 제곱근까지 비교하여 나누어떨어지는 수가 있는지 확인 + // 12 => 1*12 / 2*6 / 3*4 / 4*3/ 6*2 ... => 4까지 확인하면 나머지 숫자는 같은 숫자의 반복이므로 상관없다. + for (let i = 2; i <= parseInt(Math.sqrt(num)); i++) { + if (num % i === 0) return false; + } + return true; +}; + +// 필터링 알고리즘 +const reversePrime = arr => { + // map => 뒤집은 숫자 배열 + // filter => isPrime에 해당하는 숫자만 모음 + const filteredArr = arr + .map(num => { + return Number(String(num).split('').reverse().join('')); + }) + .filter(num => isPrime(num)); + + // filteredArr을 순회하며 출력 + filteredArr.forEach(num => console.log(num)); +}; + +const arr = [32, 55, 62, 20, 250, 370, 200, 30, 100]; +const N = arr.lenght; +let result = reversePrime(arr); +console.log(result); + +/* +[풀이 과정] + +* 시도 1 +- 각 자연수를 뒤집은 숫자를 만든다. +... 뒤집을 때 메서드를 사용했는데 다른 방법은 없는가..?? +- 각 수가 소수인지 판별 : 소수 판별 알고리즘을 만든다. +- 소수 판별 알고리즘? 2 ~ 각 수의 제곱근까지와 비교해 나뉘어 떨어지는것이 있는지 판별. + + + +*/ From bcfb56a8bedb5b3569cd70c16539cdf185e7a8ba Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Tue, 30 Aug 2022 08:20:38 +0900 Subject: [PATCH 3/8] remove: Test files --- ...3\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" | 1 - 1 file changed, 1 deletion(-) delete mode 100644 ".github/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" diff --git "a/.github/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" "b/.github/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" deleted file mode 100644 index 09d4352..0000000 --- "a/.github/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" +++ /dev/null @@ -1 +0,0 @@ -// test From 8870ea1984f18f6328e0ab999a5601da7f1bcfd6 Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Fri, 2 Sep 2022 13:50:37 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20Solved=20K=EB=B2=88=EC=A7=B8?= =?UTF-8?q?=ED=81=B0=EC=88=98=20[=EC=99=84=EC=A0=84=ED=83=90=EC=83=89]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...10\354\247\270\355\201\260\354\210\230.js" | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 "parkHyeJung/Section04/05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" diff --git "a/parkHyeJung/Section04/05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" "b/parkHyeJung/Section04/05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" new file mode 100644 index 0000000..6455895 --- /dev/null +++ "b/parkHyeJung/Section04/05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" @@ -0,0 +1,42 @@ +/* +[문제] +현수는 1부터 100사이의 자연수가 적힌 N장의 카드를 가지고 있습니다. 같은 숫자의 카드가 +여러장 있을 수 있습니다. 현수는 이 중 3장을 뽑아 각 카드에 적힌 수를 합한 값을 기록하려 +고 합니다. 3장을 뽑을 수 있는 모든 경우를 기록합니다. 기록한 값 중 K번째로 큰 수를 출력 +하는 프로그램을 작성하세요. +만약 큰 수부터 만들어진 수가 25 25 23 23 22 20 19......이고 K값이 3이라면 K번째 큰 값 +은 22입니다. + +*/ + +function kLargestNum(N, K, cards) { + cards.sort((a, b) => b - a); + let sums = []; + for (let i = 0; i < N; i++) { + for (let j = i + 1; j < N; j++) { + for (let k = j + 1; k < N; k++) { + if (sums.length < K) sums.push(cards[i] + cards[j] + cards[k]); + else break; + } + } + } + return sums[K - 1]; +} + +const N = 10; // cards.length +const K = 3; +const cards = [13, 15, 34, 23, 45, 65, 33, 11, 26, 42]; + +const result = kLargestNum(N, K, cards); +console.log(result); + +/* +[풀이과정] + +* 시도1 +- 3중 for문... 을 사용해서 각 숫자 조합을 만들고 배열에 입력한다. +... 숫자를 내림차순으로 정렬하면 k번째 숫자가 더 빨리 나오지 않을까? +... 배열의 길이가 k를 넘어가는 순간 반복문을 중지하고 리턴. + + +*/ From 282da8dec15639e709c537ae2e5f08a1964ae95d Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Sat, 3 Sep 2022 17:05:17 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20=EB=92=A4=EC=A7=91=EC=9D=80?= =?UTF-8?q?=EC=86=8C=EC=88=98=20[=EC=99=84=EC=A0=84=ED=83=90=EC=83=89]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...10\354\247\270\355\201\260\354\210\230.js" | 57 +++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git "a/parkHyeJung/Section04/05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" "b/parkHyeJung/Section04/05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" index 6455895..a69f067 100644 --- "a/parkHyeJung/Section04/05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" +++ "b/parkHyeJung/Section04/05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" @@ -7,28 +7,40 @@ 만약 큰 수부터 만들어진 수가 25 25 23 23 22 20 19......이고 K값이 3이라면 K번째 큰 값 은 22입니다. +[출력] +K번째 수가 존재하지 않으면 -1을 출력한다. + */ function kLargestNum(N, K, cards) { + // cards 배열 내림차순 정렬 cards.sort((a, b) => b - a); + + // 3개를 뽑은 합계를 담을 배열 sums let sums = []; + + // 숫자를 3회 뽑아야 하므로, for문을 3번 돈다. 중복 방지를 위해서 각각 0, 1, 2 순서로 진행. for (let i = 0; i < N; i++) { for (let j = i + 1; j < N; j++) { for (let k = j + 1; k < N; k++) { - if (sums.length < K) sums.push(cards[i] + cards[j] + cards[k]); - else break; + // 3번째 for문에서 각 순서대로 뽑힌 카드를 더한 값을 배열에 담아준다. + sums.push(cards[i] + cards[j] + cards[k]); } } } - return sums[K - 1]; + // 3번째로 '큰' 값, 즉 중복을 제외한 값이어야 하기 때문에 set을 사용해 중복제거 후 다시 배열로 변환 + sums = [...new Set(sums)]; + + // 해당 배열에 K번째 큰 수가 존재하면 리턴하고 아닐 경우 -1을 리턴 + return sums[K - 1] ? sums[K - 1] : -1; } const N = 10; // cards.length const K = 3; const cards = [13, 15, 34, 23, 45, 65, 33, 11, 26, 42]; -const result = kLargestNum(N, K, cards); -console.log(result); +const result1 = kLargestNum(N, K, cards); +// console.log(result1); /* [풀이과정] @@ -37,6 +49,41 @@ console.log(result); - 3중 for문... 을 사용해서 각 숫자 조합을 만들고 배열에 입력한다. ... 숫자를 내림차순으로 정렬하면 k번째 숫자가 더 빨리 나오지 않을까? ... 배열의 길이가 k를 넘어가는 순간 반복문을 중지하고 리턴. +=> 중복된 값이 있다는 것을 미처 생각하지 못했다! 다시 수정했음 + +* 시도2 +- 3중 for문으로 모든 경우를 배열에 담은 뒤 Set으로 중복을 제거하고 해당하는 인덱스로 접근하여 리턴. +*/ + +function answer(N, K, cards) { + // 3개를 뽑은 합이 중복되지 않고 추가되도록 Set을 생성한다. + let sums = new Set(); + + // 반복을 3중으로 돌아서 중복되지 않는 모든 경우의 조합을 만든다. + for (let i = 0; i < N; i++) { + for (let j = i + 1; j < N; j++) { + for (let k = j + 1; k < N; k++) { + // Set 에 add 메서드를 사용해 합계를 추가할 수 있다. + sums.add(cards[i] + cards[j] + cards[k]); + } + } + } + // K번째 큰 수를 출력하는 것이므로 sums를 배열로 변환하고 내림차순 정렬한 후 출력한다. + sums = [...sums].sort((a, b) => b - a); + return sums[K - 1] ? sums[K - 1] : -1; +} +const result2 = answer(N, K, cards); +console.log(result2); +/* +[Set 자료구조 정리] +- '중복되지 않는 유일한 값들의 집합'이다. set 안에 존재하는 한 값은 유일한 값이다. +- 이터러블한 자료구조로 반복할 수 있지만, 순서에 의미가 없고 그렇기 때문에 index 개념도 없다. +- set.size : 요소의 갯수를 확인 +- set.add(el) : 요소 추가 +- set.has(el) : el 이 set에 존재하는지 여부를 확인할 수 있다.(boolean 값 리턴) +- set.delete(el) : el이 set에 존재할 경우 삭제하고, 삭제 여부에 대한 boolean 값을 리턴한다. +- set.clear() : 전체 요소를 삭제할 수 있고, undefined를 반환한다. +- for...of나 forEach 메서드로 순회할 수 있다. forEach를 사용했을 때 두 번째 인자는 index 대신 해당 요소임. */ From f680a6bf78f2313be139840073f7e82c810cbbfc Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Sat, 3 Sep 2022 17:38:37 +0900 Subject: [PATCH 6/8] =?UTF-8?q?docs=20:=20Create=20Section04=5F=EC=99=84?= =?UTF-8?q?=EC=A0=84=ED=83=90=EC=83=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...04\354\240\204\355\203\220\354\203\211.md" | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 "parkHyeJung/Section04/Section04_\354\231\204\354\240\204\355\203\220\354\203\211.md" diff --git "a/parkHyeJung/Section04/Section04_\354\231\204\354\240\204\355\203\220\354\203\211.md" "b/parkHyeJung/Section04/Section04_\354\231\204\354\240\204\355\203\220\354\203\211.md" new file mode 100644 index 0000000..d2c1e3f --- /dev/null +++ "b/parkHyeJung/Section04/Section04_\354\231\204\354\240\204\355\203\220\354\203\211.md" @@ -0,0 +1,29 @@ +# Section_04 완전탐색 + +## 개요 + +- 모든 경우를 탐색해보는 알고리즘(방법), 가능한 경우의 수를 일일이 나열하면서 해당되는 답을 찾는 방법이다. +- 가능한 모든 경우를 (무식하게) 나열하며 찾기 때문에, 100% 정답을 도출할 수는 있지만 그 속도가 굉장히 느린 편이다. +- 문제를 해결할 수는 있지만 그 효율성이 떨어지기 때문에 너무 많은 경우의 수를 도출해야 하는 경우 적절하지 않은 방법이다. +- 완전탐색이 어떤 특정한 알고리즘 기법이라기 보다는, 그냥 모든 경우의 수를 다 구하며 문제를 해결하는 방식이면 완전탐색이라고 할 수 있다. + +## 적용 방법 + +1. 해결하고자 하는 문제의 경우의 수를 대략적으로 계산한다. +2. 가능한 모든 방법을 다 고려한다. +3. 실제 답을 구할 수 있는지 적용해본다. + +이 문제가 완전탐색을 적용하기에 알맞은 문제인지 파악한 뒤에, +완전 탐색 중에서도 구체적으로 어떤 방식을 사용할 것인지 고려하여 적용한다. + +## 해당하는 알고리즘 종류 + +1. **Brute Force 기법** : 반복문 / 조건문을 활용해 가능한 모든 경우를 나열하는 방법 +2. **순열** : n개의 원소 중 r 개만큼의 원소를 중복 없이 나열하는 방법 (순서가 중요하다.) +3. **재귀 호출** : 재귀 식을 가지고 자기 자신을 반복 호출하는 알고리즘, 반복문으로 코드를 작성할 때 반복문의 중첩 횟수를 예측할 수 없거나 중첩이 과다하게 많은 경우 적용해볼 수 있다. +4. **비트마스크** : 2진수 표현을 활용해 집합과 부분집합을 구할 수 있는 알고리즘. 2진수의 자릿수를 활용해 즉 0과 1인 bit 를 가지고 빠르게 연산한다는 장점이 있음. +5. **DFS, BFS** : 그래프 자료구조에서 '모든 정점을 탐색'하기 위한 방법. + +### 참고자료 + +[알고리즘-완전탐색(Exhaustive Search)](https://hongjw1938.tistory.com/78) From e0ecf91653f5cab2c038199291801718d8b99425 Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Sat, 3 Sep 2022 20:30:45 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20=EB=92=A4=EC=A7=91=EC=9D=80?= =?UTF-8?q?=EC=86=8C=EC=88=98=20[=EC=99=84=EC=A0=84=ED=83=90=EC=83=89]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...21\354\235\200\354\206\214\354\210\230.js" | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git "a/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" "b/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" index cddd040..0ba19d5 100644 --- "a/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" +++ "b/parkHyeJung/Section04/02-\353\222\244\354\247\221\354\235\200\354\206\214\354\210\230.js" @@ -37,8 +37,7 @@ const reversePrime = arr => { const arr = [32, 55, 62, 20, 250, 370, 200, 30, 100]; const N = arr.lenght; -let result = reversePrime(arr); -console.log(result); +// let result1 = reversePrime(arr); /* [풀이 과정] @@ -49,6 +48,38 @@ console.log(result); - 각 수가 소수인지 판별 : 소수 판별 알고리즘을 만든다. - 소수 판별 알고리즘? 2 ~ 각 수의 제곱근까지와 비교해 나뉘어 떨어지는것이 있는지 판별. +*/ + +function answer(arr) { + let answer = []; + for (let x of arr) { + // 뒤집어지는 수가 저장되는 res + let res = 0; + while (x) { + let t = x % 10; + res = res * 10 + t; + x = parseInt(x / 10); + } + if (isPrime(res)) answer.push(res); + } + return answer; +} +let result2 = answer(arr); +console.log(result2); + +/* +[답안 해설] +- arr의 숫자들을 x 로 반복하면서, x의 각 자릿수를 뜯어서 자리를 바꾸는 방법이다. +- x === 32 일 때. + +* 1번째 반복 : x === 32 +... t = x % 10 => 32를 10으로 나눈 나머지이므로 t === 2가 된다. +... res = res * 10 + t => 0 * 10 + 2 이므로 res === 2가 된다. +... x = parseInt(x / 10) => 32를 10으로 나눈 몫이므로 3이 된다. +* 2번째 반복 : x === 3 +... t = x % 10 => 3을 10으로 나눈 나머지이므로 t === 3이 된다. +... res = res * 10 + t => 2 * 10 + 3 이므로 23이 된다. (***) +... x = parseInt(x / 10) => parseInt( 3 / 10 ) === 0 이기 때문에 while문이 종료된다. */ From 47788fcaa306b8d7434779e04164daa38247fa91 Mon Sep 17 00:00:00 2001 From: hyejj19 Date: Sat, 3 Sep 2022 23:05:58 +0900 Subject: [PATCH 8/8] =?UTF-8?q?feat:=20Solved=20K=EB=B2=88=EC=A7=B8?= =?UTF-8?q?=ED=81=B0=EC=88=98=20[=EC=99=84=EC=A0=84=ED=83=90=EC=83=89]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" | 1 + 1 file changed, 1 insertion(+) diff --git "a/parkHyeJung/Section04/05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" "b/parkHyeJung/Section04/05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" index a69f067..184cdec 100644 --- "a/parkHyeJung/Section04/05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" +++ "b/parkHyeJung/Section04/05-K\353\262\210\354\247\270\355\201\260\354\210\230.js" @@ -65,6 +65,7 @@ function answer(N, K, cards) { for (let k = j + 1; k < N; k++) { // Set 에 add 메서드를 사용해 합계를 추가할 수 있다. sums.add(cards[i] + cards[j] + cards[k]); + console.log(i, j, k); } } }