diff options
| -rw-r--r-- | .devcontainer/devcontainer.json | 31 | ||||
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | build.zig | 74 | ||||
| -rw-r--r-- | exercises/046_optionals2.zig | 2 | ||||
| -rw-r--r-- | exercises/058_quiz7.zig | 2 | ||||
| -rw-r--r-- | exercises/065_builtins2.zig | 20 | ||||
| -rw-r--r-- | exercises/099_formatting.zig | 2 | ||||
| -rw-r--r-- | exercises/100_for4.zig | 4 | ||||
| -rw-r--r-- | exercises/105_threading2.zig | 2 | ||||
| -rw-r--r-- | exercises/106_files.zig | 2 | ||||
| -rw-r--r-- | exercises/107_files2.zig | 2 | ||||
| -rw-r--r-- | exercises/108_labeled_switch.zig | 20 | ||||
| -rw-r--r-- | exercises/109_vectors.zig | 147 | ||||
| -rwxr-xr-x | patches/eowyn.sh | 14 | ||||
| -rw-r--r-- | patches/patches/046_optionals2.patch | 4 | ||||
| -rw-r--r-- | patches/patches/058_quiz7.patch | 6 | ||||
| -rw-r--r-- | patches/patches/065_builtins2.patch | 10 | ||||
| -rw-r--r-- | patches/patches/099_formatting.patch | 4 | ||||
| -rw-r--r-- | patches/patches/100_for4.patch | 2 | ||||
| -rw-r--r-- | patches/patches/106_files.patch | 8 | ||||
| -rw-r--r-- | patches/patches/107_files2.patch | 2 | ||||
| -rw-r--r-- | patches/patches/109_vectors.patch | 13 |
23 files changed, 298 insertions, 79 deletions
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index beea353..0000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,31 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/debian -{ - "name": "Ziglings", - // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "image": "mcr.microsoft.com/devcontainers/base:bullseye", - "features": { - "ghcr.io/devcontainers-contrib/features/zig:1": { - "version": "master" - } - }, - "customizations": { - "vscode": { - "extensions": [ - "ziglang.vscode-zig" - ] - } - } - - // Features to add to the dev container. More info: https://containers.dev/features. - // "features": {}, - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - - // Configure tool-specific properties. - // "customizations": {}, - - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" -} @@ -3,6 +3,7 @@ /answers/ /patches/healed/ /output/ +.progress.txt # Leave this in here for older zig versions /zig-cache/ @@ -173,6 +173,11 @@ zig build -Dn=19 -l ... ``` +To reset the progress (have it run all the exercises that have already been completed): +``` +zig build -Dreset +``` + ## What's Covered The primary goal for Ziglings is to cover the core Zig language. @@ -120,6 +120,8 @@ pub const logo = \\ ; +const progress_filename = ".progress.txt"; + pub fn build(b: *Build) !void { if (!validate_exercises()) std.process.exit(2); @@ -162,6 +164,7 @@ pub fn build(b: *Build) !void { const exno: ?usize = b.option(usize, "n", "Select exercise"); const rand: ?bool = b.option(bool, "random", "Select random exercise"); const start: ?usize = b.option(usize, "s", "Start at exercise"); + const reset: ?bool = b.option(bool, "reset", "Reset exercise progress"); const sep = std.fs.path.sep_str; const healed_path = if (override_healed_path) |path| @@ -242,17 +245,62 @@ pub fn build(b: *Build) !void { return; } + if (reset) |_| { + std.fs.cwd().deleteFile(progress_filename) catch |err| { + switch (err) { + std.fs.Dir.DeleteFileError.FileNotFound => {}, + else => { + print("Unable to remove progress file, Error: {}\n", .{err}); + return err; + }, + } + }; + + print("Progress reset, {s} removed.\n", .{progress_filename}); + std.process.exit(0); + } + // Normal build mode: verifies all exercises according to the recommended // order. const ziglings_step = b.step("ziglings", "Check all ziglings"); b.default_step = ziglings_step; var prev_step = &header_step.step; + + var starting_exercise: u32 = 0; + + if (std.fs.cwd().openFile(progress_filename, .{})) |progress_file| { + defer progress_file.close(); + + const progress_file_size = try progress_file.getEndPos(); + + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + const contents = try progress_file.readToEndAlloc(allocator, progress_file_size); + defer allocator.free(contents); + + starting_exercise = try std.fmt.parseInt(u32, contents, 10); + } else |err| { + switch (err) { + + std.fs.File.OpenError.FileNotFound => { + // This is fine, may be the first time tests are run or progress have been reset + }, + else => { + print("Unable to open {s}: {}\n", .{progress_filename, err}); + return err; + }, + } + } + for (exercises) |ex| { - const verify_stepn = ZiglingStep.create(b, ex, work_path, .normal); - verify_stepn.step.dependOn(prev_step); + if (starting_exercise < ex.number()) { + const verify_stepn = ZiglingStep.create(b, ex, work_path, .normal); + verify_stepn.step.dependOn(prev_step); - prev_step = &verify_stepn.step; + prev_step = &verify_stepn.step; + } } ziglings_step.dependOn(prev_step); @@ -403,6 +451,18 @@ const ZiglingStep = struct { , .{ red, reset, exercise_output, red, reset, output, red, reset }); } + const progress = try std.fmt.allocPrint(b.allocator, "{d}", .{self.exercise.number()}); + defer b.allocator.free(progress); + + const file = try std.fs.cwd().createFile( + progress_filename, + .{ .read = true, .truncate = true }, + ); + defer file.close(); + + try file.writeAll(progress); + try file.sync(); + print("{s}PASSED:\n{s}{s}\n\n", .{ green_text, output, reset_text }); } @@ -970,6 +1030,7 @@ const exercises = [_]Exercise{ .{ .main_file = "074_comptime9.zig", .output = "My llama value is 2.", + .skip = true, }, .{ .main_file = "075_quiz8.zig", @@ -1202,6 +1263,13 @@ const exercises = [_]Exercise{ .output = "The pull request has been merged.", }, .{ + .main_file = "109_vectors.zig", + .output = + \\Max difference (old fn): 0.014 + \\Max difference (new fn): 0.014 + , + }, + .{ .main_file = "999_the_end.zig", .output = \\ diff --git a/exercises/046_optionals2.zig b/exercises/046_optionals2.zig index a5436d9..b5fffbb 100644 --- a/exercises/046_optionals2.zig +++ b/exercises/046_optionals2.zig @@ -48,7 +48,7 @@ pub fn main() void { // If e1 and e2 are valid pointers to elephants, // this function links the elephants so that e1's tail "points" to e2. fn linkElephants(e1: ?*Elephant, e2: ?*Elephant) void { - e1.?.*.tail = e2.?; + e1.?.tail = e2.?; } // This function visits all elephants once, starting with the diff --git a/exercises/058_quiz7.zig b/exercises/058_quiz7.zig index cf32fc3..fda83fc 100644 --- a/exercises/058_quiz7.zig +++ b/exercises/058_quiz7.zig @@ -190,7 +190,7 @@ const TripItem = union(enum) { fn printMe(self: TripItem) void { switch (self) { // Oops! The hermit forgot how to capture the union values - // in a switch statement. Please capture both values as + // in a switch statement. Please capture each value as // 'p' so the print statements work! .place => print("{s}", .{p.name}), .path => print("--{}->", .{p.dist}), diff --git a/exercises/065_builtins2.zig b/exercises/065_builtins2.zig index 0790db4..6b8168c 100644 --- a/exercises/065_builtins2.zig +++ b/exercises/065_builtins2.zig @@ -110,15 +110,15 @@ pub fn main() void { // name will not be printed if the field is of type 'void' // (which is a zero-bit type that takes up no space at all!): if (fields[0].??? != void) { - print(" {s}", .{@typeInfo(Narcissus).@"struct".fields[0].name}); + print(" {s}", .{fields[0].name}); } if (fields[1].??? != void) { - print(" {s}", .{@typeInfo(Narcissus).@"struct".fields[1].name}); + print(" {s}", .{fields[1].name}); } if (fields[2].??? != void) { - print(" {s}", .{@typeInfo(Narcissus).@"struct".fields[2].name}); + print(" {s}", .{fields[2].name}); } // Yuck, look at all that repeated code above! I don't know @@ -136,14 +136,16 @@ pub fn main() void { // But a change after Zig 0.10.0 added the source file name to the // type. "Narcissus" became "065_builtins2.Narcissus". // -// To fix this, I've added this function to strip the filename from -// the front of the type name in the dumbest way possible. (It returns -// a slice of the type name starting at character 14 (assuming -// single-byte characters). +// To fix this, we've added this function to strip the filename from +// the front of the type name. (It returns a slice of the type name +// starting at the index + 1 of character ".") // // We'll be seeing @typeName again in Exercise 070. For now, you can // see that it takes a Type and returns a u8 "string". fn maximumNarcissism(myType: anytype) []const u8 { - // Turn '065_builtins2.Narcissus' into 'Narcissus' - return @typeName(myType)[14..]; + const indexOf = @import("std").mem.indexOf; + + // Turn "065_builtins2.Narcissus" into "Narcissus" + const name = @typeName(myType); + return name[indexOf(u8, name, ".").? + 1 ..]; } diff --git a/exercises/099_formatting.zig b/exercises/099_formatting.zig index 4b64209..37fab45 100644 --- a/exercises/099_formatting.zig +++ b/exercises/099_formatting.zig @@ -16,7 +16,7 @@ // Therefore, the comments for the format() function are the only // way to definitively learn how to format strings in Zig: // -// https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig#L29 +// https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig#L33 // // Zig already has a very nice selection of formatting options. // These can be used in different ways, but generally to convert diff --git a/exercises/100_for4.zig b/exercises/100_for4.zig index e0fa602..c8a1161 100644 --- a/exercises/100_for4.zig +++ b/exercises/100_for4.zig @@ -41,12 +41,12 @@ pub fn main() void { for (hex_nums, ???) |hn, ???| { if (hn != dn) { - std.debug.print("Uh oh! Found a mismatch: {d} vs {d}\n", .{ hn, dn }); + print("Uh oh! Found a mismatch: {d} vs {d}\n", .{ hn, dn }); return; } } - std.debug.print("Arrays match!\n", .{}); + print("Arrays match!\n", .{}); } // // You are perhaps wondering what happens if one of the two lists diff --git a/exercises/105_threading2.zig b/exercises/105_threading2.zig index 7ca8f5c..7e16a1c 100644 --- a/exercises/105_threading2.zig +++ b/exercises/105_threading2.zig @@ -39,7 +39,7 @@ // in practice. Because either you don't need the precision, or you use a // calculator in which the number is stored as a very precise constant. // But at some point this constant was calculated and we are doing the same -// now.The question at this point is, how many partial values do we have +// now. The question at this point is, how many partial values do we have // to calculate for which accuracy? // // The answer is chewing, to get 8 digits after the decimal point we need diff --git a/exercises/106_files.zig b/exercises/106_files.zig index f5fd1ac..b224508 100644 --- a/exercises/106_files.zig +++ b/exercises/106_files.zig @@ -9,7 +9,7 @@ // by organizing them into directories, which hold files and other directories, // thus creating a tree structure that can be navigated. // -// Fortunately, the Zig standard library provides a simple API for interacting +// Fortunately, the Zig Standard Library provides a simple API for interacting // with the file system, see the detail documentation here: // // https://ziglang.org/documentation/master/std/#std.fs diff --git a/exercises/107_files2.zig b/exercises/107_files2.zig index 45e12f5..6768898 100644 --- a/exercises/107_files2.zig +++ b/exercises/107_files2.zig @@ -40,7 +40,7 @@ pub fn main() !void { // okay, seems like a threat of violence is not the answer in this case // can you go here to find a way to read the content? // https://ziglang.org/documentation/master/std/#std.fs.File - // hint: you might find two answers that are both vaild in this case + // hint: you might find two answers that are both valid in this case const bytes_read = zig_read_the_file_or_i_will_fight_you(&content); // Woah, too screamy. I know you're excited for zigling time but tone it down a bit. diff --git a/exercises/108_labeled_switch.zig b/exercises/108_labeled_switch.zig index 88cb196..16a5879 100644 --- a/exercises/108_labeled_switch.zig +++ b/exercises/108_labeled_switch.zig @@ -15,11 +15,11 @@ // 1 => { op = 2; continue; }, // 2 => { op = 3; continue; }, // 3 => return, -// 4 => {}, +// else => {}, // } // break; // } -// std.debug.print("This statement cannot be reached"); +// std.debug.print("This statement cannot be reached\n", .{}); // } // // By combining all we've learned so far, we can now proceed with a labeled switch @@ -34,21 +34,23 @@ // 1 => continue :foo 2, // 2 => continue :foo 3, // 3 => return, -// 4 => {}, +// else => {}, // } -// std.debug.print("This statement cannot be reached"); +// std.debug.print("This statement cannot be reached\n", .{}); // } // // The flow of execution on this second case is: // 1. The switch starts with value '1'; // 2. The switch evaluates to case '1' which in turn uses the continue statement -// to re-evaluate the labeled switch again, now providing the value '2'; +// to re-evaluate the labeled switch again, now providing the value '2'; // 3. In the case '2' we repeat the same pattern as case '1' -// but instead the value to be evaluated is now '3'; -// 4. Finally we get to case '3', where we return from the function as a whole. +// but instead the value to be evaluated is now '3'; +// 4. Finally we get to case '3', where we return from the function as a whole, +// so the debug statement is never executed. +// 5. In this example, since the input does not have clear, exhaustive patterns and +// can essentially be any 'u8' integer, we need to handle all cases not explicitly +// covered by using the 'else => {}' branch as the default case. // -// Since step 4 or a break stament do not exist in this switch, the debug statement is -// never executed // const std = @import("std"); diff --git a/exercises/109_vectors.zig b/exercises/109_vectors.zig new file mode 100644 index 0000000..96892ca --- /dev/null +++ b/exercises/109_vectors.zig @@ -0,0 +1,147 @@ +// So far in Ziglings, we've seen how for loops can be used to +// repeat calculations across an array in several ways. +// +// For loops are generally great for this kind of task, but +// sometimes they don't fully utilize the capabilities of the +// CPU. +// +// Most modern CPUs can execute instructions in which SEVERAL +// calculations are performed WITHIN registers at the SAME TIME. +// These are known as "single instruction, multiple data" (SIMD) +// instructions. SIMD instructions can make code significantly +// more performant. +// +// To see why, imagine we have a program in which we take the +// square root of four (changing) f32 floats. +// +// A simple compiler would take the program and produce machine code +// which calculates each square root sequentially. Most registers on +// modern CPUs have 64 bits, so we could imagine that each float moves +// into a 64-bit register, and the following happens four times: +// +// 32 bits 32 bits +// +-------------------+ +// register | 0 | x | +// +-------------------+ +// +// | +// [SQRT instruction] +// V +// +// +-------------------+ +// | 0 | sqrt(x) | +// +-------------------+ +// +// Notice that half of the register contains blank data to which +// nothing happened. What a waste! What if we were able to use +// that space instead? This is the idea at the core of SIMD. +// +// Most modern CPUs contain specialized registers with at least 128 bits +// for performing SIMD instructions. On a machine with 128-bit SIMD +// registers, a smart compiler would probably NOT issue four sqrt +// instructions as above, but instead pack the floats into a single +// 128-bit register, then execute a single "packed" sqrt +// instruction to do ALL the square root calculations at once. +// +// For example: +// +// +// 32 bits 32 bits 32 bits 32 bits +// +---------------------------------------+ +// register | 4.0 | 9.0 | 25.0 | 49.0 | +// +---------------------------------------+ +// +// | +// [SIMD SQRT instruction] +// V +// +// +---------------------------------------+ +// register | 2.0 | 3.0 | 5.0 | 7.0 | +// +---------------------------------------+ +// +// Pretty cool, right? +// +// Code with SIMD instructions is usually more performant than code +// without SIMD instructions. Zig cares a lot about performance, +// so it has built-in support for SIMD! It has a data structure that +// directly supports SIMD instructions: +// +// +-----------+ +// | Vectors | +// +-----------+ +// +// Operations performed on vectors in Zig will be done in parallel using +// SIMD instructions, whenever possible. +// +// Defining vectors in Zig is straightforwards. No library import is needed. +const v1 = @Vector(3, i32){ 1, 10, 100 }; +const v2 = @Vector(3, f32){ 2.0, 3.0, 5.0 }; + +// Vectors support the same builtin operators as their underlying base types. +const v3 = v1 + v1; // { 2, 20, 200}; +const v4 = v2 * v2; // { 4.0, 9.0, 25.0}; + +// Intrinsics that apply to base types usually extend to vectors. +const v5: @Vector(3, f32) = @floatFromInt(v3); // { 2.0, 20.0, 200.0} +const v6 = v4 - v5; // { 2.0, -11.0, -175.0} +const v7 = @abs(v6); // { 2.0, 11.0, 175.0} + +// We can make constant vectors, and reduce vectors. +const v8: @Vector(4, u8) = @splat(2); // { 2, 2, 2, 2} +const v8_sum = @reduce(.Add, v8); // 8 +const v8_min = @reduce(.Min, v8); // 2 + +// Fixed-length arrays can be automatically assigned to vectors (and vice-versa). +const single_digit_primes = [4]i8{ 2, 3, 5, 7 }; +const prime_vector: @Vector(4, i8) = single_digit_primes; + +// Now let's use vectors to simplify and optimize some code! +// +// Ewa is writing a program in which they frequently want to compare +// two lists of four f32s. Ewa expects the lists to be similar, and +// wants to determine the largest pairwise difference between the lists. +// +// Ewa wrote the following function to figure this out. + +fn calcMaxPairwiseDiffOld(list1: [4]f32, list2: [4]f32) f32 { + var max_diff: f32 = 0; + for (list1, list2) |n1, n2| { + const abs_diff = @abs(n1 - n2); + if (abs_diff > max_diff) { + max_diff = abs_diff; + } + } + return max_diff; +} + +// Ewa heard about vectors in Zig, and started writing a new vector +// version of the function, but has got stuck! +// +// Help Ewa finish the vector version! The examples above should help. + +const Vec4 = @Vector(4, f32); +fn calcMaxPairwiseDiffNew(a: Vec4, b: Vec4) f32 { + const abs_diff_vec = ???; + const max_diff = @reduce(???, abs_diff_vec); + return max_diff; +} + +// Quite the simplification! We could even write the function in one line +// and it would still be readable. +// +// Since the entire function is now expressed in terms of vector operations, +// the Zig compiler will easily be able to compile it down to machine code +// which utilizes the all-powerful SIMD instructions and does a lot of the +// computation in parallel. + +const std = @import("std"); +const print = std.debug.print; + +pub fn main() void { + const l1 = [4]f32{ 3.141, 2.718, 0.577, 1.000 }; + const l2 = [4]f32{ 3.154, 2.707, 0.591, 0.993 }; + const mpd_old = calcMaxPairwiseDiffOld(l1, l2); + const mpd_new = calcMaxPairwiseDiffNew(l1, l2); + print("Max difference (old fn): {d: >5.3}\n", .{mpd_old}); + print("Max difference (new fn): {d: >5.3}\n", .{mpd_new}); +} diff --git a/patches/eowyn.sh b/patches/eowyn.sh index 8cac450..afc2732 100755 --- a/patches/eowyn.sh +++ b/patches/eowyn.sh @@ -12,6 +12,12 @@ # using the patches in this directory and convey them # to convalesce in the healed directory. # +delete_progress() { + progress_file=".progress.txt" + if [ -f $progress_file ]; then + rm $progress_file + fi +} set -e # We check ourselves before we wreck ourselves. @@ -23,9 +29,12 @@ fi # Which version we have? echo "Zig version" $(zig version) -echo "Eowyn version 23.10.5.1, let's try our magic power." +echo "Eowyn version 25.1.9, let's try our magic power." echo "" +# Remove progress file +delete_progress + # Create directory of healing if it doesn't already exist. mkdir -p patches/healed @@ -54,3 +63,6 @@ zig fmt --check patches/healed # Test the healed exercises. May the compiler have mercy upon us. zig build -Dhealed + +# Remove progress file again +delete_progress diff --git a/patches/patches/046_optionals2.patch b/patches/patches/046_optionals2.patch index 1b364a6..8fa01a2 100644 --- a/patches/patches/046_optionals2.patch +++ b/patches/patches/046_optionals2.patch @@ -1,5 +1,5 @@ ---- exercises/046_optionals2.zig 2024-09-04 20:51:36.766783971 +0200 -+++ answers/046_optionals2.zig 2024-09-04 20:51:01.389400985 +0200 +--- exercises/046_optionals2.zig 2024-11-08 22:46:25.592875338 +0100 ++++ answers/046_optionals2.zig 2024-11-08 22:46:20.699447951 +0100 @@ -22,7 +22,7 @@ const Elephant = struct { diff --git a/patches/patches/058_quiz7.patch b/patches/patches/058_quiz7.patch index 265b9e3..978fbb1 100644 --- a/patches/patches/058_quiz7.patch +++ b/patches/patches/058_quiz7.patch @@ -1,8 +1,8 @@ ---- exercises/058_quiz7.zig 2023-10-03 22:15:22.125574535 +0200 -+++ answers/058_quiz7.zig 2023-10-05 20:04:07.106101152 +0200 +--- exercises/058_quiz7.zig 2024-10-28 09:06:49.448505460 +0100 ++++ answers/058_quiz7.zig 2024-10-28 09:35:14.631932322 +0100 @@ -192,8 +192,8 @@ // Oops! The hermit forgot how to capture the union values - // in a switch statement. Please capture both values as + // in a switch statement. Please capture each value as // 'p' so the print statements work! - .place => print("{s}", .{p.name}), - .path => print("--{}->", .{p.dist}), diff --git a/patches/patches/065_builtins2.patch b/patches/patches/065_builtins2.patch index d5da950..e5e6410 100644 --- a/patches/patches/065_builtins2.patch +++ b/patches/patches/065_builtins2.patch @@ -1,5 +1,5 @@ ---- exercises/065_builtins2.zig 2024-09-02 19:15:56.569952315 +0200 -+++ answers/065_builtins2.zig 2024-09-02 19:13:44.280600350 +0200 +--- exercises/065_builtins2.zig 2024-11-02 16:58:30.607829441 +0100 ++++ answers/065_builtins2.zig 2024-11-02 16:58:33.821220588 +0100 @@ -58,7 +58,7 @@ // Oops! We cannot leave the 'me' and 'myself' fields // undefined. Please set them here: @@ -24,16 +24,16 @@ // (which is a zero-bit type that takes up no space at all!): - if (fields[0].??? != void) { + if (fields[0].type != void) { - print(" {s}", .{@typeInfo(Narcissus).@"struct".fields[0].name}); + print(" {s}", .{fields[0].name}); } - if (fields[1].??? != void) { + if (fields[1].type != void) { - print(" {s}", .{@typeInfo(Narcissus).@"struct".fields[1].name}); + print(" {s}", .{fields[1].name}); } - if (fields[2].??? != void) { + if (fields[2].type != void) { - print(" {s}", .{@typeInfo(Narcissus).@"struct".fields[2].name}); + print(" {s}", .{fields[2].name}); } diff --git a/patches/patches/099_formatting.patch b/patches/patches/099_formatting.patch index 384bf86..a56b556 100644 --- a/patches/patches/099_formatting.patch +++ b/patches/patches/099_formatting.patch @@ -1,5 +1,5 @@ ---- exercises/099_formatting.zig 2023-10-03 22:15:22.125574535 +0200 -+++ answers/099_formatting.zig 2023-10-05 20:04:07.292771311 +0200 +--- exercises/099_formatting.zig 2024-11-07 21:45:10.459123650 +0100 ++++ answers/099_formatting.zig 2024-11-07 21:43:55.154345991 +0100 @@ -131,7 +131,7 @@ for (0..size) |b| { // What formatting is needed here to make our columns diff --git a/patches/patches/100_for4.patch b/patches/patches/100_for4.patch index 3539be2..ad73e9a 100644 --- a/patches/patches/100_for4.patch +++ b/patches/patches/100_for4.patch @@ -7,5 +7,5 @@ - for (hex_nums, ???) |hn, ???| { + for (hex_nums, dec_nums) |hn, dn| { if (hn != dn) { - std.debug.print("Uh oh! Found a mismatch: {d} vs {d}\n", .{ hn, dn }); + print("Uh oh! Found a mismatch: {d} vs {d}\n", .{ hn, dn }); return; diff --git a/patches/patches/106_files.patch b/patches/patches/106_files.patch index 5eb5a19..89f37ad 100644 --- a/patches/patches/106_files.patch +++ b/patches/patches/106_files.patch @@ -1,5 +1,5 @@ ---- exercises/106_files.zig 2024-06-17 10:11:53.651439869 +0200 -+++ answers/106_files.zig 2024-06-17 10:21:50.697337653 +0200 +--- exercises/106_files.zig 2024-11-09 20:33:07.455580904 +0100 ++++ answers/106_files.zig 2024-11-09 20:33:30.394785215 +0100 @@ -1,22 +1,22 @@ // // Until now, we've only been printing our output in the console, @@ -17,9 +17,9 @@ +// by organizing files into directories, which hold files and other directories, +// thus creating a tree structure for navigating. // --// Fortunately, the Zig standard library provides a simple API for interacting +-// Fortunately, the Zig Standard Library provides a simple API for interacting -// with the file system, see the detail documentation here: -+// Fortunately, zig standard library provide a simple api for interacting ++// Fortunately, the Zig Standard Library provide a simple api for interacting +// with the file system, see the detail documentation here // // https://ziglang.org/documentation/master/std/#std.fs diff --git a/patches/patches/107_files2.patch b/patches/patches/107_files2.patch index ebf8a7c..f03a2e8 100644 --- a/patches/patches/107_files2.patch +++ b/patches/patches/107_files2.patch @@ -42,7 +42,7 @@ - // can you go here to find a way to read the content? + // can you go here to find a way to read the content ? // https://ziglang.org/documentation/master/std/#std.fs.File - // hint: you might find two answers that are both vaild in this case + // hint: you might find two answers that are both valid in this case - const bytes_read = zig_read_the_file_or_i_will_fight_you(&content); + const bytes_read = try file.read(&content); diff --git a/patches/patches/109_vectors.patch b/patches/patches/109_vectors.patch new file mode 100644 index 0000000..bf18cc0 --- /dev/null +++ b/patches/patches/109_vectors.patch @@ -0,0 +1,13 @@ +--- exercises/109_vectors.zig 2024-11-07 14:57:09.673383618 +0100 ++++ answers/109_vectors.zig 2024-11-07 14:22:59.069150138 +0100 +@@ -121,8 +121,8 @@ + + const Vec4 = @Vector(4, f32); + fn calcMaxPairwiseDiffNew(a: Vec4, b: Vec4) f32 { +- const abs_diff_vec = ???; +- const max_diff = @reduce(???, abs_diff_vec); ++ const abs_diff_vec = @abs(a - b); ++ const max_diff = @reduce(.Max, abs_diff_vec); + return max_diff; + } + |
