Browse Source

Merge branch 'main' into random-exercise

Chris Boesch 1 year ago
parent
commit
1fd6aa1c65

+ 1 - 1
.woodpecker/eowyn.yaml

@@ -5,5 +5,5 @@ steps:
     commands:
       - sh ./patches/eowyn.sh
     when:
-      event: [push, cron]
+      event: [pull_request, push, cron]
       cron: daily*

+ 2 - 1
README.md

@@ -88,7 +88,8 @@ that if you update one, you may need to also update the other.
 
 ### Version Changes
 
-Version-0.13.0-dev.339
+Version-0.14.0-dev.42
+* *2024-06-17* zig 0.14.0-dev.42 - changes in `std.mem.split and tokenize` - see [#15579](https://github.com/ziglang/zig/pull/15579)
 * *2024-05-29* zig 0.13.0-dev.339 - rework std.Progress - see [#20059](https://github.com/ziglang/zig/pull/20059)
 * *2024-03-21* zig 0.12.0-dev.3518 - change to @fieldParentPtr - see [#19470](https://github.com/ziglang/zig/pull/19470)
 * *2024-03-21* zig 0.12.0-dev.3397 - rename std.os to std.posix - see [#5019](https://github.com/ziglang/zig/issues/5019)

+ 4 - 4
build.zig

@@ -15,7 +15,7 @@ const print = std.debug.print;
 //     1) Getting Started
 //     2) Version Changes
 comptime {
-    const required_zig = "0.13.0-dev.339";
+    const required_zig = "0.14.0-dev.42";
     const current_zig = builtin.zig_version;
     const min_zig = std.SemanticVersion.parse(required_zig) catch unreachable;
     if (current_zig.order(min_zig) == .lt) {
@@ -199,7 +199,7 @@ pub fn build(b: *Build) !void {
         // like for 'exno' but chooses a random exersise number.
         print("work in progress: check a random exercise\n", .{});
 
-        var prng = std.rand.DefaultPrng.init(blk: {
+        var prng = std.Random.DefaultPrng.init(blk: {
             var seed: u64 = undefined;
             try std.posix.getrandom(std.mem.asBytes(&seed));
             break :blk seed;
@@ -490,7 +490,7 @@ fn resetLine() void {
 pub fn trimLines(allocator: std.mem.Allocator, buf: []const u8) ![]const u8 {
     var list = try std.ArrayList(u8).initCapacity(allocator, buf.len);
 
-    var iter = std.mem.split(u8, buf, " \n");
+    var iter = std.mem.splitSequence(u8, buf, " \n");
     while (iter.next()) |line| {
         // TODO: trimming CR characters is probably not necessary.
         const data = std.mem.trimRight(u8, line, " \r");
@@ -552,7 +552,7 @@ fn validate_exercises() bool {
             return false;
         }
 
-        var iter = std.mem.split(u8, ex.output, "\n");
+        var iter = std.mem.splitScalar(u8, ex.output, '\n');
         while (iter.next()) |line| {
             const output = std.mem.trimRight(u8, line, " \r");
             if (output.len != line.len) {

+ 19 - 4
exercises/046_optionals2.zig

@@ -5,7 +5,7 @@
 // linked to the first elephant. This is because we had NO CONCEPT
 // of a tail that didn't point to another elephant!
 //
-// We also introduce the handy ".?" shortcut:
+// We also introduce the handy `.?` shortcut:
 //
 //     const foo = bar.?;
 //
@@ -13,7 +13,8 @@
 //
 //     const foo = bar orelse unreachable;
 //
-// See if you can find where we use this shortcut below.
+// Check out where we use this shortcut below to change control flow
+// based on if an optional value exists.
 //
 // Now let's make those elephant tails optional!
 //
@@ -31,14 +32,25 @@ pub fn main() void {
     var elephantC = Elephant{ .letter = 'C' };
 
     // Link the elephants so that each tail "points" to the next.
-    elephantA.tail = &elephantB;
-    elephantB.tail = &elephantC;
+    linkElephants(&elephantA, &elephantB);
+    linkElephants(&elephantB, &elephantC);
+
+    // `linkElephants` will stop the program if you try and link an
+    // elephant that doesn't exist! Uncomment and see what happens.
+    // const missingElephant: ?*Elephant = null;
+    // linkElephants(&elephantC, missingElephant);
 
     visitElephants(&elephantA);
 
     std.debug.print("\n", .{});
 }
 
+// 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.?;
+}
+
 // This function visits all elephants once, starting with the
 // first elephant and following the tails to the next elephant.
 fn visitElephants(first_elephant: *Elephant) void {
@@ -51,6 +63,9 @@ fn visitElephants(first_elephant: *Elephant) void {
         // We should stop once we encounter a tail that
         // does NOT point to another element. What can
         // we put here to make that happen?
+
+        // HINT: We want something similar to what `.?` does,
+        // but instead of ending the program, we want to exit the loop...
         e = e.tail ???
     }
 }

+ 8 - 8
patches/patches/046_optionals2.patch

@@ -1,18 +1,18 @@
---- exercises/046_optionals2.zig	2024-05-10 23:11:25.796632478 +0200
-+++ answers/046_optionals2.zig	2024-05-10 23:10:16.115335668 +0200
-@@ -21,7 +21,7 @@
+--- exercises/046_optionals2.zig	2024-06-23 19:43:16
++++ answers/046_optionals2.zig	2024-06-23 19:42:46
+@@ -22,7 +22,7 @@
  
  const Elephant = struct {
      letter: u8,
 -    tail: *Elephant = null, // Hmm... tail needs something...
-+    tail: ?*Elephant = null, // <---- make this optional!
++    tail: ?*Elephant = null, // Hmm... tail needs something...
      visited: bool = false,
  };
  
-@@ -51,6 +51,6 @@
-         // We should stop once we encounter a tail that
-         // does NOT point to another element. What can
-         // we put here to make that happen?
+@@ -66,6 +66,6 @@
+ 
+         // HINT: We want something similar to what `.?` does,
+         // but instead of ending the program, we want to exit the loop...
 -        e = e.tail ???
 +        e = e.tail orelse break;
      }

+ 81 - 10
patches/patches/106_files.patch

@@ -1,16 +1,63 @@
---- exercises/106_files.zig	2024-05-05 00:48:25.808548611 +0200
-+++ answers/106_files.zig	2024-05-05 01:00:40.742969819 +0200
-@@ -35,7 +35,7 @@
+--- exercises/106_files.zig	2024-06-17 10:11:53.651439869 +0200
++++ answers/106_files.zig	2024-06-17 10:21:50.697337653 +0200
+@@ -1,22 +1,22 @@
+ //
+ // Until now, we've only been printing our output in the console,
+-// which is good enough for fighting aliens and hermit bookkeeping.
++// which is good enough for fighting alien and hermit bookkeeping.
+ //
+-// However, many other tasks require some interaction with the file system,
++// However, many other task require some interaction with the file system,
+ // which is the underlying structure for organizing files on your computer.
+ //
+-// The file system provides a hierarchical structure for storing files
+-// by organizing them into directories, which hold files and other directories,
+-// thus creating a tree structure that can be navigated.
++// The File System provide a hierarchical structure for storing files
++// 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
+-// with the file system, see the detail documentation here:
++// Fortunately, 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
+ //
+-// In this exercise, we'll try to:
+-//   - create a new directory,
+-//   - open a file in the directory,
++// In this exercise, we'll try to
++//   - create a new directory
++//   - open a file in the directory
+ //   - write to the file.
+ //
+ // import std as always
+@@ -27,42 +27,42 @@
+     const cwd: std.fs.Dir = std.fs.cwd();
+ 
+     // then we'll try to make a new directory /output/
+-    // to store our output files.
++    // to put our output files.
+     cwd.makeDir("output") catch |e| switch (e) {
+-        // there is a chance you might want to run this
++        // there are chance you might want to run this
+         // program more than once and the path might already
+-        // have been created, so we'll have to handle this error
++        // been created, so we'll have to handle this error
          // by doing nothing
          //
          // we want to catch error.PathAlreadyExists and do nothing
 -        ??? => {},
+-        // if there's any other unexpected error we just propagate it through
 +        error.PathAlreadyExists => {},
-         // if is any other unexpected error we just propagate it through
++        // if is any other unexpected error we just propagate it through
          else => return e,
      };
-@@ -44,7 +44,7 @@
-     // wait a minute
+ 
+     // then we'll try to open our freshly created directory
+-    // wait a minute...
++    // wait a minute
      // opening a directory might fail!
      // what should we do here?
 -    var output_dir: std.fs.Dir = cwd.openDir("output", .{});
@@ -18,12 +65,36 @@
      defer output_dir.close();
  
      // we try to open the file `zigling.txt`,
-@@ -55,7 +55,7 @@
+-    // and propagate any error up
++    // and propagate the error up if there are any errors
+     const file: std.fs.File = try output_dir.createFile("zigling.txt", .{});
+     // it is a good habit to close a file after you are done with it
+     // so that other programs can read it and prevent data corruption
      // but here we are not yet done writing to the file
-     // if only there were a keyword in zig that
-     // allows you "defer" code execute to the end of scope...
+-    // if only there were a keyword in Zig that
+-    // allowed you to "defer" code execution to the end of the scope...
 -    file.close();
++    // if only there were a keyword in zig that
++    // allows you "defer" code execute to the end of scope...
 +    defer file.close();
  
-     // !you are not allowed to switch these two lines above the file closing line!
+-    // you are not allowed to move these two lines above the file closing line!
++    // !you are not allowed to switch these two lines above the file closing line!
      const byte_written = try file.write("It's zigling time!");
+     std.debug.print("Successfully wrote {d} bytes.\n", .{byte_written});
+ }
+ // to check if you actually write to the file, you can either,
+-// 1. open the file in your text editor, or
++// 1. open the file on your text editor, or
+ // 2. print the content of the file in the console with the following command
+ //    >> cat ./output/zigling.txt
+ //
+@@ -86,7 +86,7 @@
+ //
+ // Question:
+ //   - what should you do if you want to also read the file after opening it?
+-//   - go to the documentation of the struct `std.fs.Dir` here:
++//   - go to documentation of the struct `std.fs.Dir` here
+ //     https://ziglang.org/documentation/master/std/#std.fs.Dir
+ //       - can you find a function for opening a file? how about deleting a file?
+ //       - what kind of options can you use with those functions?

+ 41 - 9
patches/patches/107_files2.patch

@@ -1,23 +1,55 @@
---- exercises/107_files2.zig	2024-05-05 00:48:25.808548611 +0200
-+++ answers/107_files2.zig	2024-05-05 01:14:03.866062288 +0200
-@@ -33,7 +33,7 @@
-     // initalize an array of u8 with all letter 'A'.
-     // we need to pick the size of the array, 64 seems like a good number.
+--- exercises/107_files2.zig	2024-06-17 10:11:53.651439869 +0200
++++ answers/107_files2.zig	2024-06-17 10:21:50.700671057 +0200
+@@ -4,17 +4,17 @@
+ //    - create a file {project_root}/output/zigling.txt
+ //      with content `It's zigling time!`(18 byte total)
+ //
+-// Now there's no point in writing to a file if we don't read from it, am I right?
+-// Let's write a program to read the content of the file that we just created.
++// Now there no point in writing to a file if we don't read from it am I right?
++// let's write a program to read the content of the file that we just created.
+ //
+ // I am assuming that you've created the appropriate files for this to work.
+ //
+-// Alright, bud, lean in close. Here's the game plan.
++// Alright, bud, lean in close here's the game plan.
+ //    - First, we open the {project_root}/output/ directory
+ //    - Secondly, we open file `zigling.txt` in that directory
+-//    - Then, we initalize an array of characters with all letter 'A', and print it
+-//    - After that, we read the content of the file into the array
+-//    - Finally, we print out the content we just read
++//    - then, we initalize an array of characters with all letter 'A', and print it
++//    - After that, we read the content of the file to the array
++//    - Finally, we print out the read content
+ 
+ const std = @import("std");
+ 
+@@ -30,23 +30,23 @@
+     const file = try output_dir.openFile("zigling.txt", .{});
+     defer file.close();
+ 
+-    // initalize an array of u8 with all letter 'A'
+-    // we need to pick the size of the array, 64 seems like a good number
++    // initalize an array of u8 with all letter 'A'.
++    // we need to pick the size of the array, 64 seems like a good number.
      // fix the initalization below
 -    var content = ['A']*64;
 +    var content = [_]u8{'A'} ** 64;
      // this should print out : `AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`
      std.debug.print("{s}\n", .{content});
  
-@@ -41,12 +41,12 @@
-     // can you go here to find a way to read the content ?
+     // 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?
++    // 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
 -    const bytes_read = zig_read_the_file_or_i_will_fight_you(&content);
 +    const bytes_read = try file.read(&content);
  
-     // Woah, too screamy, I know you're excited for zigling time but tone it down a bit
-     // Can you print only what we read from the file ?
+-    // Woah, too screamy. I know you're excited for zigling time but tone it down a bit.
+-    // Can you print only what we read from the file?
++    // Woah, too screamy, I know you're excited for zigling time but tone it down a bit
++    // Can you print only what we read from the file ?
      std.debug.print("Successfully Read {d} bytes: {s}\n", .{
          bytes_read,
 -        content, // change this line only