79 lines
2.1 KiB
Zig
79 lines
2.1 KiB
Zig
const std = @import("std");
|
|
|
|
pub fn main() !void {
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
const allocator = gpa.allocator();
|
|
defer _ = gpa.deinit();
|
|
|
|
const examples = [_][]const u8{ "broood", "bananaaa", "hiphophiphop" };
|
|
|
|
for (examples) |example| {
|
|
const encoded = try encode(allocator, example);
|
|
defer allocator.free(encoded);
|
|
|
|
const decoded = try decode(allocator, encoded);
|
|
defer allocator.free(decoded);
|
|
|
|
std.debug.print("{s} encodes to {any} decodes to {s}\n", .{ example, encoded, decoded });
|
|
}
|
|
}
|
|
|
|
fn getSymbols(allocator: std.mem.Allocator) ![]u8 {
|
|
var symbols = std.ArrayList(u8).init(allocator);
|
|
errdefer symbols.deinit();
|
|
|
|
var c: u8 = 'a';
|
|
while (c <= 'z') : (c += 1) {
|
|
try symbols.append(c);
|
|
}
|
|
|
|
return symbols.toOwnedSlice();
|
|
}
|
|
|
|
fn encode(allocator: std.mem.Allocator, input: []const u8) ![]usize {
|
|
var output = std.ArrayList(usize).init(allocator);
|
|
errdefer output.deinit();
|
|
|
|
var symbols = try getSymbols(allocator);
|
|
defer allocator.free(symbols);
|
|
|
|
for (input) |byte| {
|
|
// Find position of the byte in symbols
|
|
var position: usize = 0;
|
|
for (symbols, 0..) |symbol, i| {
|
|
if (symbol == byte) {
|
|
position = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Remove the byte at the position
|
|
const char = symbols[position];
|
|
std.mem.copyForwards(u8, symbols[1..position + 1], symbols[0..position]);
|
|
symbols[0] = char;
|
|
|
|
try output.append(position);
|
|
}
|
|
|
|
return output.toOwnedSlice();
|
|
}
|
|
|
|
fn decode(allocator: std.mem.Allocator, input: []const usize) ![]u8 {
|
|
var output = std.ArrayList(u8).init(allocator);
|
|
errdefer output.deinit();
|
|
|
|
var symbols = try getSymbols(allocator);
|
|
defer allocator.free(symbols);
|
|
|
|
for (input) |position| {
|
|
try output.append(symbols[position]);
|
|
|
|
// Remove the byte at the position
|
|
const char = symbols[position];
|
|
std.mem.copyForwards(u8, symbols[1..position + 1], symbols[0..position]);
|
|
symbols[0] = char;
|
|
}
|
|
|
|
return output.toOwnedSlice();
|
|
}
|