* add zig examples * improved zig binary search This commit improves the binary search code in zig. The function has been made generic and the logic has been cleaned up a bit. The code has been updated to work with zig versions >= 0.9 * simplify zig selection sort This commit simplifies the logic of the zig selection sort. It now swaps in place the elements of the array instead of creating another array. This avoids allocating heap memory. The code has also been upgraded to zig version 0.9.1 * make zig recursion examples generic This commit modifies the zig examples for the recursion chapter to be generic. It also updates the code to zig version 0.9.1 * update chapter 4 examples This commit updates the zig examples in chapter 4. In particular examples have been made generic where possible. The code has been updated to zig version 0.9.1 * update zig hash table examples This commit updates the examples for the chapter 5 about hash tables. Some improvements have been done (using a set instead of a map). The code has been updated to zig version 0.9.1 * update breadth first search zig example This commit updates the zig example for the breadth first search algorithm. It adds a unit test and updates the code to zig version 0.9.1 * revamp zig dijkstra example * add comments in dijkstra zig * fix zig greedy algorithm * add test for zig dijkstra * add test for zig greedy algorithm * improve zig chapter 9 exercise This commit improves the zig exercise to comput the longest common subsequence. A main function has been added and the allocator code has been extracted from the `subsequence` function.
159 lines
4.9 KiB
Zig
159 lines
4.9 KiB
Zig
const std = @import("std");
|
|
const heap = std.heap;
|
|
const mem = std.mem;
|
|
|
|
pub fn main() !void {
|
|
var gpa = heap.GeneralPurposeAllocator(.{}){};
|
|
var arena = heap.ArenaAllocator.init(gpa.allocator());
|
|
defer arena.deinit();
|
|
|
|
var states_needed_array = [_][]const u8{ "mt", "wa", "or", "id", "nv", "ut", "ca", "az" };
|
|
var states_needed = std.BufSet.init(arena.allocator());
|
|
for (states_needed_array) |sn| {
|
|
try states_needed.insert(sn);
|
|
}
|
|
|
|
var stations = std.StringHashMap(*std.BufSet).init(arena.allocator());
|
|
|
|
var kone = std.BufSet.init(arena.allocator());
|
|
try kone.insert("id");
|
|
try kone.insert("nv");
|
|
try kone.insert("ut");
|
|
try stations.put("kone", &kone);
|
|
|
|
var ktwo = std.BufSet.init(arena.allocator());
|
|
try ktwo.insert("wa");
|
|
try ktwo.insert("id");
|
|
try ktwo.insert("mt");
|
|
try stations.put("ktwo", &ktwo);
|
|
|
|
var kthree = std.BufSet.init(arena.allocator());
|
|
try kthree.insert("or");
|
|
try kthree.insert("nv");
|
|
try kthree.insert("ca");
|
|
try stations.put("kthree", &kthree);
|
|
|
|
var kfour = std.BufSet.init(arena.allocator());
|
|
try kfour.insert("nv");
|
|
try kfour.insert("ut");
|
|
try stations.put("kfour", &kfour);
|
|
|
|
var kfive = std.BufSet.init(arena.allocator());
|
|
try kfive.insert("ca");
|
|
try kfive.insert("az");
|
|
try stations.put("kfive", &kfive);
|
|
|
|
var stations_covering = try setCovering(arena.allocator(), &stations, &states_needed);
|
|
|
|
for (stations_covering) |sc| {
|
|
std.debug.print("{s}\n", .{sc});
|
|
}
|
|
}
|
|
|
|
fn setCovering(allocator: mem.Allocator, stations: *std.StringHashMap(*std.BufSet), states_needed: *std.BufSet) ![][]const u8 {
|
|
var final_stations = std.BufSet.init(allocator);
|
|
|
|
while (states_needed.count() > 0) {
|
|
var best_station: []const u8 = undefined;
|
|
var states_covered: [][]const u8 = &[_][]const u8{};
|
|
|
|
var it = stations.iterator();
|
|
while (it.next()) |station| {
|
|
var covered = &std.ArrayList([]const u8).init(allocator);
|
|
try intersect(states_needed, station.value_ptr.*, covered);
|
|
if (covered.items.len > states_covered.len) {
|
|
best_station = station.key_ptr.*;
|
|
states_covered = covered.items;
|
|
} else covered.deinit();
|
|
}
|
|
|
|
difference(states_needed, states_covered);
|
|
try final_stations.insert(best_station);
|
|
}
|
|
|
|
var final_array = std.ArrayList([]const u8).init(allocator);
|
|
var i = final_stations.iterator();
|
|
while (i.next()) |key| {
|
|
try final_array.append(key.*);
|
|
}
|
|
|
|
return final_array.toOwnedSlice();
|
|
}
|
|
|
|
fn intersect(left: *std.BufSet, right: *std.BufSet, intersection: *std.ArrayList([]const u8)) !void {
|
|
var l_it = left.iterator();
|
|
var r_it = right.iterator();
|
|
while (l_it.next()) |l| {
|
|
while (r_it.next()) |r| {
|
|
if (std.mem.eql(u8, l.*, r.*)) {
|
|
try intersection.append(l.*);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn difference(lessening: *std.BufSet, subtracting: [][]const u8) void {
|
|
var less_it = lessening.iterator();
|
|
|
|
while (less_it.next()) |less| {
|
|
for (subtracting) |sub| {
|
|
if (std.mem.eql(u8, less.*, sub)) {
|
|
lessening.remove(less.*);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
test "setCovering" {
|
|
var gpa = heap.GeneralPurposeAllocator(.{}){};
|
|
var arena = heap.ArenaAllocator.init(gpa.allocator());
|
|
defer {
|
|
arena.deinit();
|
|
const leaked = gpa.deinit();
|
|
if (leaked) std.testing.expect(false) catch @panic("TEST FAIL"); //fail test; can't try in defer as defer is executed after we return
|
|
}
|
|
|
|
var states_needed_array = [_][]const u8{ "mt", "wa", "or", "id", "nv", "ut", "ca", "az" };
|
|
var states_needed = std.BufSet.init(arena.allocator());
|
|
for (states_needed_array) |sn| {
|
|
try states_needed.insert(sn);
|
|
}
|
|
|
|
var stations = std.StringHashMap(*std.BufSet).init(arena.allocator());
|
|
|
|
var kone = std.BufSet.init(arena.allocator());
|
|
try kone.insert("id");
|
|
try kone.insert("nv");
|
|
try kone.insert("ut");
|
|
try stations.put("kone", &kone);
|
|
|
|
var ktwo = std.BufSet.init(arena.allocator());
|
|
try ktwo.insert("wa");
|
|
try ktwo.insert("id");
|
|
try ktwo.insert("mt");
|
|
try stations.put("ktwo", &ktwo);
|
|
|
|
var kthree = std.BufSet.init(arena.allocator());
|
|
try kthree.insert("or");
|
|
try kthree.insert("nv");
|
|
try kthree.insert("ca");
|
|
try stations.put("kthree", &kthree);
|
|
|
|
var kfour = std.BufSet.init(arena.allocator());
|
|
try kfour.insert("nv");
|
|
try kfour.insert("ut");
|
|
try stations.put("kfour", &kfour);
|
|
|
|
var kfive = std.BufSet.init(arena.allocator());
|
|
try kfive.insert("ca");
|
|
try kfive.insert("az");
|
|
try stations.put("kfive", &kfive);
|
|
|
|
var stations_covering = try setCovering(arena.allocator(), &stations, &states_needed);
|
|
|
|
var expectedStations = &[_][]const u8{ "kone", "ktwo", "kfive", "kthree" };
|
|
for (stations_covering) |sc, i| {
|
|
try std.testing.expectEqualStrings(expectedStations[i], sc);
|
|
}
|
|
}
|