diff --git a/README.md b/README.md index d14729c..6f9825d 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,10 @@ This repo also contains Visual Studio Code project files for debugging. These a If you would like to contribute project files for other development environments, please send a PR. +## Modifying the template + +You can modify the template to add your own changes across all days. To do so, modify template/template.zig and then run `zig build generate`. The `$` character in the template will be replaced by the two-digit day number (e.g. 04 or 17). This step will only overwrite files which have not been modified, so you will not lose work if you update the template after implementing several days. After updating the template and generating, you should check in template/hashes.bin in addition to the updated template and source files. This will ensure that the newly generated files are not considered modified if you update the template again. + ## Setting up ZLS Zig has a reasonably robust language server, which can provide autocomplete for VSCode and many other editors. It can help significantly with exploring the std lib and suggesting parameter completions. The VSCode extension (augusterame.zls-vscode) will automatically install the language server in the background. If you are using a different editor, follow their [install instructions](https://zigtools.github.io/install-zls/). If you want to install a specific version of the language server (for example for maximum compatibility with 0.10.0), [check their releases page](https://github.com/zigtools/zls/releases) or [follow their instructions to build from source](https://github.com/zigtools/zls#from-source). Note that ZLS tracks master, so if you are using Zig 0.10.0 you may need to download a newer version to build ZLS. diff --git a/build.zig b/build.zig index 31aa471..e01a152 100644 --- a/build.zig +++ b/build.zig @@ -41,6 +41,13 @@ pub fn build(b: *Builder) void { const install_all_tests = b.step("install_tests_all", "Install tests for all days"); const run_all = b.step("run_all", "Run all days"); + const generate = b.step("generate", "Generate stub files from template/template.zig"); + const build_generate = b.addExecutable("generate", "template/generate.zig"); + build_generate.setBuildMode(.ReleaseSafe); + const run_generate = build_generate.run(); + run_generate.cwd = std.fs.path.dirname(@src().file).?; + generate.dependOn(&run_generate.step); + // Set up an exe for each day var day: u32 = 1; while (day <= 25) : (day += 1) { diff --git a/src/day01.zig b/src/day01.zig index b2d5b77..e454915 100644 --- a/src/day01.zig +++ b/src/day01.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -12,7 +11,7 @@ const gpa = util.gpa; const data = @embedFile("../data/day01.txt"); pub fn main() !void { - + } // Useful stdlib functions @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day02.zig b/src/day02.zig index 7a6ba57..979d0db 100644 --- a/src/day02.zig +++ b/src/day02.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day03.zig b/src/day03.zig index e1c4c46..fe63378 100644 --- a/src/day03.zig +++ b/src/day03.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day04.zig b/src/day04.zig index 8ba3c9d..c9ab677 100644 --- a/src/day04.zig +++ b/src/day04.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day05.zig b/src/day05.zig index deaf893..ce9f516 100644 --- a/src/day05.zig +++ b/src/day05.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day06.zig b/src/day06.zig index 68f8ecd..2db2f2e 100644 --- a/src/day06.zig +++ b/src/day06.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day07.zig b/src/day07.zig index 9f19621..33c6a09 100644 --- a/src/day07.zig +++ b/src/day07.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day08.zig b/src/day08.zig index 103b835..e02d43b 100644 --- a/src/day08.zig +++ b/src/day08.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day09.zig b/src/day09.zig index cbae5ba..506abb3 100644 --- a/src/day09.zig +++ b/src/day09.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day10.zig b/src/day10.zig index 4922906..26de46c 100644 --- a/src/day10.zig +++ b/src/day10.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day11.zig b/src/day11.zig index 6e7dd52..bdc5dcc 100644 --- a/src/day11.zig +++ b/src/day11.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day12.zig b/src/day12.zig index f6836d0..8cce6f1 100644 --- a/src/day12.zig +++ b/src/day12.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day13.zig b/src/day13.zig index d9c017f..f040aa9 100644 --- a/src/day13.zig +++ b/src/day13.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day14.zig b/src/day14.zig index d791082..67321e1 100644 --- a/src/day14.zig +++ b/src/day14.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day15.zig b/src/day15.zig index 3b9f098..87f69be 100644 --- a/src/day15.zig +++ b/src/day15.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day16.zig b/src/day16.zig index f5f9671..9d88df5 100644 --- a/src/day16.zig +++ b/src/day16.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day17.zig b/src/day17.zig index 3c5187c..c13295f 100644 --- a/src/day17.zig +++ b/src/day17.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day18.zig b/src/day18.zig index e2c4d36..cb6c80a 100644 --- a/src/day18.zig +++ b/src/day18.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day19.zig b/src/day19.zig index e247aac..e1a6664 100644 --- a/src/day19.zig +++ b/src/day19.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day20.zig b/src/day20.zig index f7a9ac4..09c608c 100644 --- a/src/day20.zig +++ b/src/day20.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day21.zig b/src/day21.zig index af7d628..8eaba73 100644 --- a/src/day21.zig +++ b/src/day21.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day22.zig b/src/day22.zig index fb4986f..c385662 100644 --- a/src/day22.zig +++ b/src/day22.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day23.zig b/src/day23.zig index b1ecf7d..a006e00 100644 --- a/src/day23.zig +++ b/src/day23.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day24.zig b/src/day24.zig index caabe67..5fe1477 100644 --- a/src/day24.zig +++ b/src/day24.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/src/day25.zig b/src/day25.zig index 768b4d9..3d653cc 100644 --- a/src/day25.zig +++ b/src/day25.zig @@ -4,7 +4,6 @@ const List = std.ArrayList; const Map = std.AutoHashMap; const StrMap = std.StringHashMap; const BitSet = std.DynamicBitSet; -const Str = []const u8; const util = @import("util.zig"); const gpa = util.gpa; @@ -42,3 +41,7 @@ const assert = std.debug.assert; const sort = std.sort.sort; const asc = std.sort.asc; const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated. diff --git a/template/generate.zig b/template/generate.zig new file mode 100644 index 0000000..c047e77 --- /dev/null +++ b/template/generate.zig @@ -0,0 +1,126 @@ +const std = @import("std"); + +const max_size = 100_000_000; +var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + +const Hash = std.crypto.hash.Md5; +const hashes_file = "template/hashes.bin"; + +fn instantiateTemplate(template: []const u8, day: u32) ![]const u8 { + var list = std.ArrayList(u8).init(gpa.allocator()); + errdefer list.deinit(); + + try list.ensureTotalCapacity(template.len + 100); + var rest: []const u8 = template; + while (std.mem.indexOfScalar(u8, rest, '$')) |index| { + try list.appendSlice(rest[0..index]); + try std.fmt.format(list.writer(), "{d:0>2}", .{day}); + rest = rest[index+1..]; + } + try list.appendSlice(rest); + return list.toOwnedSlice(); +} + +fn readHashes() !*[25][Hash.digest_length]u8 { + const hash_bytes = std.fs.cwd().readFileAlloc(gpa.allocator(), hashes_file, 25 * Hash.digest_length) catch |err| switch (err) { + error.FileTooBig => return error.InvalidFormat, + else => |e| return e, + }; + errdefer gpa.allocator().free(hash_bytes); + + if (hash_bytes.len != 25 * Hash.digest_length) + return error.InvalidFormat; + + return @ptrCast(*[25][Hash.digest_length]u8, hash_bytes.ptr); +} + +pub fn main() !void { + const template = try std.fs.cwd().readFileAlloc(gpa.allocator(), "template/template.zig", max_size); + + const hashes: *[25][Hash.digest_length]u8 = readHashes() catch |err| switch (err) { + error.FileNotFound => blk: { + std.debug.print("{s} doesn't exist, will assume all files have been modified.\nDelete src/dayXX.zig and rerun `zig build generate` to regenerate it.\n", .{hashes_file}); + const mem = try gpa.allocator().create([25][Hash.digest_length]u8); + @memset(@ptrCast([*]u8, mem), 0, @sizeOf(@TypeOf(mem.*))); + break :blk mem; + }, + error.InvalidFormat => { + std.debug.print("{s} is corrupted, delete it to silence this warning and assume all days have been modified.\n", .{hashes_file}); + std.os.exit(1); + }, + else => |e| { + std.debug.print("Failed to open {s}: {}\n", .{hashes_file, e}); + return e; + }, + }; + + var skipped_any = false; + var updated_hashes = false; + var day: u32 = 1; + while (day <= 25) : (day += 1) { + const filename = try std.fmt.allocPrint(gpa.allocator(), "src/day{d:0>2}.zig", .{day}); + defer gpa.allocator().free(filename); + + var new_file = false; + const file = std.fs.cwd().openFile(filename, .{.mode = .read_write}) catch |err| switch (err) { + error.FileNotFound => blk: { + new_file = true; + break :blk try std.fs.cwd().createFile(filename, .{}); + }, + else => |e| return e, + }; + defer file.close(); + + var regenerate = false; + if (!new_file) { + const contents = file.readToEndAlloc(gpa.allocator(), max_size) catch |err| switch (err) { + error.FileTooBig => { + std.debug.print("Skipping modified day {s}\n", .{filename}); + skipped_any = true; + continue; + }, + else => |e| return e, + }; + defer gpa.allocator().free(contents); + + var hash: [Hash.digest_length]u8 = undefined; + Hash.hash(contents, &hash, .{}); + + regenerate = std.mem.eql(u8, &hash, &hashes[day-1]); + } else { + regenerate = true; + } + + if (regenerate) { + if (!new_file) { + try file.seekTo(0); + try file.setEndPos(0); + } + + const text = try instantiateTemplate(template, day); + defer gpa.allocator().free(text); + + Hash.hash(text, &hashes[day-1], .{}); + updated_hashes = true; + + try file.writeAll(text); + if (new_file) { + std.debug.print("Creating new file {s} from template.\n", .{filename}); + } else { + std.debug.print("Updated {s}\n", .{filename}); + } + } else { + std.debug.print("Skipping modified day {s}\n", .{filename}); + skipped_any = true; + } + } + + if (updated_hashes) { + try std.fs.cwd().writeFile(hashes_file, std.mem.asBytes(hashes)); + if (skipped_any) { + std.debug.print("Some days were skipped. Delete them to force regeneration.\n",.{}); + } + } else { + std.debug.print("No updates made, all days were modified. Delete src/dayXX.zig to force regeneration.\n", .{}); + } +} \ No newline at end of file diff --git a/template/hashes.bin b/template/hashes.bin new file mode 100644 index 0000000..6fa6b9d --- /dev/null +++ b/template/hashes.bin @@ -0,0 +1,5 @@ +lgŵ<uZY1fsyQ>:Y죡c:ŝG2O&rs%cҨ}2u, + =z# /!D4&]w*q( +D+YW^s(4DM).PJouZ\u 6(A% yl 6J  K~O"-oȃH;3 s<%[:/b"YP *_qd%!\VgQ-4}?7 +AKs:vK,S"b_-!#J}PhG 77ѿχtM 6b +diĚ\Vy9`qdf^bo_.@` \ No newline at end of file diff --git a/template/template.zig b/template/template.zig new file mode 100644 index 0000000..ba9fbdf --- /dev/null +++ b/template/template.zig @@ -0,0 +1,47 @@ +const std = @import("std"); +const Allocator = std.mem.Allocator; +const List = std.ArrayList; +const Map = std.AutoHashMap; +const StrMap = std.StringHashMap; +const BitSet = std.DynamicBitSet; + +const util = @import("util.zig"); +const gpa = util.gpa; + +const data = @embedFile("../data/day$.txt"); + +pub fn main() !void { + +} + +// Useful stdlib functions +const tokenize = std.mem.tokenize; +const split = std.mem.split; +const indexOf = std.mem.indexOfScalar; +const indexOfAny = std.mem.indexOfAny; +const indexOfStr = std.mem.indexOfPosLinear; +const lastIndexOf = std.mem.lastIndexOfScalar; +const lastIndexOfAny = std.mem.lastIndexOfAny; +const lastIndexOfStr = std.mem.lastIndexOfLinear; +const trim = std.mem.trim; +const sliceMin = std.mem.min; +const sliceMax = std.mem.max; + +const parseInt = std.fmt.parseInt; +const parseFloat = std.fmt.parseFloat; + +const min = std.math.min; +const min3 = std.math.min3; +const max = std.math.max; +const max3 = std.math.max3; + +const print = std.debug.print; +const assert = std.debug.assert; + +const sort = std.sort.sort; +const asc = std.sort.asc; +const desc = std.sort.desc; + +// Generated from template/template.zig. +// Run `zig build generate` to update. +// Only unmodified days will be updated.