add initialisation method from embedde file

This commit is contained in:
Fabien Masson 2025-08-15 16:20:07 +02:00
parent 18df017371
commit d072597431
2 changed files with 38 additions and 13 deletions

View File

@ -1,6 +1,8 @@
const std = @import("std"); const std = @import("std");
const rand = std.crypto.random; const rand = std.crypto.random;
const markov_data = @embedFile("markov.bin");
pub const DataPoint = struct { pub const DataPoint = struct {
char: u8, char: u8,
prob: f32, prob: f32,
@ -15,23 +17,31 @@ pub const MarkovChain = struct {
allocator: std.mem.Allocator, allocator: std.mem.Allocator,
map: std.AutoHashMap(u8, []DataPoint), 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{ var self = MarkovChain{
.allocator = allocator, .allocator = allocator,
.map = std.AutoHashMap(u8, []DataPoint).init(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| { for (0..256) |prevChar| {
const cnt = try reader.readInt(u8, .little); 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); var nextChars: []DataPoint = try self.allocator.alloc(DataPoint, cnt);
for (0..cnt) |i| { for (0..cnt) |i| {
const nextByte = try reader.readByte(); const nextByte = try reader.readByte();
//std.debug.print("next : {c}\n", .{nextByte});
const prob: f32 = @bitCast(try reader.readInt(u32, .little)); const prob: f32 = @bitCast(try reader.readInt(u32, .little));
nextChars[i] = DataPoint{ nextChars[i] = DataPoint{
.char = nextByte, .char = nextByte,
@ -41,8 +51,6 @@ pub const MarkovChain = struct {
try self.map.put(@as(u8, @intCast(prevChar)), nextChars); try self.map.put(@as(u8, @intCast(prevChar)), nextChars);
} }
//std.debug.print("choices for A : {any}\n", .{self.map.get(97).?});
return self; return self;
} }
@ -74,19 +82,36 @@ pub const MarkovChain = struct {
} }
}; };
test "basic test" { test "basic test from file" {
var gpa = std.heap.GeneralPurposeAllocator(.{}){}; var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator(); const allocator = gpa.allocator();
defer { defer {
_ = gpa.deinit(); _ = gpa.deinit();
} }
var markov = try MarkovChain.init("markov.bin", allocator); var markov = try MarkovChain.fromFile("markov.bin", allocator);
defer markov.deinit(); defer markov.deinit();
for (0..24) |_| { for (0..6) |_| {
const randName = try markov.generate(8, allocator); const randName = try markov.generate(8, allocator);
defer allocator.free(randName); 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});
} }
} }

BIN
src/markov.bin Normal file

Binary file not shown.