Skip to content

Commit 3f00af7

Browse files
implemented knapsack and some explanations
1 parent 56afe6c commit 3f00af7

File tree

4 files changed

+87
-9
lines changed

4 files changed

+87
-9
lines changed

src/main/scala/algorithms/dynamic/Chessboard.scala

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
package algorithms.dynamic
22

3+
/// Compute the number of valid paths for a king from (1,1) to (n,n) on an n×n chessboard
4+
///
5+
/// The king starts in the bottom-left corner (1,1) and must reach the top-right corner (n,n).
6+
/// A valid move must always bring the king closer to (n,n). The possible moves are:
7+
/// - Right: (x, y) → (x + 1, y)
8+
/// - Up: (x, y) → (x, y + 1)
9+
/// - Diagonal: (x, y) → (x + 1, y + 1)
10+
///
11+
/// We use **dynamic programming** to calculate the number of paths to each cell (x, y).
12+
/// The recurrence relation is:
13+
/// num(x, y) = num(x-1, y) + num(x, y-1) + num(x-1, y-1)
14+
///
15+
/// Time Complexity: O(n²) – We compute each cell once.
316
def numberOfValidMoves(n: Int): (Int, Array[Array[Int]]) = {
417
val num: Array[Array[Int]] = Array.fill(n, n)(0)
518

@@ -19,10 +32,11 @@ def numberOfValidMoves(n: Int): (Int, Array[Array[Int]]) = {
1932
@main
2033
def MainNumberOfValidMoves(): Unit = {
2134
val n: Int = 5
22-
var (num, mat) = numberOfValidMoves(n)
35+
val (num, mat) = numberOfValidMoves(n)
2336
println(s"Number of moves for $n is : $num")
37+
// Print DP matrix for visualization
2438
mat.foreach { row =>
25-
row foreach print; println
39+
println(row.mkString(" "))
2640
}
2741

2842
}

src/main/scala/algorithms/dynamic/Fibonacci.scala

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
package algorithms.dynamic
22

3-
// top down :
4-
3+
// Top-Down Recursive Fibonacci with Memoization
4+
/// This function calculates the nth Fibonacci number using recursion and memoization.
5+
/// It stores computed Fibonacci numbers in an array `A` to avoid redundant calculations (memorization).
6+
/// Base cases are handled directly: fib(0) = 1, fib(1) = 1.
7+
/// For other cases, it recursively computes the Fibonacci number and stores it in `A` for reuse.
8+
///
9+
/// Example:
10+
/// val (fib5, _) = recFibonacci(5)
11+
/// println(fib5) // 5
12+
///
13+
/// Time complexity: O(n) due to memoization (avoids recomputation).
514
def recFibonacci(n: Int): (Int, Array[Int]) = {
615
val A: Array[Int] = Array.fill(n + 1)(0)
716
def recHelper(c: Int): Int = {
@@ -16,8 +25,16 @@ def recFibonacci(n: Int): (Int, Array[Int]) = {
1625
(recHelper(n), A)
1726
}
1827

19-
// bottom up
20-
28+
// Bottom-Up Dynamic Programming Fibonacci
29+
/// This function calculates the nth Fibonacci number using bottom-up dynamic programming.
30+
/// It iteratively computes Fibonacci numbers starting from the base cases and stores them in an array `A`.
31+
/// The result for each Fibonacci number is directly built up, avoiding recursion.
32+
///
33+
/// Example:
34+
/// val (fib5, _) = DPFibonacci(5)
35+
/// println(fib5) // 5
36+
///
37+
/// Time complexity: O(n) due to the iterative approach (no recursion).
2138
def DPFibonacci(n: Int): (Int, Array[Int]) = {
2239
val A: Array[Int] = Array.fill(n + 1)(0)
2340
A(0) = 1
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package algorithms.dynamic
2+
3+
// Knapsack Problem (Bottom-Up Dynamic Programming):
4+
// Given a budget and arrays for item prices and values, find the maximum value
5+
// of items that can be selected without exceeding the budget.
6+
// The solution is built using dynamic programming, where we compute the
7+
// optimal value for each subproblem (considering each item and budget).
8+
//
9+
// Example:
10+
// Given prices: [2, 3, 4], values: [3, 4, 5], budget = 5
11+
// The optimal selection: item 1 (price 2, value 3) and item 2 (price 3, value 4)
12+
// for a total value of 7, without exceeding the budget of 5.
13+
14+
def knapsack(budget: Int, prices: Array[Int], values: Array[Int]): Int = {
15+
val n = prices.length
16+
if (prices.length != values.length) throw new RuntimeException("Mismatching Arrays!")
17+
18+
// Create DP table (E) to store optimal values for subproblems
19+
val E: Array[Array[Int]] = Array.ofDim[Int](budget + 1, n + 1)
20+
21+
// Initialize base case
22+
for (j <- 0 to n) { E(0)(j) = 0 }
23+
for (b <- 0 to budget) { E(b)(0) = 0 }
24+
25+
// Fill DP table using bottom-up
26+
for (i <- 1 to n) { // Loop over items
27+
for (b <- 1 to budget) { // Loop over possible budgets
28+
if (prices(i - 1) <= b) { // If the current item can be included
29+
E(b)(i) = Math.max(E(b)(i - 1), E(b - prices(i - 1))(i - 1) + values(i - 1))
30+
} else {
31+
E(b)(i) = E(b)(i - 1) // If the item can't be included, take the value from the previous row
32+
}
33+
}
34+
}
35+
36+
// Return the maximum value with the given budget
37+
E(budget)(n)
38+
}
39+
40+
@main
41+
def knapSackMain(): Unit = {
42+
val prices: Array[Int] = Array(2, 3, 4)
43+
val values: Array[Int] = Array(3, 4, 5)
44+
val budget = 5
45+
val result = knapsack(budget, prices, values)
46+
println(s"The knapsack solution for prices [2,3,4] and values [3,4,5] with budget 5 is $result")
47+
}

src/main/scala/datastructures/tree/AVLTree.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ package datastructures.tree
22

33
case class avlTree[T](
44
key: T,
5-
val left: Option[avlTree[T]] = None,
6-
val right: Option[avlTree[T]] = None,
7-
val parent: Option[avlTree[T]] = None
5+
left: Option[avlTree[T]] = None,
6+
right: Option[avlTree[T]] = None,
7+
parent: Option[avlTree[T]] = None
88
)
99

1010
def isSearchTree[T](avl: avlTree[T]): Boolean = {

0 commit comments

Comments
 (0)