diff --git a/exercises/099_formatting.zig b/exercises/099_formatting.zig index 6df2528..074358b 100644 --- a/exercises/099_formatting.zig +++ b/exercises/099_formatting.zig @@ -1,115 +1,140 @@ // -// The output on the console looks a bit rudimentary at first glance. -// However, if you look at the development of modern computers, you can -// see the enormous progress that has been made over the years. -// Starting with monochrome lines on flickering CRT monitors, modern -// terminal emulators offer a razor-sharp image with true color and -// nearly infinite font size thanks to modern hardware. +// Terminals have come a long way over the years. Starting with +// monochrome lines on flickering CRT monitors and continuously +// improving to today's modern terminal emulators with sharp +// images, true color, fonts, ligatures, and characters in every +// known language. // -// In addition, they have mastered ligatures and can represent almost -// any character in any language. This also makes the output of programs -// on the console more atractive than ever in recent years. +// Formatting our results to be appealing and allow quick visual +// comprehension of the information is what users desire. <3 // -// This makes it all the more important to format the presentation of -// results in an appealing way, because that is what users appreciate, -// quick visual comprehension of the information. +// C set string formatting standards over the years, and Zig is +// following suit and growing daily. Due to this growth, there is +// no official documentation for standard library features such +// as string formatting. // -// C has set standards here over the years, and Zig is preparing to -// follow suit. Currently, however, it still lags a bit behind the model, -// but the Zig community is working diligently behind the scenes on -// further options. +// Therefore, the comments for the format() function are the only +// way to definitively learn how to format strings in Zig: // -// Nevertheless, it is time to take a closer look at the possibilities -// that already exist. And of course we will continue this series loosely, -// because Zig continues to grow almost daily. +// https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig#L29 // -// Since there is no proper documentation on the formatting yet, the most -// important source here is the source code: +// Zig already has a very nice selection of formatting options. +// These can be used in different ways, but typically to convert +// numerical values into various text representations. The +// results can be used for direct output to a terminal or stored +// for later use or written to file. The latter is useful when +// large amounts of data are to be processed by other programs. // -// https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig#L29 +// In Ziglings, we are concerned with the output to the console. +// But since the formatting instructions for files are the same, +// what you learn applies universally. +// +// Since we write to "debug" output in Ziglings, our answers +// usually look something like this: // +// print("Text {placeholder} another text \n", .{foo}); // -// And in fact, you already discover quite a lot of useful formatting. -// These can be used in different ways, e.g. to convert numerical values -// into text and for direct output to the console or to a file. The latter -// is useful when large amounts of data are to be processed by other programs. +// In addition to being replaced with foo in this example, the +// {placeholder} in the string can also have formatting applied. +// How does that work? // -// However, we are concerned here exclusively with the output to the console. -// But since the formatting instructions for files are the same, what you -// learn applies universally. +// This actually happens in several stages. In one stage, escape +// sequences are evaluated. The one we've seen the most +// (including the example above) is "\n" which means "line feed". +// Whenever this statement is found, a new line is started in the +// output. Escape sequences can also be written one after the +// other, e.g. "\n\n" will cause two line feeds. // -// Since we basically write to debug output in Ziglings, our output usually -// looks like this: +// By the way, the result of these escape sequences are passed +// directly to the terminal program. Other than translating them +// into control codes, escape sequences have nothing to do with +// Zig. Zig knows nothing about "line feeds" or "tabs" or +// "bells". // -// print("Text {placeholder} another text \n", .{variable}); +// The formatting that Zig *does* perform itself is found in the +// curly brackets: "{placeholder}". Formatting instructions in +// the placeholder will determine how the corresponding value, +// e.g. foo, is displayed. // -// But how is the statement just shown formatted? +// And this is where it gets exciting, because format() accepts a +// variety of formatting instructions. It's basically a tiny +// language of its own. Here's a numeric example: // -// This actually happens in several stages. On the one hand, escape -// sequences are evaluated, there is the "\n" which means "line feed" -// in the example. Whenever this statement is found, a new line is started -// in the output. Escpape sequences can also be written one after the -// other, e.g. "\n\n" will cause two line feeds. +// print("Catch-{x:0>4}.", .{twenty_two}); +// +// This formatting instruction outputs a hexadecimal number with +// leading zeros: // -// By the way, these formattings are passed directly to the terminal -// program, i.e. escape sequences have nothing to do with Zig in this -// respect. The formatting that Zig actually performs is found in the -// curly bracket, the "placeholder", and affects the coresponding variable. +// Catch-0x0016. // -// And this is where it gets exciting, because numbers can have different -// sizes, be positive or negative, with a decimal point or without, -// and so on. +// Or you can center-align a string like so: // -// In order to bring these then into a uniform format for the output, -// instructions can be given to the placeholder: +// print("{s:*^20}\n", .{"Hello!"}); // -// print("=> {x:0>4}", .{var}); +// Output: // -// This instruction outputs a hexadecimal number with leading zeros. +// *******Hello!******* // -// => 0x0017 +// Let's try making use of some formatting. We've decided that +// the one thing missing from our lives is a multiplication table +// for all numbers from 1-15. We want the table to be nice and +// neat, with numbers in straight columns like so: // -// Let's move on to our exercise: we want to create a table that shows us -// the multiplication of all numbers together from 1-15. So if you search -// for the number '5' in the row and '4' in the column (or vice versa), -// the result of '5 x 4 = 20' should be displayed there. +// X | 1 2 3 4 5 ... +// ---+---+---+---+---+---+ +// 1 | 1 2 3 4 5 // +// 2 | 2 4 6 8 10 +// +// 3 | 3 6 9 12 15 +// +// 4 | 4 8 12 16 20 +// +// 5 | 5 10 15 20 25 +// +// ... +// +// Without string formatting, this would be a more challenging +// assignment because the number of digits in the numbers vary +// from 1 to 3. But formatting can help us with that. // const std = @import("std"); const print = std.debug.print; pub fn main() !void { - // the max. size of the table + // Max number to multiply const size = 15; - // print the header: + // Print the header: // - // we start with a single 'X' for the diagonal, - // that means there is no result + // We start with a single 'X' for the diagonal. print("\n X |", .{}); - // header row with all numbers from 1 to size + // Header row with all numbers from 1 to size. for (0..size) |n| { print("{d:>3} ", .{n + 1}); } print("\n", .{}); - // row line + // Header column rule line. var n: u8 = 0; while (n <= size) : (n += 1) { print("---+", .{}); } print("\n", .{}); - // now the actual table + // Now the actual table. (Is there anything more beautiful + // than a well-formatted table?) for (0..size) |a| { print("{d:>2} |", .{a + 1}); + for (0..size) |b| { - // what formatting is needed here? + // What formatting is needed here to make our columns + // nice and straight? print("{???} ", .{(a + 1) * (b + 1)}); } - // after each row we use double line feed + // After each row we use double line feed: print("\n\n", .{}); } } diff --git a/patches/patches/099_formatting.patch b/patches/patches/099_formatting.patch index bb25059..5b7efbe 100644 --- a/patches/patches/099_formatting.patch +++ b/patches/patches/099_formatting.patch @@ -1,5 +1,4 @@ -108,109c108 -< // what formatting is needed here? +134c134 < print("{???} ", .{(a + 1) * (b + 1)}); --- > print("{d:>3} ", .{(a + 1) * (b + 1)});