Ziglings

Exercise 001

diff --git a/exercises/001_hello.zig b/exercises/001_hello.zig
index 2d95a10..eab663a 100644
--- a/exercises/001_hello.zig
+++ b/exercises/001_hello.zig
@@ -16,6 +16,6 @@
 //
 const std = @import("std");

-fn main() void {
+pub fn main() void {
     std.debug.print("Hello world!\n", .{});
 }

Exercise 002

diff --git a/exercises/002_std.zig b/exercises/002_std.zig
index 8cc3792..5916c7c 100644
--- a/exercises/002_std.zig
+++ b/exercises/002_std.zig
@@ -11,7 +11,7 @@
 // Please complete the import below:
 //
 
-??? = @import("std");
+const std = @import("std");
 
 pub fn main() void {
     std.debug.print("Standard Library.\n", .{});

Exercise 003

diff --git a/exercises/003_assignment.zig b/exercises/003_assignment.zig
index 10ba8cb..f2f34a1 100644
--- a/exercises/003_assignment.zig
+++ b/exercises/003_assignment.zig
@@ -34,12 +34,15 @@
 const std = @import("std");
 
 pub fn main() void {
-    const n: u8 = 50;
+    // we need a variable in order to change the value; hence var
+    var n: u8 = 50;
     n = n + 5;
 
-    const pi: u8 = 314159;
+    // u8 is too small as is u16
+    const pi: u32 = 314159;
 
-    const negative_eleven: u8 = -11;
+    // u8 cannot have a sign; hence i8
+    const negative_eleven: i8 = -11;
 
     // There are no errors in the next line, just explanation:
     // Perhaps you noticed before that the print function takes two

Exercise 004

diff --git a/exercises/004_arrays.zig b/exercises/004_arrays.zig
index 88fcc78..b6756bb 100644
--- a/exercises/004_arrays.zig
+++ b/exercises/004_arrays.zig
@@ -27,7 +27,7 @@ pub fn main() void {
     // (Problem 1)
     // This "const" is going to cause a problem later - can you see what it is?
     // How do we fix it?
-    const some_primes = [_]u8{ 1, 3, 5, 7, 11, 13, 17, 19 };
+    var some_primes = [_]u8{ 1, 3, 5, 7, 11, 13, 17, 19 };
 
     // Individual values can be set with '[]' notation.
     // Example: This line changes the first prime to 2 (which is correct):
@@ -40,11 +40,11 @@ pub fn main() void {
     // (Problem 2)
     // Looks like we need to complete this expression. Use the example
     // above to set "fourth" to the fourth element of the some_primes array:
-    const fourth = some_primes[???];
+    const fourth = some_primes[3];
 
     // (Problem 3)
     // Use the len property to get the length of the array:
-    const length = some_primes.???;
+    const length = some_primes.len;
 
     std.debug.print("First: {}, Fourth: {}, Length: {}\n", .{
         first, fourth, length,

Exercise 005

diff --git a/exercises/005_arrays2.zig b/exercises/005_arrays2.zig
index 497d400..e5058a9 100644
--- a/exercises/005_arrays2.zig
+++ b/exercises/005_arrays2.zig
@@ -25,12 +25,12 @@ pub fn main() void {
     // (Problem 1)
     // Please set this array concatenating the two arrays above.
     // It should result in: 1 3 3 7
-    const leet = ???;
+    const leet = le ++ et;
 
     // (Problem 2)
     // Please set this array using repetition.
     // It should result in: 1 0 0 1 1 0 0 1 1 0 0 1
-    const bit_pattern = [_]u8{ ??? } ** 3;
+    const bit_pattern = [_]u8{ 1, 0, 0, 1 } ** 3;
 
     // Okay, that's all of the problems. Let's see the results.
     //

Exercise 006

diff --git a/exercises/006_strings.zig b/exercises/006_strings.zig
index 5a7172c..3ad26ce 100644
--- a/exercises/006_strings.zig
+++ b/exercises/006_strings.zig
@@ -24,18 +24,18 @@ pub fn main() void {
     // (Problem 1)
     // Use array square bracket syntax to get the letter 'd' from
     // the string "stardust" above.
-    const d: u8 = ziggy[???];
+    const d: u8 = ziggy[4];
 
     // (Problem 2)
     // Use the array repeat '**' operator to make "ha ha ha ".
-    const laugh = "ha " ???;
+    const laugh = "ha " ** 3;
 
     // (Problem 3)
     // Use the array concatenation '++' operator to make "Major Tom".
     // (You'll need to add a space as well!)
     const major = "Major";
     const tom = "Tom";
-    const major_tom = major ??? tom;
+    const major_tom = major ++ " " ++ tom;
 
     // That's all the problems. Let's see our results:
     std.debug.print("d={u} {s}{s}\n", .{ d, laugh, major_tom });

Exercise 007

diff --git a/exercises/007_strings2.zig b/exercises/007_strings2.zig
index 6350be1..74cb752 100644
--- a/exercises/007_strings2.zig
+++ b/exercises/007_strings2.zig
@@ -15,9 +15,9 @@ const std = @import("std");
 
 pub fn main() void {
     const lyrics =
-        Ziggy played guitar
-        Jamming good with Andrew Kelley
-        And the Spiders from Mars
+        \\Ziggy played guitar
+        \\Jamming good with Andrew Kelley
+        \\And the Spiders from Mars
     ;
 
     std.debug.print("{s}\n", .{lyrics});

Exercise 008

diff --git a/exercises/008_quiz.zig b/exercises/008_quiz.zig
index 5a81fb2..dff4da3 100644
--- a/exercises/008_quiz.zig
+++ b/exercises/008_quiz.zig
@@ -19,7 +19,7 @@ pub fn main() void {
     // the idiomatic type to use for array indexing.
     //
     // There IS a problem on this line, but 'usize' isn't it.
-    const x: usize = 1;
+    var x: usize = 1;
 
     // Note: When you want to declare memory (an array in this
     // case) without putting anything in it, you can set it to
@@ -33,10 +33,10 @@ pub fn main() void {
     lang[0] = letters[x];
 
     x = 3;
-    lang[???] = letters[x];
+    lang[1] = letters[x];
 
-    x = ???;
-    lang[2] = letters[???];
+    x = 5;
+    lang[2] = letters[x];
 
     // We want to "Program in Zig!" of course:
     std.debug.print("Program in {s}!\n", .{lang});

Exercise 009

diff --git a/exercises/009_if.zig b/exercises/009_if.zig
index e167104..68bf04b 100644
--- a/exercises/009_if.zig
+++ b/exercises/009_if.zig
@@ -24,7 +24,7 @@ pub fn main() void {
     const foo = 42;
 
     // Please fix this condition:
-    if (foo) {
+    if (foo == 42) {
         // We want our program to print this message!
         std.debug.print("Foo is 42!\n", .{});
     } else {

Exercise 010

diff --git a/exercises/010_if2.zig b/exercises/010_if2.zig
index f0ffb43..7bbc01c 100644
--- a/exercises/010_if2.zig
+++ b/exercises/010_if2.zig
@@ -10,7 +10,7 @@ pub fn main() void {
 
     // Please use an if...else expression to set "price".
     // If discount is true, the price should be $17, otherwise $20:
-    const price: u8 = if ???;
+    const price: u8 = if (discount) 17 else 20;
 
     std.debug.print("With the discount, the price is ${}.\n", .{price});
 }

Exercise 011

diff --git a/exercises/011_while.zig b/exercises/011_while.zig
index 674d904..1706e67 100644
--- a/exercises/011_while.zig
+++ b/exercises/011_while.zig
@@ -21,7 +21,7 @@ pub fn main() void {
     var n: u32 = 2;
 
     // Please use a condition that is true UNTIL "n" reaches 1024:
-    while (???) {
+    while (n < 1024) {
         // Print the current number
         std.debug.print("{} ", .{n});
 

Exercise 012

diff --git a/exercises/012_while2.zig b/exercises/012_while2.zig
index c9905aa..6f8e168 100644
--- a/exercises/012_while2.zig
+++ b/exercises/012_while2.zig
@@ -25,7 +25,7 @@ pub fn main() void {
 
     // Please set the continue expression so that we get the desired
     // results in the print statement below.
-    while (n < 1000) : ??? {
+    while (n < 1000) : (n *= 2) {
         // Print the current number
         std.debug.print("{} ", .{n});
     }

Exercise 013

diff --git a/exercises/013_while3.zig b/exercises/013_while3.zig
index 4cccf62..8f9a924 100644
--- a/exercises/013_while3.zig
+++ b/exercises/013_while3.zig
@@ -24,8 +24,8 @@ pub fn main() void {
     while (n <= 20) : (n += 1) {
         // The '%' symbol is the "modulo" operator and it
         // returns the remainder after division.
-        if (n % 3 == 0) ???;
-        if (n % 5 == 0) ???;
+        if (n % 3 == 0) continue;
+        if (n % 5 == 0) continue;
         std.debug.print("{} ", .{n});
     }
 

Exercise 014

diff --git a/exercises/014_while4.zig b/exercises/014_while4.zig
index 95aecb0..dfd48fc 100644
--- a/exercises/014_while4.zig
+++ b/exercises/014_while4.zig
@@ -18,7 +18,7 @@ pub fn main() void {
     // Oh dear! This while loop will go forever?!
     // Please fix this so the print statement below gives the desired output.
     while (true) : (n += 1) {
-        if (???) ???;
+        if (n == 4) break;
     }
 
     // Result: we want n=4

Exercise 015

diff --git a/exercises/015_for.zig b/exercises/015_for.zig
index 0ee8e7d..e6b9729 100644
--- a/exercises/015_for.zig
+++ b/exercises/015_for.zig
@@ -15,7 +15,7 @@ pub fn main() void {
 
     std.debug.print("A Dramatic Story: ", .{});
 
-    for (???) |???| {
+    for (story) |scene| {
         if (scene == 'h') std.debug.print(":-)  ", .{});
         if (scene == 's') std.debug.print(":-(  ", .{});
         if (scene == 'n') std.debug.print(":-|  ", .{});

Exercise 016

diff --git a/exercises/016_for2.zig b/exercises/016_for2.zig
index 6fb7844..eaab65f 100644
--- a/exercises/016_for2.zig
+++ b/exercises/016_for2.zig
@@ -25,7 +25,7 @@ pub fn main() void {
     // the value of the place as a power of two for each bit.
     //
     // See if you can figure out the missing pieces:
-    for (bits, ???) |bit, ???| {
+    for (bits, 0..) |bit, i| {
         // Note that we convert the usize i to a u32 with
         // @intCast(), a builtin function just like @import().
         // We'll learn about these properly in a later exercise.

Exercise 017

diff --git a/exercises/017_quiz2.zig b/exercises/017_quiz2.zig
index 6f32c2e..4ad3ca7 100644
--- a/exercises/017_quiz2.zig
+++ b/exercises/017_quiz2.zig
@@ -9,18 +9,18 @@
 // Let's go from 1 to 16. This has been started for you, but there
 // are some problems. :-(
 //
-const std = import standard library;
+const std = @import("std");
 
-function main() void {
+pub fn main() void {
     var i: u8 = 1;
     const stop_at: u8 = 16;
 
     // What kind of loop is this? A 'for' or a 'while'?
-    ??? (i <= stop_at) : (i += 1) {
+    while (i <= stop_at) : (i += 1) {
         if (i % 3 == 0) std.debug.print("Fizz", .{});
         if (i % 5 == 0) std.debug.print("Buzz", .{});
         if (!(i % 3 == 0) and !(i % 5 == 0)) {
-            std.debug.print("{}", .{???});
+            std.debug.print("{}", .{i});
         }
         std.debug.print(", ", .{});
     }

Exercise 018

diff --git a/exercises/018_functions.zig b/exercises/018_functions.zig
index 1f78438..c9cc6c5 100644
--- a/exercises/018_functions.zig
+++ b/exercises/018_functions.zig
@@ -25,6 +25,6 @@ pub fn main() void {
 // We're just missing a couple things. One thing we're NOT missing is the
 // keyword "pub", which is not needed here. Can you guess why?
 //
-??? deepThought() ??? {
+fn deepThought() u8 {
     return 42; // Number courtesy Douglas Adams
 }

Exercise 019

diff --git a/exercises/019_functions2.zig b/exercises/019_functions2.zig
index 5a76c7b..de90b87 100644
--- a/exercises/019_functions2.zig
+++ b/exercises/019_functions2.zig
@@ -22,7 +22,7 @@ pub fn main() void {
 // You'll need to figure out the parameter name and type that we're
 // expecting. The output type has already been specified for you.
 //
-fn twoToThe(???) u32 {
+fn twoToThe(my_number: u32) u32 {
     return std.math.pow(u32, 2, my_number);
     // std.math.pow(type, a, b) takes a numeric type and two
     // numbers of that type (or that can coerce to that type) and

Exercise 020

diff --git a/exercises/020_quiz3.zig b/exercises/020_quiz3.zig
index 571628e..2284999 100644
--- a/exercises/020_quiz3.zig
+++ b/exercises/020_quiz3.zig
@@ -21,8 +21,8 @@ pub fn main() void {
 //
 // This function prints, but does not return anything.
 //
-fn printPowersOfTwo(numbers: [4]u16) ??? {
-    loop (numbers) |n| {
+fn printPowersOfTwo(numbers: [4]u16) void {
+    for (numbers) |n| {
         std.debug.print("{} ", .{twoToThe(n)});
     }
 }
@@ -31,13 +31,13 @@ fn printPowersOfTwo(numbers: [4]u16) ??? {
 // exercise. But don't be fooled! This one does the math without the aid
 // of the standard library!
 //
-fn twoToThe(number: u16) ??? {
+fn twoToThe(number: u16) u16 {
     var n: u16 = 0;
     var total: u16 = 1;
 
-    loop (n < number) : (n += 1) {
+    while (n < number) : (n += 1) {
         total *= 2;
     }
 
-    return ???;
+    return total;
 }

Exercise 021

diff --git a/exercises/021_errors.zig b/exercises/021_errors.zig
index 7afeace..64a39ef 100644
--- a/exercises/021_errors.zig
+++ b/exercises/021_errors.zig
@@ -7,14 +7,14 @@
 //
 // We have the start of an error set, but we're missing the condition
 // "TooSmall". Please add it where needed!
+const std = @import("std");
+
 const MyNumberError = error{
     TooBig,
-    ???,
+    TooSmall,
     TooFour,
 };
 
-const std = @import("std");
-
 pub fn main() void {
     const nums = [_]u8{ 2, 3, 4, 5, 6 };
 
@@ -26,7 +26,7 @@ pub fn main() void {
         if (number_error == MyNumberError.TooBig) {
             std.debug.print(">4. ", .{});
         }
-        if (???) {
+        if (number_error == MyNumberError.TooSmall) {
             std.debug.print("<4. ", .{});
         }
         if (number_error == MyNumberError.TooFour) {

Exercise 022

diff --git a/exercises/022_errors2.zig b/exercises/022_errors2.zig
index 1d513b3..dd142e4 100644
--- a/exercises/022_errors2.zig
+++ b/exercises/022_errors2.zig
@@ -19,7 +19,10 @@ const std = @import("std");
 const MyNumberError = error{TooSmall};
 
 pub fn main() void {
-    var my_number: ??? = 5;
+    // this is tricky to remember
+    // but we need a union of the Error and the Type
+    // expressed as Error!Type
+    var my_number: MyNumberError!u8 = 5;
 
     // Looks like my_number will need to either store a number OR
     // an error. Can you set the type correctly above?

Exercise 023

diff --git a/exercises/023_errors3.zig b/exercises/023_errors3.zig
index 195f21a..2fdc4a2 100644
--- a/exercises/023_errors3.zig
+++ b/exercises/023_errors3.zig
@@ -12,14 +12,14 @@ const MyNumberError = error{TooSmall};
 
 pub fn main() void {
     const a: u32 = addTwenty(44) catch 22;
-    const b: u32 = addTwenty(4) ??? 22;
+    const b: u32 = addTwenty(4) catch 22;
 
     std.debug.print("a={}, b={}\n", .{ a, b });
 }
 
 // Please provide the return type from this function.
 // Hint: it'll be an error union.
-fn addTwenty(n: u32) ??? {
+fn addTwenty(n: u32) MyNumberError!u32 {
     if (n < 5) {
         return MyNumberError.TooSmall;
     } else {

Exercise 024

diff --git a/exercises/024_errors4.zig b/exercises/024_errors4.zig
index 02ec0f2..dc5c7d6 100644
--- a/exercises/024_errors4.zig
+++ b/exercises/024_errors4.zig
@@ -59,7 +59,13 @@ fn fixTooSmall(n: u32) MyNumberError!u32 {
     // If we get a TooSmall error, we should return 10.
     // If we get any other error, we should return that error.
     // Otherwise, we return the u32 number.
-    return detectProblems(n) ???;
+    return detectProblems(n) catch |err| {
+        if (err == MyNumberError.TooSmall) {
+            return 10;
+        }
+
+        return err;
+    };
 }
 
 fn detectProblems(n: u32) MyNumberError!u32 {

Exercise 025

diff --git a/exercises/025_errors5.zig b/exercises/025_errors5.zig
index 94bf1c7..46faa41 100644
--- a/exercises/025_errors5.zig
+++ b/exercises/025_errors5.zig
@@ -26,7 +26,9 @@ fn addFive(n: u32) MyNumberError!u32 {
     // This function needs to return any error which might come back from detect().
     // Please use a "try" statement rather than a "catch".
     //
-    const x = detect(n);
+    // we just need to throw the try here
+    // instead of running catch detect(n) |err| { ... };
+    const x = try detect(n);
 
     return x + 5;
 }

Exercise 026

diff --git a/exercises/026_hello2.zig b/exercises/026_hello2.zig
index 582dba9..4b436da 100644
--- a/exercises/026_hello2.zig
+++ b/exercises/026_hello2.zig
@@ -23,5 +23,5 @@ pub fn main() !void {
     // to be able to pass it up as a return value of main().
     //
     // We just learned of a single statement which can accomplish this.
-    stdout.interface.print("Hello world!\n", .{});
+    try stdout.interface.print("Hello world!\n", .{});
 }

Exercise 027

diff --git a/exercises/027_defer.zig b/exercises/027_defer.zig
index b41e2af..68d0974 100644
--- a/exercises/027_defer.zig
+++ b/exercises/027_defer.zig
@@ -20,6 +20,6 @@ const std = @import("std");
 pub fn main() void {
     // Without changing anything else, please add a 'defer' statement
     // to this code so that our program prints "One Two\n":
-    std.debug.print("Two\n", .{});
+    defer std.debug.print("Two\n", .{});
     std.debug.print("One ", .{});
 }

Exercise 028

diff --git a/exercises/028_defer2.zig b/exercises/028_defer2.zig
index 35c1326..358fe28 100644
--- a/exercises/028_defer2.zig
+++ b/exercises/028_defer2.zig
@@ -18,7 +18,7 @@ pub fn main() void {
 fn printAnimal(animal: u8) void {
     std.debug.print("(", .{});
 
-    std.debug.print(") ", .{}); // <---- how?!
+    defer std.debug.print(") ", .{}); // <---- how?!
 
     if (animal == 'g') {
         std.debug.print("Goat", .{});

Exercise 029

diff --git a/exercises/029_errdefer.zig b/exercises/029_errdefer.zig
index 39ab306..bda1ea2 100644
--- a/exercises/029_errdefer.zig
+++ b/exercises/029_errdefer.zig
@@ -32,7 +32,7 @@ fn makeNumber() MyErr!u32 {
 
     // Please make the "failed" message print ONLY if the makeNumber()
     // function exits with an error:
-    std.debug.print("failed!\n", .{});
+    errdefer std.debug.print("failed!\n", .{});
 
     var num = try getNumber(); // <-- This could fail!
 

Exercise 030

diff --git a/exercises/030_switch.zig b/exercises/030_switch.zig
index cb983f5..04e6b6d 100644
--- a/exercises/030_switch.zig
+++ b/exercises/030_switch.zig
@@ -46,6 +46,7 @@ pub fn main() void {
             // match for every possible value).  Please add an "else"
             // to this switch to print a question mark "?" when c is
             // not one of the existing matches.
+            else => std.debug.print("?", .{}),
         }
     }
 

Exercise 031

diff --git a/exercises/031_switch2.zig b/exercises/031_switch2.zig
index cf5b5a5..444539c 100644
--- a/exercises/031_switch2.zig
+++ b/exercises/031_switch2.zig
@@ -31,6 +31,7 @@ pub fn main() void {
             26 => 'Z',
             // As in the last exercise, please add the 'else' clause
             // and this time, have it return an exclamation mark '!'.
+            else => '!',
         };
 
         std.debug.print("{c}", .{real_char});

Exercise 032

diff --git a/exercises/032_unreachable.zig b/exercises/032_unreachable.zig
index ffc35a4..7fe5fc1 100644
--- a/exercises/032_unreachable.zig
+++ b/exercises/032_unreachable.zig
@@ -35,6 +35,7 @@ pub fn main() void {
             3 => {
                 current_value *= current_value;
             },
+            else => unreachable,
         }
 
         std.debug.print("{} ", .{current_value});

Exercise 033

diff --git a/exercises/033_iferror.zig b/exercises/033_iferror.zig
index 12da2d2..f2e04d4 100644
--- a/exercises/033_iferror.zig
+++ b/exercises/033_iferror.zig
@@ -21,13 +21,13 @@
 //         ...
 //     }
 //
+const std = @import("std");
+
 const MyNumberError = error{
     TooBig,
     TooSmall,
 };
 
-const std = @import("std");
-
 pub fn main() void {
     const nums = [_]u8{ 2, 3, 4, 5, 6 };
 
@@ -40,6 +40,7 @@ pub fn main() void {
         } else |err| switch (err) {
             MyNumberError.TooBig => std.debug.print(">4. ", .{}),
             // Please add a match for TooSmall here and have it print: "<4. "
+            MyNumberError.TooSmall => std.debug.print("<4. ", .{}),
         }
     }
 

Exercise 034

diff --git a/exercises/034_quiz4.zig b/exercises/034_quiz4.zig
index 8704397..cf4f053 100644
--- a/exercises/034_quiz4.zig
+++ b/exercises/034_quiz4.zig
@@ -9,10 +9,11 @@ const std = @import("std");
 
 const NumError = error{IllegalNumber};
 
-pub fn main() void {
+// we return no value but we may return an error
+pub fn main() !void {
     var stdout = std.fs.File.stdout().writer(&.{});
 
-    const my_num: u32 = getNumber();
+    const my_num: u32 = try getNumber();
 
     try stdout.interface.print("my_num={}\n", .{my_num});
 }

Exercise 035

diff --git a/exercises/035_enums.zig b/exercises/035_enums.zig
index 1825f52..da0e415 100644
--- a/exercises/035_enums.zig
+++ b/exercises/035_enums.zig
@@ -20,7 +20,7 @@
 const std = @import("std");
 
 // Please complete the enum!
-const Ops = enum { ??? };
+const Ops = enum { inc, pow, dec };
 
 pub fn main() void {
     const operations = [_]Ops{

Exercise 036

diff --git a/exercises/036_enums2.zig b/exercises/036_enums2.zig
index dc2998c..5e0efdd 100644
--- a/exercises/036_enums2.zig
+++ b/exercises/036_enums2.zig
@@ -31,7 +31,7 @@ const std = @import("std");
 const Color = enum(u32) {
     red = 0xff0000,
     green = 0x00ff00,
-    blue = ???,
+    blue = 0x0000ff,
 };
 
 pub fn main() void {
@@ -53,12 +53,12 @@ pub fn main() void {
         \\<p>
         \\  <span style="color: #{x:0>6}">Red</span>
         \\  <span style="color: #{x:0>6}">Green</span>
-        \\  <span style="color: #{}">Blue</span>
+        \\  <span style="color: #{x:0>6}">Blue</span>
         \\</p>
         \\
     , .{
         @intFromEnum(Color.red),
         @intFromEnum(Color.green),
-        @intFromEnum(???), // Oops! We're missing something!
+        @intFromEnum(Color.blue), // Oops! We're missing something!
     });
 }

Exercise 037

diff --git a/exercises/037_structs.zig b/exercises/037_structs.zig
index c345faf..d28efbc 100644
--- a/exercises/037_structs.zig
+++ b/exercises/037_structs.zig
@@ -36,6 +36,7 @@ const Character = struct {
     role: Role,
     gold: u32,
     experience: u32,
+    health: u32,
 };
 
 pub fn main() void {
@@ -44,6 +45,7 @@ pub fn main() void {
         .role = Role.wizard,
         .gold = 20,
         .experience = 10,
+        .health = 100,
     };
 
     // Glorp gains some gold.

Exercise 038

diff --git a/exercises/038_structs2.zig b/exercises/038_structs2.zig
index b9d84aa..5f1f4d1 100644
--- a/exercises/038_structs2.zig
+++ b/exercises/038_structs2.zig
@@ -43,6 +43,13 @@ pub fn main() void {
     // Feel free to run this program without adding Zump. What does
     // it do and why?
 
+    chars[1] = Character{
+        .role = Role.bard,
+        .gold = 10,
+        .health = 100,
+        .experience = 20,
+    };
+
     // Printing all RPG characters in a loop:
     for (chars, 0..) |c, num| {
         std.debug.print("Character {} - G:{} H:{} XP:{}\n", .{

Exercise 039

diff --git a/exercises/039_pointers.zig b/exercises/039_pointers.zig
index 24ca46d..392dbf4 100644
--- a/exercises/039_pointers.zig
+++ b/exercises/039_pointers.zig
@@ -30,7 +30,7 @@ pub fn main() void {
 
     // Please make num2 equal 5 using num1_pointer!
     // (See the "cheatsheet" above for ideas.)
-    num2 = ???;
+    num2 = num1_pointer.*;
 
     std.debug.print("num1: {}, num2: {}\n", .{ num1, num2 });
 }

Exercise 040

diff --git a/exercises/040_pointers2.zig b/exercises/040_pointers2.zig
index a4852f6..f69e3a8 100644
--- a/exercises/040_pointers2.zig
+++ b/exercises/040_pointers2.zig
@@ -22,7 +22,10 @@
 const std = @import("std");
 
 pub fn main() void {
-    const a: u8 = 12;
+    // we can go var -> const
+    // but not const -> const
+    // or const -> var
+    var a: u8 = 12;
     const b: *u8 = &a; // fix this!
 
     std.debug.print("a: {}, b: {}\n", .{ a, b.* });

Exercise 041

diff --git a/exercises/041_pointers3.zig b/exercises/041_pointers3.zig
index 9e2bcc6..8b4155f 100644
--- a/exercises/041_pointers3.zig
+++ b/exercises/041_pointers3.zig
@@ -31,7 +31,8 @@ pub fn main() void {
 
     // Please define pointer "p" so that it can point to EITHER foo or
     // bar AND change the value it points to!
-    ??? p: ??? = undefined;
+    // we have to start with a var here
+    var p: *u8 = undefined;
 
     p = &foo;
     p.* += 1;

Exercise 042

diff --git a/exercises/042_pointers4.zig b/exercises/042_pointers4.zig
index 1f6db70..a08904c 100644
--- a/exercises/042_pointers4.zig
+++ b/exercises/042_pointers4.zig
@@ -37,5 +37,6 @@ pub fn main() void {
 // This function should take a reference to a u8 value and set it
 // to 5.
 fn makeFive(x: *u8) void {
-    ??? = 5; // fix me!
+    // dereference and then modify
+    x.* = 5; // fix me!
 }

Exercise 043

diff --git a/exercises/043_pointers5.zig b/exercises/043_pointers5.zig
index 9e2fa6f..23ee2e2 100644
--- a/exercises/043_pointers5.zig
+++ b/exercises/043_pointers5.zig
@@ -68,7 +68,7 @@ pub fn main() void {
 
     // FIX ME!
     // Please pass Glorp to printCharacter():
-    printCharacter(???);
+    printCharacter(&glorp);
 }
 
 // Note how this function's "c" parameter is a pointer to a Character struct.

Exercise 044

diff --git a/exercises/044_quiz5.zig b/exercises/044_quiz5.zig
index 8a0d88c..3e6ee79 100644
--- a/exercises/044_quiz5.zig
+++ b/exercises/044_quiz5.zig
@@ -19,12 +19,14 @@ const Elephant = struct {
 pub fn main() void {
     var elephantA = Elephant{ .letter = 'A' };
     // (Please add Elephant B here!)
+    var elephantB = Elephant{ .letter = 'B' };
     var elephantC = Elephant{ .letter = 'C' };
 
     // Link the elephants so that each tail "points" to the next elephant.
     // They make a circle: A->B->C->A...
     elephantA.tail = &elephantB;
     // (Please link Elephant B's tail to Elephant C here!)
+    elephantB.tail = &elephantC;
     elephantC.tail = &elephantA;
 
     visitElephants(&elephantA);

Exercise 045

diff --git a/exercises/045_optionals.zig b/exercises/045_optionals.zig
index 494c960..1763f6b 100644
--- a/exercises/045_optionals.zig
+++ b/exercises/045_optionals.zig
@@ -29,7 +29,7 @@ pub fn main() void {
 
     // Please threaten the result so that answer is either the
     // integer value from deepThought() OR the number 42:
-    const answer: u8 = result;
+    const answer: u8 = result orelse 42;
 
     std.debug.print("The Ultimate Answer: {}.\n", .{answer});
 }

Exercise 046

diff --git a/exercises/046_optionals2.zig b/exercises/046_optionals2.zig
index b5fffbb..78bc5b2 100644
--- a/exercises/046_optionals2.zig
+++ b/exercises/046_optionals2.zig
@@ -22,7 +22,7 @@ const std = @import("std");
 
 const Elephant = struct {
     letter: u8,
-    tail: *Elephant = null, // Hmm... tail needs something...
+    tail: ?*Elephant = null, // Hmm... tail needs something...
     visited: bool = false,
 };
 
@@ -34,6 +34,7 @@ pub fn main() void {
     // Link the elephants so that each tail "points" to the next.
     linkElephants(&elephantA, &elephantB);
     linkElephants(&elephantB, &elephantC);
+    linkElephants(&elephantC, &elephantA);
 
     // `linkElephants` will stop the program if you try and link an
     // elephant that doesn't exist! Uncomment and see what happens.
@@ -66,6 +67,6 @@ fn visitElephants(first_elephant: *Elephant) void {
 
         // 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.?;
     }
 }

Exercise 047

diff --git a/exercises/047_methods.zig b/exercises/047_methods.zig
index 3221ca2..3a2bac5 100644
--- a/exercises/047_methods.zig
+++ b/exercises/047_methods.zig
@@ -88,7 +88,7 @@ pub fn main() void {
         for (&aliens) |*alien| {
 
             // *** Zap the alien with the heat ray here! ***
-            ???.zap(???);
+            heat_ray.zap(alien);
 
             // If the alien's health is still above 0, it's still alive.
             if (alien.health > 0) aliens_alive += 1;

Exercise 048

diff --git a/exercises/048_methods2.zig b/exercises/048_methods2.zig
index a1fbe9e..f0ce821 100644
--- a/exercises/048_methods2.zig
+++ b/exercises/048_methods2.zig
@@ -54,7 +54,7 @@ fn visitElephants(first_elephant: *Elephant) void {
 
         // This gets the next elephant or stops:
         // which method do we want here?
-        e = if (e.hasTail()) e.??? else break;
+        e = if (e.hasTail()) e.getTail() else break;
     }
 }
 

Exercise 049

diff --git a/exercises/049_quiz6.zig b/exercises/049_quiz6.zig
index 9dbea51..2da18de 100644
--- a/exercises/049_quiz6.zig
+++ b/exercises/049_quiz6.zig
@@ -27,7 +27,13 @@ const Elephant = struct {
     // Your Elephant trunk methods go here!
     // ---------------------------------------------------
 
-    ???
+    pub fn getTrunk(self: *Elephant) *Elephant {
+        return self.trunk.?;
+    }
+
+    pub fn hasTrunk(self: *Elephant) bool {
+        return (self.trunk != null);
+    }
 
     // ---------------------------------------------------
 

Exercise 050

diff --git a/exercises/050_no_value.zig b/exercises/050_no_value.zig
index f5365cf..8bca2ea 100644
--- a/exercises/050_no_value.zig
+++ b/exercises/050_no_value.zig
@@ -65,10 +65,10 @@ const std = @import("std");
 const Err = error{Cthulhu};
 
 pub fn main() void {
-    var first_line1: *const [16]u8 = ???;
+    var first_line1: *const [16]u8 = undefined;
     first_line1 = "That is not dead";
 
-    var first_line2: Err!*const [21]u8 = ???;
+    var first_line2: Err!*const [21]u8 = undefined;
     first_line2 = "which can eternal lie";
 
     // Note we need the "{!s}" format for the error union string.
@@ -77,8 +77,8 @@ pub fn main() void {
     printSecondLine();
 }
 
-fn printSecondLine() ??? {
-    var second_line2: ?*const [18]u8 = ???;
+fn printSecondLine() void {
+    var second_line2: ?*const [18]u8 = undefined;
     second_line2 = "even death may die";
 
     std.debug.print("And with strange aeons {s}.\n", .{second_line2.?});

Exercise 051

diff --git a/exercises/051_values.zig b/exercises/051_values.zig
index 4e98d8e..debd521 100644
--- a/exercises/051_values.zig
+++ b/exercises/051_values.zig
@@ -87,7 +87,7 @@ pub fn main() void {
     // Let's assign the std.debug.print function to a const named
     // "print" so that we can use this new name later!
 
-    const print = ???;
+    const print = std.debug.print;
 
     // Now let's look at assigning and pointing to values in Zig.
     //
@@ -163,13 +163,13 @@ pub fn main() void {
     print("XP before:{}, ", .{glorp.experience});
 
     // Fix 1 of 2 goes here:
-    levelUp(glorp, reward_xp);
+    levelUp(&glorp, reward_xp);
 
     print("after:{}.\n", .{glorp.experience});
 }
 
 // Fix 2 of 2 goes here:
-fn levelUp(character_access: Character, xp: u32) void {
+fn levelUp(character_access: *Character, xp: u32) void {
     character_access.experience += xp;
 }
 

Exercise 052

diff --git a/exercises/052_slices.zig b/exercises/052_slices.zig
index af5930b..533b6af 100644
--- a/exercises/052_slices.zig
+++ b/exercises/052_slices.zig
@@ -32,8 +32,8 @@ pub fn main() void {
     var cards = [8]u8{ 'A', '4', 'K', '8', '5', '2', 'Q', 'J' };
 
     // Please put the first 4 cards in hand1 and the rest in hand2.
-    const hand1: []u8 = cards[???];
-    const hand2: []u8 = cards[???];
+    const hand1: []u8 = cards[0 .. cards.len / 2];
+    const hand2: []u8 = cards[cards.len / 2 ..];
 
     std.debug.print("Hand1: ", .{});
     printHand(hand1);
@@ -43,7 +43,7 @@ pub fn main() void {
 }
 
 // Please lend this function a hand. A u8 slice hand, that is.
-fn printHand(hand: ???) void {
+fn printHand(hand: []u8) void {
     for (hand) |h| {
         std.debug.print("{u} ", .{h});
     }

Exercise 053

diff --git a/exercises/053_slices2.zig b/exercises/053_slices2.zig
index 545b4da..924f6a3 100644
--- a/exercises/053_slices2.zig
+++ b/exercises/053_slices2.zig
@@ -17,19 +17,19 @@ const std = @import("std");
 pub fn main() void {
     const scrambled = "great base for all your justice are belong to us";
 
-    const base1: []u8 = scrambled[15..23];
-    const base2: []u8 = scrambled[6..10];
-    const base3: []u8 = scrambled[32..];
+    const base1: []const u8 = scrambled[15..23];
+    const base2: []const u8 = scrambled[6..10];
+    const base3: []const u8 = scrambled[32..];
     printPhrase(base1, base2, base3);
 
-    const justice1: []u8 = scrambled[11..14];
-    const justice2: []u8 = scrambled[0..5];
-    const justice3: []u8 = scrambled[24..31];
+    const justice1: []const u8 = scrambled[11..14];
+    const justice2: []const u8 = scrambled[0..5];
+    const justice3: []const u8 = scrambled[24..31];
     printPhrase(justice1, justice2, justice3);
 
     std.debug.print("\n", .{});
 }
 
-fn printPhrase(part1: []u8, part2: []u8, part3: []u8) void {
+fn printPhrase(part1: []const u8, part2: []const u8, part3: []const u8) void {
     std.debug.print("'{s} {s} {s}.' ", .{ part1, part2, part3 });
 }

Exercise 054

diff --git a/exercises/054_manypointers.zig b/exercises/054_manypointers.zig
index ede02df..8bb3971 100644
--- a/exercises/054_manypointers.zig
+++ b/exercises/054_manypointers.zig
@@ -33,7 +33,7 @@ pub fn main() void {
     // we can CONVERT IT TO A SLICE. (Hint: we do know the length!)
     //
     // Please fix this line so the print statement below can print it:
-    const zen12_string: []const u8 = zen_manyptr;
+    const zen12_string: []const u8 = zen_manyptr[0..zen12.len];
 
     // Here's the moment of truth!
     std.debug.print("{s}\n", .{zen12_string});

Exercise 055

diff --git a/exercises/055_unions.zig b/exercises/055_unions.zig
index 794f2df..a88cd2f 100644
--- a/exercises/055_unions.zig
+++ b/exercises/055_unions.zig
@@ -59,8 +59,8 @@ pub fn main() void {
     std.debug.print("Insect report! ", .{});
 
     // Oops! We've made a mistake here.
-    printInsect(ant, AntOrBee.c);
-    printInsect(bee, AntOrBee.c);
+    printInsect(ant, AntOrBee.a);
+    printInsect(bee, AntOrBee.b);
 
     std.debug.print("\n", .{});
 }

Exercise 056

diff --git a/exercises/056_unions2.zig b/exercises/056_unions2.zig
index c46d133..bebc833 100644
--- a/exercises/056_unions2.zig
+++ b/exercises/056_unions2.zig
@@ -44,14 +44,14 @@ pub fn main() void {
     std.debug.print("Insect report! ", .{});
 
     // Could it really be as simple as just passing the union?
-    printInsect(???);
-    printInsect(???);
+    printInsect(ant);
+    printInsect(bee);
 
     std.debug.print("\n", .{});
 }
 
 fn printInsect(insect: Insect) void {
-    switch (???) {
+    switch (insect) {
         .still_alive => |a| std.debug.print("Ant alive is: {}. ", .{a}),
         .flowers_visited => |f| std.debug.print("Bee visited {} flowers. ", .{f}),
     }

Exercise 057

diff --git a/exercises/057_unions3.zig b/exercises/057_unions3.zig
index a5017d2..0c3c3b2 100644
--- a/exercises/057_unions3.zig
+++ b/exercises/057_unions3.zig
@@ -15,7 +15,7 @@
 //
 const std = @import("std");
 
-const Insect = union(InsectStat) {
+const Insect = union(enum) {
     flowers_visited: u16,
     still_alive: bool,
 };

Exercise 058

diff --git a/exercises/058_quiz7.zig b/exercises/058_quiz7.zig
index fda83fc..a82294a 100644
--- a/exercises/058_quiz7.zig
+++ b/exercises/058_quiz7.zig
@@ -192,8 +192,8 @@ const TripItem = union(enum) {
             // Oops! The hermit forgot how to capture the union values
             // in a switch statement. Please capture each value as
             // 'p' so the print statements work!
-            .place => print("{s}", .{p.name}),
-            .path => print("--{}->", .{p.dist}),
+            .place => |p| print("{s}", .{p.name}),
+            .path => |p| print("--{}->", .{p.dist}),
         }
     }
 };
@@ -255,7 +255,7 @@ const HermitsNotebook = struct {
             // dereference and optional value "unwrapping" look
             // together. Remember that you return the address with the
             // "&" operator.
-            if (place == entry.*.?.place) return entry;
+            if (place == entry.*.?.place) return &entry.*.?;
             // Try to make your answer this long:__________;
         }
         return null;
@@ -309,7 +309,7 @@ const HermitsNotebook = struct {
     //
     // Looks like the hermit forgot something in the return value of
     // this function. What could that be?
-    fn getTripTo(self: *HermitsNotebook, trip: []?TripItem, dest: *Place) void {
+    fn getTripTo(self: *HermitsNotebook, trip: []?TripItem, dest: *Place) TripError!void {
         // We start at the destination entry.
         const destination_entry = self.getEntry(dest);
 

Exercise 059

diff --git a/exercises/059_integers.zig b/exercises/059_integers.zig
index ae65790..32953e5 100644
--- a/exercises/059_integers.zig
+++ b/exercises/059_integers.zig
@@ -20,9 +20,9 @@ const print = @import("std").debug.print;
 
 pub fn main() void {
     const zig = [_]u8{
-        0o131, // octal
-        0b1101000, // binary
-        0x66, // hex
+        0o132, // octal
+        0b1101001, // binary
+        0x67, // hex
     };
 
     print("{s} is cool.\n", .{zig});

Exercise 060

diff --git a/exercises/060_floats.zig b/exercises/060_floats.zig
index 90da930..ee18246 100644
--- a/exercises/060_floats.zig
+++ b/exercises/060_floats.zig
@@ -43,7 +43,7 @@ pub fn main() void {
     //
     // We'll convert this weight from pounds to metric units at a
     // conversion of 0.453592 kg to the pound.
-    const shuttle_weight: f16 = 0.453592 * 4480e3;
+    const shuttle_weight: f32 = 0.453592 * 4480e3;
 
     // By default, float values are formatted in standard decimal
     // notation. Experiment with '{d}' and '{d:.3}' to see how

Exercise 061

diff --git a/exercises/061_coercions.zig b/exercises/061_coercions.zig
index ccf3c9b..0ecf542 100644
--- a/exercises/061_coercions.zig
+++ b/exercises/061_coercions.zig
@@ -67,7 +67,7 @@ const print = @import("std").debug.print;
 pub fn main() void {
     var letter: u8 = 'A';
 
-    const my_letter:   ???   = &letter;
+    const my_letter: ?*[1]u8 = &letter;
     //               ^^^^^^^
     //           Your type here.
     // Must coerce from &letter (which is a *u8).

Exercise 062

diff --git a/exercises/062_loop_expressions.zig b/exercises/062_loop_expressions.zig
index f6b8771..8c37e28 100644
--- a/exercises/062_loop_expressions.zig
+++ b/exercises/062_loop_expressions.zig
@@ -47,7 +47,7 @@ pub fn main() void {
     // return it from the for loop.
     const current_lang: ?[]const u8 = for (langs) |lang| {
         if (lang.len == 3) break lang;
-    };
+    } else null;
 
     if (current_lang) |cl| {
         print("Current language: {s}\n", .{cl});

Exercise 063

diff --git a/exercises/063_labels.zig b/exercises/063_labels.zig
index 79adfaa..796325a 100644
--- a/exercises/063_labels.zig
+++ b/exercises/063_labels.zig
@@ -115,21 +115,21 @@ pub fn main() void {
             // (Remember that want_it will be the index number of
             // the ingredient based on its position in the
             // required ingredient list for each food.)
-            const found = for (wanted_ingredients) |want_it| {
-                if (required_ingredient == want_it) break true;
-            } else false;
+            for (wanted_ingredients) |want_it| {
+                if (required_ingredient == want_it) break;
+            } else continue :food_loop;
 
             // We did not find this required ingredient, so we
             // can't make this Food. Continue the outer loop.
-            if (!found) continue :food_loop;
+            // if (!found) continue :food_loop;
         }
 
         // If we get this far, the required ingredients were all
         // wanted for this Food.
         //
         // Please return this Food from the loop.
-        break;
-    };
+        break food;
+    } else menu[0];
     // ^ Oops! We forgot to return Mac & Cheese as the default
     // Food when the requested ingredients aren't found.
 

Exercise 064

diff --git a/exercises/064_builtins.zig b/exercises/064_builtins.zig
index e91dfbe..30c165b 100644
--- a/exercises/064_builtins.zig
+++ b/exercises/064_builtins.zig
@@ -63,7 +63,7 @@ pub fn main() void {
     //
     // If there was no overflow at all while adding 5 to a, what value would
     // 'my_result' hold? Write the answer in into 'expected_result'.
-    const expected_result: u8 = ???;
+    const expected_result: u8 = 0b00010010;
     print(". Without overflow: {b:0>8}. ", .{expected_result});
 
     print("Furthermore, ", .{});
@@ -78,6 +78,6 @@ pub fn main() void {
     // Now it's your turn. See if you can fix this attempt to use
     // this builtin to reverse the bits of a u8 integer.
     const input: u8 = 0b11110000;
-    const tupni: u8 = @bitReverse(input, tupni);
+    const tupni: u8 = @bitReverse(input);
     print("{b:0>8} backwards is {b:0>8}.\n", .{ input, tupni });
 }

Exercise 065

diff --git a/exercises/065_builtins2.zig b/exercises/065_builtins2.zig
index 2d13994..66b9da1 100644
--- a/exercises/065_builtins2.zig
+++ b/exercises/065_builtins2.zig
@@ -58,7 +58,7 @@ pub fn main() void {
     // Oops! We cannot leave the 'me' and 'myself' fields
     // undefined. Please set them here:
     narcissus.me = &narcissus;
-    narcissus.??? = ???;
+    narcissus.myself = &narcissus;
 
     // This determines a "peer type" from three separate
     // references (they just happen to all be the same object).
@@ -70,7 +70,7 @@ pub fn main() void {
     //
     // The fix for this is very subtle, but it makes a big
     // difference!
-    const Type2 = narcissus.fetchTheMostBeautifulType();
+    const Type2 = Narcissus.fetchTheMostBeautifulType();
 
     // Now we print a pithy statement about Narcissus.
     print("A {s} loves all {s}es. ", .{
@@ -113,15 +113,15 @@ pub fn main() void {
     // Please complete these 'if' statements so that the field
     // 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) {
+    if (fields[0].type != void) {
         print(" {s}", .{fields[0].name});
     }
 
-    if (fields[1].??? != void) {
+    if (fields[1].type != void) {
         print(" {s}", .{fields[1].name});
     }
 
-    if (fields[2].??? != void) {
+    if (fields[2].type != void) {
         print(" {s}", .{fields[2].name});
     }
 

Exercise 066

diff --git a/exercises/066_comptime.zig b/exercises/066_comptime.zig
index 9b07a2d..124b472 100644
--- a/exercises/066_comptime.zig
+++ b/exercises/066_comptime.zig
@@ -62,8 +62,8 @@ pub fn main() void {
     // types with specific sizes. The comptime numbers will be
     // coerced (if they'll fit!) into your chosen runtime types.
     // For this it is necessary to specify a size, e.g. 32 bit.
-    var var_int = 12345;
-    var var_float = 987.654;
+    var var_int: u32 = 12345;
+    var var_float: f32 = 987.654;
 
     // We can change what is stored at the areas set aside for
     // "var_int" and "var_float" in the running compiled program.

Exercise 067

diff --git a/exercises/067_comptime2.zig b/exercises/067_comptime2.zig
index bdbc3da..3984001 100644
--- a/exercises/067_comptime2.zig
+++ b/exercises/067_comptime2.zig
@@ -36,7 +36,7 @@ pub fn main() void {
     // In this contrived example, we've decided to allocate some
     // arrays using a variable count! But something's missing...
     //
-    var count = 0;
+    comptime var count = 0;
 
     count += 1;
     const a1: [count]u8 = .{'A'} ** count;

Exercise 068

diff --git a/exercises/068_comptime3.zig b/exercises/068_comptime3.zig
index 15b8997..1bd5fd1 100644
--- a/exercises/068_comptime3.zig
+++ b/exercises/068_comptime3.zig
@@ -43,7 +43,7 @@ const Schooner = struct {
         //
         // Please change this so that it sets a 0 scale to 1
         // instead.
-        if (my_scale == 0) @compileError("Scale 1:0 is not valid!");
+        if (my_scale == 0) my_scale = 1;
 
         self.scale = my_scale;
         self.hull_length /= my_scale;
@@ -69,7 +69,7 @@ pub fn main() void {
     // Hey, we can't just pass this runtime variable as an
     // argument to the scaleMe() method. What would let us do
     // that?
-    var scale: u32 = undefined;
+    comptime var scale: u32 = undefined;
 
     scale = 32; // 1:32 scale
 

Exercise 069

diff --git a/exercises/069_comptime4.zig b/exercises/069_comptime4.zig
index e090bb3..0263de0 100644
--- a/exercises/069_comptime4.zig
+++ b/exercises/069_comptime4.zig
@@ -42,8 +42,8 @@ pub fn main() void {
 //     2) Sets the size of the array of type T (which is the
 //        sequence we're creating and returning).
 //
-fn makeSequence(comptime T: type, ??? size: usize) [???]T {
-    var sequence: [???]T = undefined;
+fn makeSequence(comptime T: type, comptime size: usize) [size]T {
+    var sequence: [size]T = undefined;
     var i: usize = 0;
 
     while (i < size) : (i += 1) {

Exercise 070

diff --git a/exercises/070_comptime5.zig b/exercises/070_comptime5.zig
index afd4ae8..c6bc4bb 100644
--- a/exercises/070_comptime5.zig
+++ b/exercises/070_comptime5.zig
@@ -123,8 +123,8 @@ fn isADuck(possible_duck: anytype) bool {
     // Please make sure MyType has both waddle() and quack()
     // methods:
     const MyType = @TypeOf(possible_duck);
-    const walks_like_duck = ???;
-    const quacks_like_duck = ???;
+    const walks_like_duck = @hasDecl(MyType, "waddle");
+    const quacks_like_duck = @hasDecl(MyType, "quack");
 
     const is_duck = walks_like_duck and quacks_like_duck;
 

Exercise 071

diff --git a/exercises/071_comptime6.zig b/exercises/071_comptime6.zig
index 9b3e5a2..3274c5b 100644
--- a/exercises/071_comptime6.zig
+++ b/exercises/071_comptime6.zig
@@ -40,7 +40,7 @@ pub fn main() void {
 
     const fields = @typeInfo(Narcissus).@"struct".fields;
 
-    ??? {
+    inline for (fields) |field| {
         if (field.type != void) {
             print(" {s}", .{field.name});
         }

Exercise 072

diff --git a/exercises/072_comptime7.zig b/exercises/072_comptime7.zig
index 631e75b..1bdcc1a 100644
--- a/exercises/072_comptime7.zig
+++ b/exercises/072_comptime7.zig
@@ -35,7 +35,7 @@ pub fn main() void {
     // at compile time.
     //
     // Please fix this to loop once per "instruction":
-    ??? (i < instructions.len) : (???) {
+    inline while (i < instructions.len) : (i += 3) {
 
         // This gets the digit from the "instruction". Can you
         // figure out why we subtract '0' from it?

Exercise 073

diff --git a/exercises/073_comptime8.zig b/exercises/073_comptime8.zig
index fe1f8ea..2e69566 100644
--- a/exercises/073_comptime8.zig
+++ b/exercises/073_comptime8.zig
@@ -32,12 +32,12 @@ const llamas = [llama_count]u32{ 5, 10, 15, 20, 25 };
 pub fn main() void {
     // We meant to fetch the last llama. Please fix this simple
     // mistake so the assertion no longer fails.
-    const my_llama = getLlama(5);
+    const my_llama = getLlama(4);
 
     print("My llama value is {}.\n", .{my_llama});
 }
 
-fn getLlama(i: usize) u32 {
+fn getLlama(comptime i: usize) u32 {
     // We've put a guard assert() at the top of this function to
     // prevent mistakes. The 'comptime' keyword here means that
     // the mistake will be caught when we compile!

Exercise 074

diff --git a/exercises/074_comptime9.zig b/exercises/074_comptime9.zig
index 4088aad..5eaa6fd 100644
--- a/exercises/074_comptime9.zig
+++ b/exercises/074_comptime9.zig
@@ -39,7 +39,7 @@ const llamas = makeLlamas(llama_count);
 
 // And here's the function. Note that the return value type
 // depends on one of the input arguments!
-fn makeLlamas(count: usize) [count]u8 {
+fn makeLlamas(comptime count: usize) [count]u8 {
     var temp: [count]u8 = undefined;
     var i = 0;
 

Exercise 075

diff --git a/exercises/075_quiz8.zig b/exercises/075_quiz8.zig
index 63d208b..5fd2e9f 100644
--- a/exercises/075_quiz8.zig
+++ b/exercises/075_quiz8.zig
@@ -49,7 +49,7 @@ const Path = struct {
 //
 // Please fill in the body of this function!
 fn makePath(from: *Place, to: *Place, dist: u8) Path {
-
+    return Path{ .from = from, .to = to, .dist = dist };
 }
 
 // Using our new function, these path definitions take up considerably less

Exercise 076

diff --git a/exercises/076_sentinels.zig b/exercises/076_sentinels.zig
index accb600..e8b956b 100644
--- a/exercises/076_sentinels.zig
+++ b/exercises/076_sentinels.zig
@@ -82,7 +82,7 @@ fn printSequence(my_seq: anytype) void {
             print("Array:", .{});
 
             // Loop through the items in my_seq.
-            for (???) |s| {
+            for (my_seq) |s| {
                 print("{}", .{s});
             }
         },
@@ -93,8 +93,8 @@ fn printSequence(my_seq: anytype) void {
 
             // Loop through the items in my_seq until we hit the
             // sentinel value.
-            var i: usize = 0;
-            while (??? != my_sentinel) {
+            var i: u32 = 0;
+            while (my_seq[i] != my_sentinel) {
                 print("{}", .{my_seq[i]});
                 i += 1;
             }

Exercise 077

diff --git a/exercises/077_sentinels2.zig b/exercises/077_sentinels2.zig
index fb8f13d..c2fb54c 100644
--- a/exercises/077_sentinels2.zig
+++ b/exercises/077_sentinels2.zig
@@ -60,7 +60,7 @@ pub fn main() void {
     // length... You've actually solved this problem before!
     //
     // Here's a big hint: do you remember how to take a slice?
-    const printable = ???;
+    const printable = foo.data[0..foo.length];
 
     print("{s}\n", .{printable});
 }

Exercise 078

diff --git a/exercises/078_sentinels3.zig b/exercises/078_sentinels3.zig
index 1e443e6..90b953f 100644
--- a/exercises/078_sentinels3.zig
+++ b/exercises/078_sentinels3.zig
@@ -21,7 +21,7 @@ pub fn main() void {
     const data: [*]const u8 = "Weird Data!";
 
     // Please cast 'data' to 'printable':
-    const printable: [*:0]const u8 = ???;
+    const printable: [*:0]const u8 = @ptrCast(data);
 
     print("{s}\n", .{printable});
 }

Exercise 079

diff --git a/exercises/079_quoted_identifiers.zig b/exercises/079_quoted_identifiers.zig
index 182c7ff..6abbe59 100644
--- a/exercises/079_quoted_identifiers.zig
+++ b/exercises/079_quoted_identifiers.zig
@@ -20,11 +20,11 @@
 const print = @import("std").debug.print;
 
 pub fn main() void {
-    const 55_cows: i32 = 55;
-    const isn't true: bool = false;
+    const @"55_cows": i32 = 55;
+    const @"isn't true": bool = false;
 
     print("Sweet freedom: {}, {}.\n", .{
-        55_cows,
-        isn't true,
+        @"55_cows",
+        @"isn't true",
     });
 }

Exercise 080

diff --git a/exercises/080_anonymous_structs.zig b/exercises/080_anonymous_structs.zig
index 4e3ce84..452b647 100644
--- a/exercises/080_anonymous_structs.zig
+++ b/exercises/080_anonymous_structs.zig
@@ -48,13 +48,13 @@ pub fn main() void {
     // * circle1 should hold i32 integers
     // * circle2 should hold f32 floats
     //
-    const circle1 = ??? {
+    const circle1 = Circle(i32){
         .center_x = 25,
         .center_y = 70,
         .radius = 15,
     };
 
-    const circle2 = ??? {
+    const circle2 = Circle(f32){
         .center_x = 25.234,
         .center_y = 70.999,
         .radius = 15.714,

Exercise 081

diff --git a/exercises/081_anonymous_structs2.zig b/exercises/081_anonymous_structs2.zig
index df78713..0b84438 100644
--- a/exercises/081_anonymous_structs2.zig
+++ b/exercises/081_anonymous_structs2.zig
@@ -38,7 +38,7 @@ pub fn main() void {
 
 // Please complete this function which prints an anonymous struct
 // representing a circle.
-fn printCircle(???) void {
+fn printCircle(circle: anytype) void {
     print("x:{} y:{} radius:{}\n", .{
         circle.center_x,
         circle.center_y,

Exercise 082

diff --git a/exercises/082_anonymous_structs3.zig b/exercises/082_anonymous_structs3.zig
index 469cd66..1994e01 100644
--- a/exercises/082_anonymous_structs3.zig
+++ b/exercises/082_anonymous_structs3.zig
@@ -82,14 +82,14 @@ fn printTuple(tuple: anytype) void {
     //         @typeInfo(Circle).@"struct".fields
     //
     // This will be an array of StructFields.
-    const fields = ???;
+    const fields = @typeInfo(@TypeOf(tuple)).@"struct".fields;
 
     // 2. Loop through each field. This must be done at compile
     // time.
     //
     //     Hint: remember 'inline' loops?
     //
-    for (fields) |field| {
+    inline for (fields) |field| {
         // 3. Print the field's name, type, and value.
         //
         //     Each 'field' in this loop is one of these:
@@ -119,9 +119,10 @@ fn printTuple(tuple: anytype) void {
         //
         // The first field should print as: "0"(bool):true
         print("\"{s}\"({any}):{any} ", .{
-            field.???,
-            field.???,
-            ???,
+            field.name,
+            field.type,
+            // this is poorly explained, but here we are
+            @field(tuple, field.name),
         });
     }
 }

Exercise 083

diff --git a/exercises/083_anonymous_lists.zig b/exercises/083_anonymous_lists.zig
index daaeaff..82d008a 100644
--- a/exercises/083_anonymous_lists.zig
+++ b/exercises/083_anonymous_lists.zig
@@ -20,6 +20,6 @@ pub fn main() void {
     //
     //     = .{ 'h', 'e', 'l', 'l', 'o' };
     //
-    const hello = .{ 'h', 'e', 'l', 'l', 'o' };
+    const hello: [5]u8 = .{ 'h', 'e', 'l', 'l', 'o' };
     print("I say {s}!\n", .{hello});
 }

Exercise 092

diff --git a/exercises/092_interfaces.zig b/exercises/092_interfaces.zig
index 7775dd5..12caaaf 100644
--- a/exercises/092_interfaces.zig
+++ b/exercises/092_interfaces.zig
@@ -106,7 +106,7 @@ pub fn main() !void {
     for (my_insects) |insect| {
         // Almost done! We want to print() each insect with a
         // single method call here.
-        ???
+        insect.print();
     }
 }
 

Exercise 093

diff --git a/exercises/093_hello_c.zig b/exercises/093_hello_c.zig
index 182e0b0..a1a40cb 100644
--- a/exercises/093_hello_c.zig
+++ b/exercises/093_hello_c.zig
@@ -54,7 +54,7 @@ pub fn main() void {
     //
     // In this exercise we use 'write' to output 17 chars,
     // but something is still missing...
-    const c_res = write(2, "Hello C from Zig!", 17);
+    const c_res = c.write(2, "Hello C from Zig!", 17);
 
     // let's see what the result from C is:
     std.debug.print(" - C result is {d} chars written.\n", .{c_res});

Exercise 094

diff --git a/exercises/094_c_math.zig b/exercises/094_c_math.zig
index ec59a86..395ed34 100644
--- a/exercises/094_c_math.zig
+++ b/exercises/094_c_math.zig
@@ -26,7 +26,7 @@ const std = @import("std");
 
 const c = @cImport({
     // What do we need here?
-    ???
+    @cInclude("math.h");
 });
 
 pub fn main() !void {

Exercise 095

diff --git a/exercises/095_for3.zig b/exercises/095_for3.zig
index 0d4f42f..30f19bb 100644
--- a/exercises/095_for3.zig
+++ b/exercises/095_for3.zig
@@ -54,7 +54,7 @@ pub fn main() void {
 
     // I want to print every number between 1 and 20 that is NOT
     // divisible by 3 or 5.
-    for (???) |n| {
+    for (1..20) |n| {
 
         // The '%' symbol is the "modulo" operator and it
         // returns the remainder after division.

Exercise 096

diff --git a/exercises/096_memory_allocation.zig b/exercises/096_memory_allocation.zig
index 58de7b0..e353008 100644
--- a/exercises/096_memory_allocation.zig
+++ b/exercises/096_memory_allocation.zig
@@ -64,7 +64,7 @@ pub fn main() !void {
     const allocator = arena.allocator();
 
     // allocate memory for this array
-    const avg: []f64 = ???;
+    const avg: []f64 = try allocator.alloc(f64, arr.len);
 
     runningAverage(arr, avg);
     std.debug.print("Running Average: ", .{});

Exercise 097

diff --git a/exercises/097_bit_manipulation.zig b/exercises/097_bit_manipulation.zig
index 0e64ad7..d5d419d 100644
--- a/exercises/097_bit_manipulation.zig
+++ b/exercises/097_bit_manipulation.zig
@@ -80,7 +80,7 @@ pub fn main() !void {
     y ^= x;
 
     // What must be written here?
-    ???;
+    x ^= y;
 
     print("x = {b}; y = {b}\n", .{ x, y });
 }

Exercise 098

diff --git a/exercises/098_bit_manipulation2.zig b/exercises/098_bit_manipulation2.zig
index 8b51265..62b11ed 100644
--- a/exercises/098_bit_manipulation2.zig
+++ b/exercises/098_bit_manipulation2.zig
@@ -60,5 +60,5 @@ fn isPangram(str: []const u8) bool {
     // and if so, we know the given string is a pangram
     //
     // but what do we have to compare?
-    return bits == 0x..???;
+    return bits == 0x3ffffff;
 }

Exercise 099

diff --git a/exercises/099_formatting.zig b/exercises/099_formatting.zig
index ef6b84e..37fa877 100644
--- a/exercises/099_formatting.zig
+++ b/exercises/099_formatting.zig
@@ -131,7 +131,7 @@ pub fn main() !void {
         for (0..size) |b| {
             // What formatting is needed here to make our columns
             // nice and straight?
-            print("{???} ", .{(a + 1) * (b + 1)});
+            print("{d:>3} ", .{(a + 1) * (b + 1)});
         }
 
         // After each row we use double line feed:

Exercise 100

diff --git a/exercises/100_for4.zig b/exercises/100_for4.zig
index c8a1161..f2c1d5f 100644
--- a/exercises/100_for4.zig
+++ b/exercises/100_for4.zig
@@ -39,7 +39,7 @@ pub fn main() void {
     const hex_nums = [_]u8{ 0xb, 0x2a, 0x77 };
     const dec_nums = [_]u8{ 11, 42, 119 };
 
-    for (hex_nums, ???) |hn, ???| {
+    for (hex_nums, dec_nums) |hn, dn| {
         if (hn != dn) {
             print("Uh oh! Found a mismatch: {d} vs {d}\n", .{ hn, dn });
             return;

Exercise 101

diff --git a/exercises/101_for5.zig b/exercises/101_for5.zig
index 200e71d..be968db 100644
--- a/exercises/101_for5.zig
+++ b/exercises/101_for5.zig
@@ -51,7 +51,7 @@ pub fn main() void {
 
     // We would like to number our list starting with 1, not 0.
     // How do we do that?
-    for (roles, gold, experience, ???) |c, g, e, i| {
+    for (roles, gold, experience, 1..) |c, g, e, i| {
         const role_name = switch (c) {
             .wizard => "Wizard",
             .thief => "Thief",

Exercise 102

diff --git a/exercises/102_testing.zig b/exercises/102_testing.zig
index 0dec9b9..d713d53 100644
--- a/exercises/102_testing.zig
+++ b/exercises/102_testing.zig
@@ -71,7 +71,7 @@ fn sub(a: f16, b: f16) f16 {
 // The corresponding test is not much different from the previous one. Except
 // that it contains an error that you need to correct.
 test "sub" {
-    try testing.expect(sub(10, 5) == 6);
+    try testing.expect(sub(10, 5) == 5);
 
     try testing.expect(sub(3, 1.5) == 1.5);
 }
@@ -92,5 +92,5 @@ test "divide" {
 
     // Now we test if the function returns an error if we pass a zero as
     // denominator. But which error needs to be tested?
-    try testing.expectError(error.???, divide(15, 0));
+    try testing.expectError(error.DivisionByZero, divide(15, 0));
 }

Exercise 103

diff --git a/exercises/103_tokenization.zig b/exercises/103_tokenization.zig
index 972e8e8..86e4258 100644
--- a/exercises/103_tokenization.zig
+++ b/exercises/103_tokenization.zig
@@ -135,7 +135,7 @@ pub fn main() !void {
     ;
 
     // now the tokenizer, but what do we need here?
-    var it = std.mem.tokenizeAny(u8, poem, ???);
+    var it = std.mem.tokenizeAny(u8, poem, "; ,!\n");
 
     // print all words and count them
     var cnt: usize = 0;

Exercise 104

diff --git a/exercises/104_threading.zig b/exercises/104_threading.zig
index 2b0e6f7..fe9023d 100644
--- a/exercises/104_threading.zig
+++ b/exercises/104_threading.zig
@@ -97,12 +97,12 @@ pub fn main() !void {
         defer handle.join();
 
         // Second thread
-        const handle2 = try std.Thread.spawn(.{}, thread_function, .{-4}); // that can't be right?
+        const handle2 = try std.Thread.spawn(.{}, thread_function, .{2}); // that can't be right?
         defer handle2.join();
 
         // Third thread
         const handle3 = try std.Thread.spawn(.{}, thread_function, .{3});
-        defer ??? // <-- something is missing
+        defer handle3.join(); // <-- something is missing
 
         // After the threads have been started,
         // they run in parallel and we can still do some work in between.

Exercise 105

diff --git a/exercises/105_threading2.zig b/exercises/105_threading2.zig
index 374391a..0edd9b3 100644
--- a/exercises/105_threading2.zig
+++ b/exercises/105_threading2.zig
@@ -81,8 +81,8 @@ pub fn main() !void {
         defer handle1.join();
 
         // Second thread to calculate the minus numbers.
-        ???
-        
+        const handle2 = try std.Thread.spawn(.{}, thread_pi, .{ &pi_minus, 3, count });
+        defer handle2.join();
     }
     // Here we add up the results.
     std.debug.print("PI ≈ {d:.8}\n", .{4 + pi_plus - pi_minus});

Exercise 106

diff --git a/exercises/106_files.zig b/exercises/106_files.zig
index b38bc72..01efb94 100644
--- a/exercises/106_files.zig
+++ b/exercises/106_files.zig
@@ -35,7 +35,7 @@ pub fn main() !void {
         // by doing nothing
         //
         // we want to catch error.PathAlreadyExists and do nothing
-        ??? => {},
+        error.PathAlreadyExists => return,
         // if there's any other unexpected error we just propagate it through
         else => return e,
     };
@@ -44,7 +44,7 @@ pub fn main() !void {
     // wait a minute...
     // opening a directory might fail!
     // what should we do here?
-    var output_dir: std.fs.Dir = cwd.openDir("output", .{});
+    var output_dir: std.fs.Dir = try cwd.openDir("output", .{});
     defer output_dir.close();
 
     // we try to open the file `zigling.txt`,
@@ -55,7 +55,7 @@ pub fn main() !void {
     // but here we are not yet done writing to the file
     // if only there were a keyword in Zig that
     // allowed you to "defer" code execution to the end of the scope...
-    file.close();
+    defer file.close();
 
     // you are not allowed to move these two lines above the file closing line!
     const byte_written = try file.write("It's zigling time!");

Exercise 107

diff --git a/exercises/107_files2.zig b/exercises/107_files2.zig
index 9b94101..5b3d91e 100644
--- a/exercises/107_files2.zig
+++ b/exercises/107_files2.zig
@@ -33,7 +33,7 @@ pub fn main() !void {
     // initialize 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 initialization 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 @@ pub fn main() !void {
     // 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 valid 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?
     std.debug.print("Successfully Read {d} bytes: {s}\n", .{
         bytes_read,
-        content, // change this line only
+        content[0..bytes_read], // change this line only
     });
 }

Exercise 108

diff --git a/exercises/108_labeled_switch.zig b/exercises/108_labeled_switch.zig
index 897fcf5..3c0ed90 100644
--- a/exercises/108_labeled_switch.zig
+++ b/exercises/108_labeled_switch.zig
@@ -67,13 +67,13 @@ pub fn main() void {
     // how would you fix it?
     pr: switch (PullRequestState.Draft) {
         PullRequestState.Draft => continue :pr PullRequestState.InReview,
-        PullRequestState.InReview => continue :pr PullRequestState.Rejected,
+        PullRequestState.InReview => continue :pr PullRequestState.Approved,
         PullRequestState.Approved => continue :pr PullRequestState.Merged,
         PullRequestState.Rejected => {
             std.debug.print("The pull request has been rejected.\n", .{});
             return;
         },
-        PullRequestState.Merged => break, // Would you know where to break to?
+        PullRequestState.Merged => break :pr, // Would you know where to break to?
     }
     std.debug.print("The pull request has been merged.\n", .{});
 }

Exercise 109

diff --git a/exercises/109_vectors.zig b/exercises/109_vectors.zig
index 96892ca..f7dee84 100644
--- a/exercises/109_vectors.zig
+++ b/exercises/109_vectors.zig
@@ -74,6 +74,9 @@
 // SIMD instructions, whenever possible.
 //
 // Defining vectors in Zig is straightforwards. No library import is needed.
+const std = @import("std");
+const print = std.debug.print;
+
 const v1 = @Vector(3, i32){ 1, 10, 100 };
 const v2 = @Vector(3, f32){ 2.0, 3.0, 5.0 };
 
@@ -121,8 +124,8 @@ fn calcMaxPairwiseDiffOld(list1: [4]f32, list2: [4]f32) f32 {
 
 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;
 }
 
@@ -134,9 +137,6 @@ fn calcMaxPairwiseDiffNew(a: Vec4, b: Vec4) f32 {
 // 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 };

Exercise 110

diff --git a/exercises/110_quiz9.zig b/exercises/110_quiz9.zig
index 8f5cb61..8c35b30 100644
--- a/exercises/110_quiz9.zig
+++ b/exercises/110_quiz9.zig
@@ -84,7 +84,7 @@ pub fn main() !void {
     PORTB = 0b1100;
     print("  {b:0>4} // (initial state of PORTB)\n", .{PORTB});
     print("^ {b:0>4} // (bitmask)\n", .{0b0101});
-    PORTB ^= (1 << 1) | (1 << 0); // What's wrong here?
+    PORTB ^= (1 << 2) | (1 << 0); // What's wrong here?
     checkAnswer(0b1001, PORTB);
 
     newline();
@@ -92,7 +92,7 @@ pub fn main() !void {
     PORTB = 0b1100;
     print("  {b:0>4} // (initial state of PORTB)\n", .{PORTB});
     print("^ {b:0>4} // (bitmask)\n", .{0b0011});
-    PORTB ^= (1 << 1) & (1 << 0); // What's wrong here?
+    PORTB ^= (1 << 1) | (1 << 0); // What's wrong here?
     checkAnswer(0b1111, PORTB);
 
     newline();
@@ -103,7 +103,7 @@ pub fn main() !void {
     PORTB = 0b1001; // reset PORTB
     print("  {b:0>4} // (initial state of PORTB)\n", .{PORTB});
     print("| {b:0>4} // (bitmask)\n", .{0b0100});
-    PORTB = PORTB ??? (1 << 2); // What's missing here?
+    PORTB = PORTB | (1 << 2); // What's missing here?
     checkAnswer(0b1101, PORTB);
 
     newline();
@@ -111,7 +111,7 @@ pub fn main() !void {
     PORTB = 0b1001; // reset PORTB
     print("  {b:0>4} // (reset state)\n", .{PORTB});
     print("| {b:0>4} // (bitmask)\n", .{0b0100});
-    PORTB ??? (1 << 2); // What's missing here?
+    PORTB |= (1 << 2); // What's missing here?
     checkAnswer(0b1101, PORTB);
 
     newline();
@@ -122,7 +122,7 @@ pub fn main() !void {
     PORTB = 0b1110; // reset PORTB
     print("  {b:0>4} // (initial state of PORTB)\n", .{PORTB});
     print("& {b:0>4} // (bitmask)\n", .{0b1011});
-    PORTB = PORTB & ???@as(u4, 1 << 2); // What character is missing here?
+    PORTB = PORTB & ~@as(u4, 1 << 2); // What character is missing here?
     checkAnswer(0b1010, PORTB);
 
     newline();
@@ -130,7 +130,7 @@ pub fn main() !void {
     PORTB = 0b0111; // reset PORTB
     print("  {b:0>4} // (reset state)\n", .{PORTB});
     print("& {b:0>4} // (bitmask)\n", .{0b1110});
-    PORTB &= ~(1 << 0); // What's missing here?
+    PORTB &= ~@as(u4, 1 << 0); // What's missing here?
     checkAnswer(0b0110, PORTB);
 
     newline();
../