diff --git a/src/lib.zig b/src/lib.zig index 9f414ef..0c4e650 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -1,6 +1,8 @@ const std = @import("std"); const rand = std.crypto.random; +const markov_data = @embedFile("markov.bin"); + pub const DataPoint = struct { char: u8, prob: f32, @@ -15,23 +17,31 @@ pub const MarkovChain = struct { allocator: std.mem.Allocator, map: std.AutoHashMap(u8, []DataPoint), - pub fn init(path: []const u8, allocator: std.mem.Allocator) !MarkovChain { + pub fn fromFile(path: []const u8, allocator: std.mem.Allocator) !MarkovChain { + var markovBinFile = try std.fs.cwd().openFile(path, .{ .mode = .read_only }); + const reader = markovBinFile.reader(); + + return try fromReader(&reader, allocator); + } + + pub fn fromMemory(data: []const u8, allocator: std.mem.Allocator) !MarkovChain { + var stream = std.io.fixedBufferStream(data); + const reader = stream.reader(); + + return try fromReader(reader, allocator); + } + + fn fromReader(reader: anytype, allocator: std.mem.Allocator) !MarkovChain { var self = MarkovChain{ .allocator = allocator, .map = std.AutoHashMap(u8, []DataPoint).init(allocator), }; - var markovBinFile = try std.fs.cwd().openFile(path, .{ .mode = .read_only }); - - var reader = markovBinFile.reader(); - for (0..256) |prevChar| { const cnt = try reader.readInt(u8, .little); - //std.debug.print("previous : {c} - cnt : {d}\n", .{ @as(u8, @intCast(prevChar)), cnt }); var nextChars: []DataPoint = try self.allocator.alloc(DataPoint, cnt); for (0..cnt) |i| { const nextByte = try reader.readByte(); - //std.debug.print("next : {c}\n", .{nextByte}); const prob: f32 = @bitCast(try reader.readInt(u32, .little)); nextChars[i] = DataPoint{ .char = nextByte, @@ -41,8 +51,6 @@ pub const MarkovChain = struct { try self.map.put(@as(u8, @intCast(prevChar)), nextChars); } - //std.debug.print("choices for A : {any}\n", .{self.map.get(97).?}); - return self; } @@ -74,19 +82,36 @@ pub const MarkovChain = struct { } }; -test "basic test" { +test "basic test from file" { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); defer { _ = gpa.deinit(); } - var markov = try MarkovChain.init("markov.bin", allocator); + var markov = try MarkovChain.fromFile("markov.bin", allocator); defer markov.deinit(); - for (0..24) |_| { + for (0..6) |_| { const randName = try markov.generate(8, allocator); defer allocator.free(randName); - std.debug.print("generated : {s}\n", .{randName}); + std.debug.print("generated from file: {s}\n", .{randName}); + } +} + +test "basic test from embedded file" { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const allocator = gpa.allocator(); + defer { + _ = gpa.deinit(); + } + + var markov = try MarkovChain.fromMemory(markov_data, allocator); + defer markov.deinit(); + + for (0..6) |_| { + const randName = try markov.generate(8, allocator); + defer allocator.free(randName); + std.debug.print("generated from memory: {s}\n", .{randName}); } } diff --git a/src/markov.bin b/src/markov.bin new file mode 100644 index 0000000..e33f0de Binary files /dev/null and b/src/markov.bin differ