-
Notifications
You must be signed in to change notification settings - Fork 343
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #407 from zierf/zig_rust_improvements
Rust & Zig: Various Improvements
- Loading branch information
Showing
14 changed files
with
175 additions
and
176 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
pub fn fibonacci(n: usize) usize { | ||
return switch (n) { | ||
0...1 => n, | ||
else => fibonacci(n - 1) + fibonacci(n - 2), | ||
}; | ||
pub fn fibonacci(comptime T: type) fn (T) T { | ||
return struct { | ||
pub fn fib(n: T) T { | ||
return switch (n) { | ||
0...1 => n, | ||
else => fib(n - 1) + fib(n - 2), | ||
}; | ||
} | ||
}.fib; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,62 @@ | ||
const std = @import("std"); | ||
const Allocator = std.mem.Allocator; | ||
|
||
/// Calculates the Levenshtein distance between two strings using Wagner-Fischer algorithm | ||
/// Calculates the Levenshtein distance between two strings using Wagner-Fischer algorithm. | ||
/// | ||
/// Space Complexity: O(min(m,n)) - only uses two arrays instead of full matrix | ||
/// Time Complexity: O(m*n) where m and n are the lengths of the input strings | ||
pub fn levenshteinDistance(s1: *const []const u8, s2: *const []const u8, buffer: *const []usize) usize { | ||
// Early termination checks | ||
if (s1.*.len == 0) return s2.*.len; | ||
if (s2.*.len == 0) return s1.*.len; | ||
|
||
// Make s1 the shorter string for space optimization | ||
const str1, const str2 = init: { | ||
if (s1.*.len > s2.*.len) { | ||
break :init .{ s2.*, s1.* }; | ||
/// Time Complexity: O(m*n) - where m and n are the lengths of the input strings | ||
pub fn levenshteinDistance(comptime T: type) (fn (allocator: Allocator, s1: *const []const u8, s2: *const []const u8) T) { | ||
return struct { | ||
pub fn levenshtein(allocator: Allocator, s1: *const []const u8, s2: *const []const u8) T { | ||
// early termination checks | ||
if (s1.*.len == 0) return @intCast(s2.*.len); | ||
if (s2.*.len == 0) return @intCast(s1.*.len); | ||
|
||
// make s1 the shorter string for space optimization | ||
const str1, const str2 = init: { | ||
if (s1.*.len > s2.*.len) { | ||
break :init .{ s2.*, s1.* }; | ||
} | ||
|
||
break :init .{ s1.*, s2.* }; | ||
}; | ||
|
||
const m = str1.len; | ||
const n = str2.len; | ||
|
||
const row_elements = m + 1; | ||
|
||
// use two rows instead of full matrix for space optimization | ||
var prev_row: []T = allocator.alloc(T, row_elements) catch unreachable; | ||
var curr_row: []T = allocator.alloc(T, row_elements) catch unreachable; | ||
defer allocator.free(prev_row); | ||
defer allocator.free(curr_row); | ||
|
||
// initialize first row | ||
for (0..m + 1) |i| { | ||
prev_row[i] = @intCast(i); | ||
} | ||
|
||
// main computation loop | ||
for (str2, 0..n) |ch2, j| { | ||
curr_row[0] = @as(T, @intCast(j)) + 1; | ||
|
||
for (str1, 0..m) |ch1, i| { | ||
const cost: T = @intFromBool(ch1 != ch2); | ||
|
||
// calculate minimum of three operations | ||
curr_row[i + 1] = @min( | ||
prev_row[i + 1] + 1, // deletion | ||
curr_row[i] + 1, // insertion | ||
prev_row[i] + cost, // substitution | ||
); | ||
} | ||
|
||
// swap rows | ||
std.mem.swap([]T, &prev_row, &curr_row); | ||
} | ||
|
||
return prev_row[m]; | ||
} | ||
|
||
break :init .{ s1.*, s2.* }; | ||
}; | ||
|
||
const m = str1.len; | ||
const n = str2.len; | ||
|
||
var prev_row = buffer.*[0..(m + 1)]; | ||
var curr_row = buffer.*[(m + 1)..]; | ||
|
||
// Initialize first row | ||
for (0..m + 1) |i| { | ||
prev_row[i] = i; | ||
} | ||
|
||
// Main computation loop | ||
for (str2, 0..n) |ch2, j| { | ||
curr_row[0] = j + 1; | ||
|
||
for (str1, 0..m) |ch1, i| { | ||
const cost: usize = @intFromBool(ch1 != ch2); | ||
|
||
// Calculate minimum of three operations | ||
curr_row[i + 1] = @min( | ||
prev_row[i + 1] + 1, // deletion | ||
curr_row[i] + 1, // insertion | ||
prev_row[i] + cost, // substitution | ||
); | ||
} | ||
|
||
// Swap rows | ||
std.mem.swap([]usize, &prev_row, &curr_row); | ||
} | ||
|
||
return prev_row[m]; | ||
}.levenshtein; | ||
} |
Oops, something went wrong.