Compare commits
No commits in common. "b68855fc2de2898dc90af1e5e56235324ecbd5eb" and "67a8356a34badbfcbfbb56f61d015d5f4758c1d5" have entirely different histories.
b68855fc2d
...
67a8356a34
16 changed files with 26 additions and 79 deletions
16
README.md
16
README.md
|
|
@ -1,13 +1,5 @@
|
||||||
# Ziglings
|
# Ziglings
|
||||||
|
|
||||||
## ⚠️ Attention! Ziglings has moved to Codeberg!
|
|
||||||
|
|
||||||
Check out our handy new URL: https://ziglings.org
|
|
||||||
|
|
||||||
Or visit the repo directly at: https://codeberg.org/ziglings/exercises
|
|
||||||
|
|
||||||
***
|
|
||||||
|
|
||||||
Welcome to Ziglings! This project contains a series of tiny
|
Welcome to Ziglings! This project contains a series of tiny
|
||||||
broken programs (and one nasty surprise). By fixing them, you'll
|
broken programs (and one nasty surprise). By fixing them, you'll
|
||||||
learn how to read and write [Zig](https://ziglang.org/) code.
|
learn how to read and write [Zig](https://ziglang.org/) code.
|
||||||
|
|
@ -59,8 +51,8 @@ $ zig version
|
||||||
Clone this repository with Git:
|
Clone this repository with Git:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git clone https://ziglings.org
|
$ git clone https://github.com/ratfactor/ziglings
|
||||||
$ cd ziglings.org
|
$ cd ziglings
|
||||||
```
|
```
|
||||||
|
|
||||||
Then run `zig build` and follow the instructions to begin!
|
Then run `zig build` and follow the instructions to begin!
|
||||||
|
|
@ -122,10 +114,12 @@ Version-0.11.0-dev.4246+71dfce31b
|
||||||
|
|
||||||
## Advanced Usage
|
## Advanced Usage
|
||||||
|
|
||||||
It can be handy to check just a single exercise:
|
It can be handy to check just a single exercise or _start_ from a
|
||||||
|
single exercise:
|
||||||
|
|
||||||
```
|
```
|
||||||
zig build -Dn=19
|
zig build -Dn=19
|
||||||
|
zig build -Dn=19 start
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also run without checking for correctness:
|
You can also run without checking for correctness:
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@
|
||||||
// const a2: u8 = 0x41; // hexadecimal
|
// const a2: u8 = 0x41; // hexadecimal
|
||||||
// const a3: u8 = 0o101; // octal
|
// const a3: u8 = 0o101; // octal
|
||||||
// const a4: u8 = 0b1000001; // binary
|
// const a4: u8 = 0b1000001; // binary
|
||||||
// const a5: u8 = 'A'; // ASCII code point literal
|
// const a5: u8 = 'A'; // UTF-8 code point literal
|
||||||
// const a6: u16 = 'Ȁ'; // Unicode code points can take up to 21 bits
|
|
||||||
//
|
//
|
||||||
// You can also place underscores in numbers to aid readability:
|
// You can also place underscores in numbers to aid readability:
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,8 @@ pub fn main() void {
|
||||||
// types with specific sizes. The comptime numbers will be
|
// types with specific sizes. The comptime numbers will be
|
||||||
// coerced (if they'll fit!) into your chosen runtime types.
|
// coerced (if they'll fit!) into your chosen runtime types.
|
||||||
// For this it is necessary to specify a size, e.g. 32 bit.
|
// For this it is necessary to specify a size, e.g. 32 bit.
|
||||||
var var_int: u32 = 12345;
|
var var_int = 12345;
|
||||||
var var_float: f32 = 987.654;
|
var var_float = 987.654;
|
||||||
|
|
||||||
// We can change what is stored at the areas set aside for
|
// We can change what is stored at the areas set aside for
|
||||||
// "var_int" and "var_float" in the running compiled program.
|
// "var_int" and "var_float" in the running compiled program.
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ pub fn main() void {
|
||||||
// In this contrived example, we've decided to allocate some
|
// In this contrived example, we've decided to allocate some
|
||||||
// arrays using a variable count! But something's missing...
|
// arrays using a variable count! But something's missing...
|
||||||
//
|
//
|
||||||
comptime var count = 0;
|
var count = 0;
|
||||||
|
|
||||||
count += 1;
|
count += 1;
|
||||||
var a1: [count]u8 = .{'A'} ** count;
|
var a1: [count]u8 = .{'A'} ** count;
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,7 @@ const Schooner = struct {
|
||||||
//
|
//
|
||||||
// Please change this so that it sets a 0 scale to 1
|
// Please change this so that it sets a 0 scale to 1
|
||||||
// instead.
|
// instead.
|
||||||
// if (my_scale == 0) @compileError("Scale 1:0 is not valid!");
|
if (my_scale == 0) @compileError("Scale 1:0 is not valid!");
|
||||||
if (my_scale == 0) my_scale = 1;
|
|
||||||
|
|
||||||
self.scale = my_scale;
|
self.scale = my_scale;
|
||||||
self.hull_length /= my_scale;
|
self.hull_length /= my_scale;
|
||||||
|
|
@ -70,7 +69,7 @@ pub fn main() void {
|
||||||
// Hey, we can't just pass this runtime variable as an
|
// Hey, we can't just pass this runtime variable as an
|
||||||
// argument to the scaleMe() method. What would let us do
|
// argument to the scaleMe() method. What would let us do
|
||||||
// that?
|
// that?
|
||||||
comptime var scale: u32 = undefined;
|
var scale: u32 = undefined;
|
||||||
|
|
||||||
scale = 32; // 1:32 scale
|
scale = 32; // 1:32 scale
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ pub fn main() void {
|
||||||
// 2) Sets the size of the array of type T (which is the
|
// 2) Sets the size of the array of type T (which is the
|
||||||
// sequence we're creating and returning).
|
// sequence we're creating and returning).
|
||||||
//
|
//
|
||||||
fn makeSequence(comptime T: type, comptime size: usize) [size]T {
|
fn makeSequence(comptime T: type, ??? size: usize) [???]T {
|
||||||
var sequence: [size]T = undefined;
|
var sequence: [???]T = undefined;
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
|
|
||||||
while (i < size) : (i += 1) {
|
while (i < size) : (i += 1) {
|
||||||
|
|
|
||||||
|
|
@ -123,8 +123,8 @@ fn isADuck(possible_duck: anytype) bool {
|
||||||
// Please make sure MyType has both waddle() and quack()
|
// Please make sure MyType has both waddle() and quack()
|
||||||
// methods:
|
// methods:
|
||||||
const MyType = @TypeOf(possible_duck);
|
const MyType = @TypeOf(possible_duck);
|
||||||
const walks_like_duck = @hasDecl(MyType, "waddle");
|
const walks_like_duck = ???;
|
||||||
const quacks_like_duck = @hasDecl(MyType, "quack");
|
const quacks_like_duck = ???;
|
||||||
|
|
||||||
const is_duck = walks_like_duck and quacks_like_duck;
|
const is_duck = walks_like_duck and quacks_like_duck;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ pub fn main() void {
|
||||||
|
|
||||||
const fields = @typeInfo(Narcissus).Struct.fields;
|
const fields = @typeInfo(Narcissus).Struct.fields;
|
||||||
|
|
||||||
inline for (fields) |field| {
|
??? {
|
||||||
if (field.type != void) {
|
if (field.type != void) {
|
||||||
print(" {s}", .{field.name});
|
print(" {s}", .{field.name});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ pub fn main() void {
|
||||||
// at compile time.
|
// at compile time.
|
||||||
//
|
//
|
||||||
// Please fix this to loop once per "instruction":
|
// Please fix this to loop once per "instruction":
|
||||||
inline while (i < instructions.len) : (i += 3) {
|
??? (i < instructions.len) : (???) {
|
||||||
|
|
||||||
// This gets the digit from the "instruction". Can you
|
// This gets the digit from the "instruction". Can you
|
||||||
// figure out why we subtract '0' from it?
|
// figure out why we subtract '0' from it?
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,12 @@ const llamas = [llama_count]u32{ 5, 10, 15, 20, 25 };
|
||||||
pub fn main() void {
|
pub fn main() void {
|
||||||
// We meant to fetch the last llama. Please fix this simple
|
// We meant to fetch the last llama. Please fix this simple
|
||||||
// mistake so the assertion no longer fails.
|
// mistake so the assertion no longer fails.
|
||||||
const my_llama = getLlama(4);
|
const my_llama = getLlama(5);
|
||||||
|
|
||||||
print("My llama value is {}.\n", .{my_llama});
|
print("My llama value is {}.\n", .{my_llama});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getLlama(comptime i: usize) u32 {
|
fn getLlama(i: usize) u32 {
|
||||||
// We've put a guard assert() at the top of this function to
|
// We've put a guard assert() at the top of this function to
|
||||||
// prevent mistakes. The 'comptime' keyword here means that
|
// prevent mistakes. The 'comptime' keyword here means that
|
||||||
// the mistake will be caught when we compile!
|
// the mistake will be caught when we compile!
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ const llamas = makeLlamas(llama_count);
|
||||||
|
|
||||||
// And here's the function. Note that the return value type
|
// And here's the function. Note that the return value type
|
||||||
// depends on one of the input arguments!
|
// depends on one of the input arguments!
|
||||||
fn makeLlamas(comptime count: usize) [count]u8 {
|
fn makeLlamas(count: usize) [count]u8 {
|
||||||
var temp: [count]u8 = undefined;
|
var temp: [count]u8 = undefined;
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@
|
||||||
// of it.
|
// of it.
|
||||||
//
|
//
|
||||||
const print = @import("std").debug.print;
|
const print = @import("std").debug.print;
|
||||||
const mem = @import("std").mem;
|
|
||||||
const fmt = @import("std").fmt;
|
|
||||||
|
|
||||||
const TripError = error{ Unreachable, EatenByAGrue };
|
const TripError = error{ Unreachable, EatenByAGrue };
|
||||||
|
|
||||||
|
|
@ -51,47 +49,12 @@ const Path = struct {
|
||||||
//
|
//
|
||||||
// Please fill in the body of this function!
|
// Please fill in the body of this function!
|
||||||
fn makePath(from: *Place, to: *Place, dist: u8) Path {
|
fn makePath(from: *Place, to: *Place, dist: u8) Path {
|
||||||
return Path{
|
|
||||||
.from = from,
|
|
||||||
.to = to,
|
|
||||||
.dist = dist,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn makePath2(comptime path: []const u8) Path {
|
|
||||||
var it = mem.split(u8, path, "->");
|
|
||||||
var from: []const u8 = it.first();
|
|
||||||
it = mem.split(u8, it.next().?, ":");
|
|
||||||
var to: []const u8 = it.first();
|
|
||||||
var dist: []const u8 = it.next().?;
|
|
||||||
return Path{
|
|
||||||
.from = &@field(@This(), from),
|
|
||||||
.to = &@field(@This(), to),
|
|
||||||
.dist = try fmt.parseInt(u8, dist, 10),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn makePath3(comptime path: []const u8) Path {
|
|
||||||
var it = mem.split(u8, path, "->");
|
|
||||||
var from: []const u8 = it.first();
|
|
||||||
var list = it.next().?;
|
|
||||||
var connections_it = mem.split(u8, list[1..(path.len - from.len - 3)], " ");
|
|
||||||
|
|
||||||
while (connections_it.next()) |connect| {
|
|
||||||
var connection_it = mem.split(u8, connect, ":");
|
|
||||||
return Path{
|
|
||||||
.from = &@field(@This(), from),
|
|
||||||
.to = &@field(@This(), connection_it.first()),
|
|
||||||
.dist = try fmt.parseInt(u8, connection_it.next().?, 10),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using our new function, these path definitions take up considerably less
|
// Using our new function, these path definitions take up considerably less
|
||||||
// space in our program now!
|
// space in our program now!
|
||||||
// const a_paths = [_]Path{makePath(&a, &b, 2)};
|
const a_paths = [_]Path{makePath(&a, &b, 2)};
|
||||||
const a_paths = [_]Path{makePath2("a->b:2")};
|
|
||||||
// const a_paths = makePath3("a->(b:2)");
|
|
||||||
const b_paths = [_]Path{ makePath(&b, &a, 2), makePath(&b, &d, 1) };
|
const b_paths = [_]Path{ makePath(&b, &a, 2), makePath(&b, &d, 1) };
|
||||||
const c_paths = [_]Path{ makePath(&c, &d, 3), makePath(&c, &e, 2) };
|
const c_paths = [_]Path{ makePath(&c, &d, 3), makePath(&c, &e, 2) };
|
||||||
const d_paths = [_]Path{ makePath(&d, &b, 1), makePath(&d, &c, 3), makePath(&d, &f, 7) };
|
const d_paths = [_]Path{ makePath(&d, &b, 1), makePath(&d, &c, 3), makePath(&d, &f, 7) };
|
||||||
|
|
@ -191,10 +154,6 @@ pub fn main() void {
|
||||||
const start = &a; // Archer's Point
|
const start = &a; // Archer's Point
|
||||||
const destination = &f; // Fox Pond
|
const destination = &f; // Fox Pond
|
||||||
|
|
||||||
// makePath3("a->(b:2 d:3)");
|
|
||||||
var temp: Path = makePath3("a->(b:2)");
|
|
||||||
_ = temp;
|
|
||||||
|
|
||||||
// We could either have this:
|
// We could either have this:
|
||||||
//
|
//
|
||||||
// a.paths = a_paths[0..];
|
// a.paths = a_paths[0..];
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ pub fn main() void {
|
||||||
// use a marble scoop, spoon magnet, and feather tongs to grab
|
// use a marble scoop, spoon magnet, and feather tongs to grab
|
||||||
// each type of object.
|
// each type of object.
|
||||||
//
|
//
|
||||||
// Now, would you rather use the magic bag:
|
// Now, would you rather the magic bag:
|
||||||
//
|
//
|
||||||
// A. Grouped the items in clusters so you have to pick up one
|
// A. Grouped the items in clusters so you have to pick up one
|
||||||
// marble, then one spoon, then one feather?
|
// marble, then one spoon, then one feather?
|
||||||
|
|
@ -95,7 +95,7 @@ pub fn main() void {
|
||||||
// marbles at once, then all the spoons, then all of the
|
// marbles at once, then all the spoons, then all of the
|
||||||
// feathers?
|
// feathers?
|
||||||
//
|
//
|
||||||
// If this metaphor is working, hopefully, it's clear that the 'B'
|
// If this metaphor is working, hopefully it's clear that the 'B'
|
||||||
// option would be much more efficient.
|
// option would be much more efficient.
|
||||||
//
|
//
|
||||||
// Well, it probably comes as little surprise that storing and
|
// Well, it probably comes as little surprise that storing and
|
||||||
|
|
@ -120,7 +120,3 @@ pub fn main() void {
|
||||||
// three arrays of one data type each, like those in the exercise
|
// three arrays of one data type each, like those in the exercise
|
||||||
// above (SoA).
|
// above (SoA).
|
||||||
//
|
//
|
||||||
// For a more practical application of "data-oriented design"
|
|
||||||
// watch the following talk from Andrew Kelley, the creator of Zig:
|
|
||||||
// https://vimeo.com/649009599
|
|
||||||
//
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
91c91
|
92c92
|
||||||
< ???.zap(???);
|
< ???.zap(???);
|
||||||
---
|
---
|
||||||
> heat_ray.zap(alien);
|
> heat_ray.zap(alien);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
23,25c23,25
|
22,24c22,24
|
||||||
< 0o131, // octal
|
< 0o131, // octal
|
||||||
< 0b1101000, // binary
|
< 0b1101000, // binary
|
||||||
< 0x66, // hex
|
< 0x66, // hex
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
46c46
|
43c43
|
||||||
< const shuttle_weight: f16 = 907.18 * 2200;
|
< const shuttle_weight: f16 = 907.18 * 2200;
|
||||||
---
|
---
|
||||||
> const shuttle_weight: f32 = 907.18 * 2200.0;
|
> const shuttle_weight: f32 = 907.18 * 2200.0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue