Skip to content

Commit

Permalink
Added Dynamic Programming (#18)
Browse files Browse the repository at this point in the history
* Added knapsack and coinchange
  • Loading branch information
spirosmaggioros authored Jan 3, 2025
1 parent e68f833 commit dd1a5c2
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 1 deletion.
21 changes: 21 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ pub fn build(b: *std.Build) void {
.name = "linkedList.zig",
.category = "dataStructures",
});
if (std.mem.eql(u8, op, "ds/doublylinkedlist"))
build_algorithm(b, .{
.optimize = optimize,
.target = target,
.name = "doublyLinkedList.zig",
.category = "dataStructures",
});
if (std.mem.eql(u8, op, "ds/lrucache"))
build_algorithm(b, .{
.optimize = optimize,
Expand All @@ -76,6 +83,20 @@ pub fn build(b: *std.Build) void {
});

// Dynamic Programming algorithms
if (std.mem.eql(u8, op, "dp/coinChange"))
build_algorithm(b, .{
.optimize = optimize,
.target = target,
.name = "coinChange.zig",
.category = "dynamicProgramming"
});
if (std.mem.eql(u8, op, "dp/knapsack"))
build_algorithm(b, .{
.optimize = optimize,
.target = target,
.name = "knapsack.zig",
.category = "dynamicProgramming"
});

// Math algorithms
if (std.mem.eql(u8, op, "math/ceil"))
Expand Down
38 changes: 38 additions & 0 deletions dynamicProgramming/coinChange.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const std = @import("std");
const print = std.debug.print;
const testing = std.testing;

// Minimum cost function that solves the coin change problem(https://en.wikipedia.org/wiki/Change-making_problem)
// Arguments:
// arr: the array that contains the coins
// N: the total amount of money that you have
pub fn min_cost(arr: []const u32, comptime N: i32) i32 {
const max_of: i32 = N + 1;

var dp: [N + 1]i32 = undefined;
for (&dp) |*x| {
x.* = max_of;
}

dp[0] = 0;
for (0..(N + 1)) |i| {
for (arr[0..arr.len]) |x| {
if (x <= i) {
dp[i] = @min(dp[i], 1 + dp[i - x]);
}
}
}

return if (dp[N] > N) -1 else dp[N];
}

test "Testing min_cost algorithm" {
const v = [3]u32{ 1, 2, 5 };
try testing.expect(min_cost(&v, 11) == 3);

const v2 = [1]u32{2};
try testing.expect(min_cost(&v2, 3) == -1);

const v3 = [1]u32{1};
try testing.expect(min_cost(&v3, 0) == 0);
}
55 changes: 55 additions & 0 deletions dynamicProgramming/knapsack.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const std = @import("std");
const print = std.debug.print;
const testing = std.testing;

const pairs = struct {
cost: u32,
capacity: u32,
};

// Function that solves the 0/1 knapsack problem
// Arguments
// arr: Array of pairs that holds the capacity and the cost of each element
// capacity: The total capacity of your bag
// Determines which items to include in the collection so that the total weight is
// less than or equal to a given limit and the total value is as large as possible.
//
// Returns the collected value
pub fn knapsack(comptime arr: []const pairs, comptime capacity: u32) u32 {
if (capacity == 0) {
return 0;
}

const n: u32 = comptime arr.len;
var dp: [n + 1][capacity + 1]u32 = undefined;
for (0..(n + 1)) |i| {
for (0..(capacity + 1)) |j| {
dp[i][j] = 0;
}
}

for (1..(n + 1)) |i| {
for (0..(capacity + 1)) |j| {
dp[i][j] = dp[i - 1][j];
if (i == 0 or j == 0) {
dp[i][j] = 0;
} else if (arr[i - 1].capacity <= j) {
dp[i][j] = @max(dp[i - 1][j], arr[i - 1].cost + dp[i - 1][j - arr[i - 1].capacity]);
}
}
}

return dp[n][capacity];
}

test "Testing knapsack function" {
const arr = [_]pairs{ pairs{ .capacity = 10, .cost = 60 }, pairs{ .capacity = 20, .cost = 100 }, pairs{ .capacity = 30, .cost = 120 } };

try testing.expect(knapsack(&arr, 50) == 220);

const arr2 = [_]pairs{ pairs{ .capacity = 5, .cost = 40 }, pairs{ .capacity = 3, .cost = 20 }, pairs{ .capacity = 6, .cost = 10 }, pairs{ .capacity = 3, .cost = 30 } };
try testing.expect(knapsack(&arr2, 10) == 70);

const arr3 = [_]pairs{ pairs{ .capacity = 100, .cost = 100 }, pairs{ .capacity = 150, .cost = 150 } };
try testing.expect(knapsack(&arr3, 20) == 0);
}
3 changes: 3 additions & 0 deletions runall.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ rem Math

rem Data Structures
%ZIG_TEST% -Dalgorithm=ds/linkedlist %Args%
%ZIG_TEST% -Dalgorithm=ds/doublylinkedlist %Args%
%ZIG_TEST% -Dalgorithm=ds/lrucache %Args%

rem Dynamic Programming
%ZIG_TEST% -Dalgorithm=dp/coinChange %Args%
%ZIG_TEST% -Dalgorithm=dp/knapsack %Args%

rem Sort
%ZIG_TEST% -Dalgorithm=sort/quicksort %Args%
Expand Down
5 changes: 4 additions & 1 deletion runall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ $ZIG_TEST -Dalgorithm=math/gcd $Args

# Data Structures
$ZIG_TEST -Dalgorithm=ds/linkedlist $Args
$ZIG_TEST -Dalgorithm=ds/doublylinkedlist $Args
$ZIG_TEST -Dalgorithm=ds/lrucache $Args

# Dynamic Programming
$ZIG_TEST -Dalgorithm=dp/coinChange $Args
$ZIG_TEST -Dalgorithm=dp/knapsack $Args

## Sort
$ZIG_TEST -Dalgorithm=sort/quicksort $Args
Expand All @@ -42,4 +45,4 @@ $ZIG_TEST -Dalgorithm=web/httpClient $Args
$ZIG_TEST -Dalgorithm=web/httpServer $Args
$ZIG_TEST -Dalgorithm=web/tls1_3 $Args

## Add more...
## Add more...

0 comments on commit dd1a5c2

Please sign in to comment.