Browse Source

Added ex. 46 optionals 2 - elephants!

Dave Gauer 4 years ago
parent
commit
f27601b558
4 changed files with 64 additions and 1 deletions
  1. 5 1
      build.zig
  2. 2 0
      exercises/44_quiz5.zig
  3. 46 0
      exercises/46_optionals2.zig
  4. 11 0
      patches/patches/46_optionals2.patch

+ 5 - 1
build.zig

@@ -240,7 +240,11 @@ const exercises = [_]Exercise{
         .main_file = "45_optionals.zig",
         .output = "The Ultimate Answer: 42.",
     },
-    // optional fields (elephant tail - no longer need circular)
+    .{
+        .main_file = "46_optionals2.zig",
+        .output = "Elephant A. Elephant B. Elephant C.",
+        .hint = "Elephants!",
+    },
     // super-simple struct method
     // use struct method for elephant tails
     // quiz: add elephant trunk (like tail)!

+ 2 - 0
exercises/44_quiz5.zig

@@ -28,6 +28,8 @@ pub fn main() void {
     elephantC.tail = &elephantA;
 
     visitElephants(&elephantA);
+
+    std.debug.print("\n", .{});
 }
 
 // This function visits all elephants once, starting with the

+ 46 - 0
exercises/46_optionals2.zig

@@ -0,0 +1,46 @@
+//
+// Now that we have optional types, we can apply them to structs.
+// The last time we checked in with our elephants, we had to link
+// all three of them together in a "circle" so that the last tail
+// linked to the first elephant. This is because we had NO CONCEPT
+// of a tail that didn't point to another elephant!
+//
+const std = @import("std"); // single quotes
+
+const Elephant = struct {
+    letter: u8,
+    tail: *Elephant = undefined, // <---- make this optional!
+    visited: bool = false,
+};
+
+pub fn main() void {
+    var elephantA = Elephant{ .letter = 'A' };
+    var elephantB = Elephant{ .letter = 'B' };
+    var elephantC = Elephant{ .letter = 'C' };
+
+    // Link the elephants so that each tail "points" to the next.
+    elephantA.tail = &elephantB;
+    elephantB.tail = &elephantC;
+
+    visitElephants(&elephantA);
+
+    std.debug.print("\n", .{});
+}
+
+// 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 {
+    var e = first_elephant;
+
+    while (!e.visited) {
+        std.debug.print("Elephant {u}. ", .{e.letter});
+        e.visited = true;
+
+        // We should stop once we encounter a tail that
+        // does NOT point to another element. What can
+        // we put here to make that happen?
+        if (e.tail == null) ???;
+
+        e = e.tail.?;
+    }
+}

+ 11 - 0
patches/patches/46_optionals2.patch

@@ -0,0 +1,11 @@
+12c12
+<     tail: *Elephant = undefined, // <---- make this optional!
+---
+>     tail: ?*Elephant = undefined,
+39,42c39
+<         // We should stop once we encounter a tail that
+<         // does NOT point to another element. What can
+<         // we put here to make that happen?
+<         if (e.tail == null) ???;
+---
+>         if (e.tail == null) break;