diff --git a/build.zig b/build.zig
index 38890c2..1b4855d 100644
--- a/build.zig
+++ b/build.zig
@@ -1076,6 +1076,10 @@ const exercises = [_]Exercise{
         .main_file = "100_for4.zig",
         .output = "Arrays match!",
     },
+    .{
+        .main_file = "101_for5.zig",
+        .output = "1. Wizard (Gold: 25, XP: 40)\n2. Bard (Gold: 11, XP: 17)\n3. Bard (Gold: 5, XP: 55)\n4. Warrior (Gold: 7392, XP: 21)",
+    },
     .{
         .main_file = "999_the_end.zig",
         .output = "\nThis is the end for now!\nWe hope you had fun and were able to learn a lot, so visit us again when the next exercises are available.",
diff --git a/exercises/101_for5.zig b/exercises/101_for5.zig
new file mode 100644
index 0000000..3861417
--- /dev/null
+++ b/exercises/101_for5.zig
@@ -0,0 +1,120 @@
+//
+// The 'for' loop is not just limited to looping over one or two
+// items. Let's try an example with a whole bunch!
+//
+// But first, there's one last thing we've avoided mentioning
+// until now: The special range that leaves off the last value:
+//
+//     for ( things, 0.. ) |t, i| { ... }
+//
+// That's how we tell Zig that we want to get a numeric value for
+// every item in "things", starting with 0.
+//
+// A nice feature of these index ranges is that you can have them
+// start with any number you choose. The first value of "i" in
+// this example will be 500, then 501, 502, etc.:
+//
+//     for ( things, 500.. ) |t, i| { ... }
+//
+// Remember our RPG characters? They had the following
+// properties, which we stored in a struct type:
+//
+//     class
+//     gold
+//     experience
+//
+// What we're going to do now is store the same RPG character
+// data, but in a separate array for each property.
+//
+// It might look a little awkward, but let's bear with it.
+//
+// We've started writing a program to print a numbered list of
+// characters with each of their properties, but it needs a
+// little help:
+//
+const std = @import("std");
+const print = std.debug.print;
+
+// This is the same character class enum we've seen before.
+const Class = enum {
+    wizard,
+    thief,
+    bard,
+    warrior,
+};
+
+pub fn main() void {
+    // Here are the three "property" arrays:
+    const classes = [4]Class{ .wizard, .bard, .bard, .warrior };
+    const gold = [4]u16{ 25, 11, 5, 7392 };
+    const experience = [4]u8{ 40, 17, 55, 21 };
+
+    // We would like to number our list starting with 1, not 0.
+    // How do we do that?
+    for (classes, gold, experience, ???) |c, g, e, i| {
+        const class_name = switch (c) {
+            .wizard => "Wizard",
+            .thief => "Thief",
+            .bard => "Bard",
+            .warrior => "Warrior",
+        };
+
+        std.debug.print("{d}. {s} (Gold: {d}, XP: {d})\n", .{
+            i,
+            class_name,
+            g,
+            e,
+        });
+    }
+}
+//
+// By the way, storing our character data in arrays like this
+// isn't *just* a silly way to demonstrate multi-object 'for'
+// loops.
+//
+// It's *also* a silly way to introduce a concept called
+// "data-oriented design".
+//
+// Let's use a metaphor to build up an intuition for what this is
+// all about:
+//
+// Let's say you've been tasked with grabbing three glass
+// marbles, three spoons, and three feathers from a bucket. But
+// you can't use your hands to grab them. Instead, you have a
+// special marble scoop, spoon magnet, and feather tongs to grab
+// each type of object.
+//
+// Now, would you rather have:
+//
+// A. The items layered so you have to pick up one marble, then
+//    one spoon, then one feather?
+//
+//    OR
+//
+// B. The items separated by type so you can pick up all of the
+//    marbles at once, then all the spoons, then all of the
+//    feathers?
+//
+// If this metaphor is working, hopefully it's clear that the 'B'
+// option would be much more efficient.
+//
+// Well, it probably comes as little surprise that storing and
+// using data in a sequential and uniform fashion is also more
+// efficient for modern CPUs.
+//
+// Decades of OOP practices have steered people towards grouping
+// different data types together into "objects" with the hope
+// that it would be friendlier to the human mind. But
+// data-oriented design groups data in a way that is more
+// efficient for the computer.
+//
+// In Zig terminology, the difference in groupings is sometimes
+// known as "Array of Structs" (AoS) versus "Struct of Arrays"
+// (SoA).
+//
+// To envision these two designs in action, imagine an array of
+// RPG character structs, each containing three different data
+// types (AoS) versus a single RPG character struct containing
+// three arrays of one data type each, like those in the exercise
+// above (SoA).
+//
diff --git a/patches/patches/101_for5.patch b/patches/patches/101_for5.patch
new file mode 100644
index 0000000..0466cc8
--- /dev/null
+++ b/patches/patches/101_for5.patch
@@ -0,0 +1,4 @@
+54c54
+<     for (classes, gold, experience, ???) |c, g, e, i| {
+---
+>     for (classes, gold, experience, 1..) |c, g, e, i| {