summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jose Colon Rodriguez2024-02-12 06:48:45 -0400
committerGravatar Jose Colon Rodriguez2024-02-12 06:48:45 -0400
commit32e2303b67ab28aade9d6b2fd75953d966bd2c68 (patch)
tree51f6a4dfef1fe2495da8364600d201b8bedc8816 /src
parentinit (diff)
downloadzg-32e2303b67ab28aade9d6b2fd75953d966bd2c68.tar.gz
zg-32e2303b67ab28aade9d6b2fd75953d966bd2c68.tar.xz
zg-32e2303b67ab28aade9d6b2fd75953d966bd2c68.zip
Created Trie
Diffstat (limited to 'src')
-rw-r--r--src/main.zig4
-rw-r--r--src/trie.zig81
2 files changed, 85 insertions, 0 deletions
diff --git a/src/main.zig b/src/main.zig
index 5de7458..b517641 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -17,3 +17,7 @@ pub fn main() !void {
17 17
18 std.debug.print("result: {}, took: {}\n", .{ result, timer.lap() / std.time.ns_per_ms }); 18 std.debug.print("result: {}, took: {}\n", .{ result, timer.lap() / std.time.ns_per_ms });
19} 19}
20
21test {
22 _ = @import("trie.zig");
23}
diff --git a/src/trie.zig b/src/trie.zig
new file mode 100644
index 0000000..ee77954
--- /dev/null
+++ b/src/trie.zig
@@ -0,0 +1,81 @@
1const std = @import("std");
2const mem = std.mem;
3
4pub const Color = enum { red, blue };
5
6pub const Node = struct {
7 children: [256]?*Node = [_]?*Node{null} ** 256,
8 value: ?Color = null,
9};
10
11pub const Trie = struct {
12 allocator: mem.Allocator,
13 root: Node,
14 node_count: usize = 0,
15
16 fn asBytes(cp: u24) []const u8 {
17 const bytes: [3]u8 = @bitCast(cp);
18
19 return if (bytes[0] < 128)
20 bytes[0..1]
21 else if (bytes[1] == 0)
22 bytes[0..1]
23 else if (bytes[2] == 0)
24 bytes[0..2]
25 else
26 bytes[0..];
27 }
28
29 pub fn put(self: *Trie, cp: u24, v: Color) !void {
30 const s = asBytes(cp);
31 var current: *Node = &self.root;
32
33 for (s, 0..) |b, i| {
34 if (current.children[b]) |n| {
35 if (i == s.len - 1) {
36 n.value = v;
37 return;
38 }
39
40 current = n;
41 continue;
42 }
43
44 self.node_count += 1;
45 const new_node = try self.allocator.create(Node);
46 new_node.* = .{ .value = if (i == s.len - 1) v else null };
47 current.children[b] = new_node;
48 current = new_node;
49 }
50 }
51
52 pub fn get(self: Trie, cp: u24) ?Color {
53 const s = asBytes(cp);
54 var current = &self.root;
55
56 return for (s, 0..) |b, i| {
57 if (current.children[b]) |n| {
58 if (i == s.len - 1) break if (n.value) |v| v else null;
59 current = n;
60 }
61 } else null;
62 }
63};
64
65test "Trie works" {
66 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
67 defer arena.deinit();
68 const allocator = arena.allocator();
69
70 var trie = Trie{ .allocator = allocator, .root = .{} };
71
72 const cp_1: u21 = '\u{10ffff}';
73 const cp_2: u21 = '\u{10ff}';
74 const cp_3: u21 = '\u{10}';
75
76 try trie.put(cp_1, .red);
77 try trie.put(cp_3, .blue);
78 try std.testing.expectEqual(@as(?Color, .red), trie.get(cp_1));
79 try std.testing.expectEqual(@as(?Color, null), trie.get(cp_2));
80 try std.testing.expectEqual(@as(?Color, .blue), trie.get(cp_3));
81}