Skip to content

Commit 15a2096

Browse files
committed
feat(js): add modular solution and documentation for normal challenge 4 - Knapsack Dynamic Programming
1 parent 9ba7f3d commit 15a2096

File tree

7 files changed

+193
-49
lines changed

7 files changed

+193
-49
lines changed
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
21
/*
32
Challenge: Develop a function that implements the Merge Sort algorithm to sort an array.
43
Evaluate the efficiency of your implementation and consider cases with large arrays.
54
*/
65

76
// main.js - Example usage of MergeSort
87

9-
import MergeSort from './mergeSort.js';
8+
import MergeSort from "./mergeSort.js";
109

1110
function main() {
12-
const sampleArray = [38, 27, 43, 3, 9, 82, 10];
13-
console.log("Original array:", sampleArray);
14-
const sortedArray = MergeSort.mergeSort(sampleArray);
15-
console.log("Sorted array:", sortedArray);
11+
const sampleArray = [38, 27, 43, 3, 9, 82, 10];
12+
console.log("Original array:", sampleArray);
13+
const sortedArray = MergeSort.mergeSort(sampleArray);
14+
console.log("Sorted array:", sortedArray);
1615
}
1716

1817
main();
Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
11
// mergeSort.js - Merge Sort implementation
22

33
class MergeSort {
4-
static mergeSort(arr) {
5-
if (arr.length <= 1) {
6-
return arr;
7-
}
8-
const mid = Math.floor(arr.length / 2);
9-
const left = MergeSort.mergeSort(arr.slice(0, mid));
10-
const right = MergeSort.mergeSort(arr.slice(mid));
11-
return MergeSort.merge(left, right);
4+
static mergeSort(arr) {
5+
if (arr.length <= 1) {
6+
return arr;
127
}
8+
const mid = Math.floor(arr.length / 2);
9+
const left = MergeSort.mergeSort(arr.slice(0, mid));
10+
const right = MergeSort.mergeSort(arr.slice(mid));
11+
return MergeSort.merge(left, right);
12+
}
1313

14-
static merge(left, right) {
15-
const result = [];
16-
let i = 0, j = 0;
17-
while (i < left.length && j < right.length) {
18-
if (left[i] < right[j]) {
19-
result.push(left[i]);
20-
i++;
21-
} else {
22-
result.push(right[j]);
23-
j++;
24-
}
25-
}
26-
return result.concat(left.slice(i)).concat(right.slice(j));
14+
static merge(left, right) {
15+
const result = [];
16+
let i = 0,
17+
j = 0;
18+
while (i < left.length && j < right.length) {
19+
if (left[i] < right[j]) {
20+
result.push(left[i]);
21+
i++;
22+
} else {
23+
result.push(right[j]);
24+
j++;
25+
}
2726
}
27+
return result.concat(left.slice(i)).concat(right.slice(j));
28+
}
2829
}
2930

3031
export default MergeSort;
Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
// longestUniqueSubstring.js - Implementation of longest unique substring using sliding window technique
22

33
class LongestUniqueSubstring {
4-
static lengthOfLongestSubstring(s) {
5-
const charIndexMap = new Map();
6-
let left = 0;
7-
let maxLength = 0;
8-
let maxSubstring = "";
4+
static lengthOfLongestSubstring(s) {
5+
const charIndexMap = new Map();
6+
let left = 0;
7+
let maxLength = 0;
8+
let maxSubstring = "";
99

10-
for (let right = 0; right < s.length; right++) {
11-
if (charIndexMap.has(s[right]) && charIndexMap.get(s[right]) >= left) {
12-
left = charIndexMap.get(s[right]) + 1;
13-
}
14-
charIndexMap.set(s[right], right);
15-
if (right - left + 1 > maxLength) {
16-
maxLength = right - left + 1;
17-
maxSubstring = s.substring(left, right + 1);
18-
}
19-
}
20-
return { maxLength, maxSubstring };
10+
for (let right = 0; right < s.length; right++) {
11+
if (charIndexMap.has(s[right]) && charIndexMap.get(s[right]) >= left) {
12+
left = charIndexMap.get(s[right]) + 1;
13+
}
14+
charIndexMap.set(s[right], right);
15+
if (right - left + 1 > maxLength) {
16+
maxLength = right - left + 1;
17+
maxSubstring = s.substring(left, right + 1);
18+
}
2119
}
20+
return { maxLength, maxSubstring };
21+
}
2222
}
2323

2424
export default LongestUniqueSubstring;

2-NORMAL/JavaScript/3-longest-unique-substring/proposed-solution/main.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ Use sliding window techniques to optimize the solution's performance.
55

66
// main.js - Example usage of LongestUniqueSubstring
77

8-
import LongestUniqueSubstring from './longestUniqueSubstring.js';
9-
8+
import LongestUniqueSubstring from "./longestUniqueSubstring.js";
109

1110
function main() {
12-
const testString = "abcabcbb";
13-
const { maxLength, maxSubstring } = LongestUniqueSubstring.lengthOfLongestSubstring(testString);
14-
console.log(`Length of longest substring without repeating characters: ${maxLength}`);
15-
console.log(`Longest substring without repeating characters: ${maxSubstring}`);
11+
const testString = "abcabcbb";
12+
const { maxLength, maxSubstring } =
13+
LongestUniqueSubstring.lengthOfLongestSubstring(testString);
14+
console.log(
15+
`Length of longest substring without repeating characters: ${maxLength}`
16+
);
17+
console.log(
18+
`Longest substring without repeating characters: ${maxSubstring}`
19+
);
1620
}
1721

1822
main();
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Challenge Description and Solution
2+
3+
## English Version
4+
5+
### Challenge Description
6+
Solve the 0/1 knapsack problem using dynamic programming. Given a set of items with weights and values, determine the combination that maximizes value without exceeding the capacity.
7+
8+
### Code Explanation
9+
The solution uses a 2D dynamic programming table `dp` where `dp[i][w]` represents the maximum value achievable with the first `i` items and capacity `w`.
10+
11+
For each item, the algorithm decides whether to include it or not based on maximizing the total value without exceeding the capacity.
12+
13+
### Relevant Code Snippet
14+
15+
```javascript
16+
class Knapsack {
17+
static knapsack(weights, values, capacity) {
18+
const n = weights.length;
19+
const dp = Array.from({ length: n + 1 }, () => Array(capacity + 1).fill(0));
20+
21+
for (let i = 1; i <= n; i++) {
22+
for (let w = 0; w <= capacity; w++) {
23+
if (weights[i - 1] <= w) {
24+
dp[i][w] = Math.max(
25+
values[i - 1] + dp[i - 1][w - weights[i - 1]],
26+
dp[i - 1][w]
27+
);
28+
} else {
29+
dp[i][w] = dp[i - 1][w];
30+
}
31+
}
32+
}
33+
return dp[n][capacity];
34+
}
35+
}
36+
```
37+
38+
### Example Usage
39+
40+
```javascript
41+
import Knapsack from './knapsack.js';
42+
43+
const weights = [2, 3, 4, 5];
44+
const values = [3, 4, 5, 6];
45+
const capacity = 5;
46+
const maxValue = Knapsack.knapsack(weights, values, capacity);
47+
console.log(`Maximum value in knapsack with capacity ${capacity}: ${maxValue}`);
48+
```
49+
50+
---
51+
52+
## Versión en Español
53+
54+
### Descripción del Reto
55+
Resuelve el problema de la mochila 0/1 usando programación dinámica. Dado un conjunto de objetos con pesos y valores, determina la combinación que maximiza el valor sin exceder la capacidad.
56+
57+
### Explicación del Código
58+
La solución utiliza una tabla 2D de programación dinámica `dp` donde `dp[i][w]` representa el valor máximo alcanzable con los primeros `i` objetos y capacidad `w`.
59+
60+
Para cada objeto, el algoritmo decide si incluirlo o no basado en maximizar el valor total sin exceder la capacidad.
61+
62+
### Fragmento de Código Relevante
63+
64+
```javascript
65+
class Knapsack {
66+
static knapsack(weights, values, capacity) {
67+
const n = weights.length;
68+
const dp = Array.from({ length: n + 1 }, () => Array(capacity + 1).fill(0));
69+
70+
for (let i = 1; i <= n; i++) {
71+
for (let w = 0; w <= capacity; w++) {
72+
if (weights[i - 1] <= w) {
73+
dp[i][w] = Math.max(
74+
values[i - 1] + dp[i - 1][w - weights[i - 1]],
75+
dp[i - 1][w]
76+
);
77+
} else {
78+
dp[i][w] = dp[i - 1][w];
79+
}
80+
}
81+
}
82+
return dp[n][capacity];
83+
}
84+
}
85+
```
86+
87+
### Ejemplo de Uso
88+
89+
```javascript
90+
import Knapsack from './knapsack.js';
91+
92+
const weights = [2, 3, 4, 5];
93+
const values = [3, 4, 5, 6];
94+
const capacity = 5;
95+
const maxValue = Knapsack.knapsack(weights, values, capacity);
96+
console.log(`Valor máximo en la mochila con capacidad ${capacity}: ${maxValue}`);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// knapsack.js - 0/1 Knapsack problem using dynamic programming
2+
3+
class Knapsack {
4+
static knapsack(weights, values, capacity) {
5+
const n = weights.length;
6+
const dp = Array.from({ length: n + 1 }, () => Array(capacity + 1).fill(0));
7+
8+
for (let i = 1; i <= n; i++) {
9+
for (let w = 0; w <= capacity; w++) {
10+
if (weights[i - 1] <= w) {
11+
dp[i][w] = Math.max(
12+
values[i - 1] + dp[i - 1][w - weights[i - 1]],
13+
dp[i - 1][w]
14+
);
15+
} else {
16+
dp[i][w] = dp[i - 1][w];
17+
}
18+
}
19+
}
20+
return dp[n][capacity];
21+
}
22+
}
23+
24+
export default Knapsack;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// main.js - Example usage of Knapsack
2+
3+
import Knapsack from "./knapsack.js";
4+
5+
/*
6+
Challenge: Solve the 0/1 knapsack problem using dynamic programming.
7+
Given a set of items with weights and values, determine the combination that maximizes value without exceeding the capacity.
8+
*/
9+
10+
function main() {
11+
const weights = [2, 3, 4, 5];
12+
const values = [3, 4, 5, 6];
13+
const capacity = 5;
14+
const maxValue = Knapsack.knapsack(weights, values, capacity);
15+
console.log(
16+
`Maximum value in knapsack with capacity ${capacity}: ${maxValue}`
17+
);
18+
}
19+
20+
main();

0 commit comments

Comments
 (0)