Compare commits

..

117 commits

Author SHA1 Message Date
Norman Köhring
e8270de928 some exercises 2024-05-27 15:21:28 +02:00
Chris Boesch
776316e60b Merge pull request 'Update exercises/105_threading2.zig' (#95) from rpm0372/exercises:TypoIn105 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/95
2024-05-12 11:50:56 +00:00
rpm0372
efe2d19c69 Update exercises/105_threading2.zig
The last word, '"diggits" was misspelled.
2024-05-11 22:38:15 +00:00
Chris Boesch
49c54fb075 Merge pull request 'Nobody wants the long version of finding out if a variable is set.' (#94) from minor_improvements into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/94
2024-05-10 21:40:54 +00:00
Chris Boesch
67f87a76c2
Nobody wants the long version of finding out if a variable is set.
So switched to the short version with 'orelse'. ;)
2024-05-10 23:21:04 +02:00
Chris Boesch
dfdaf03d99 Merge pull request 'Add devcontainer config' (#90) from aquilarafa/exercises:add-devcontainer into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/90
2024-05-06 15:17:52 +00:00
Rafael Áquila
5da194ba9c Add devcontainer.json 2024-05-06 07:47:27 -03:00
Chris Boesch
8345e839b0 Merge pull request 'Fix some typos' (#89) from typos into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/89
2024-05-06 07:25:18 +00:00
Chris Boesch
6c23f2682e Merge branch 'main' into typos 2024-05-06 07:20:37 +00:00
Chris Boesch
19bd8745e4
Fix some typos 2024-05-06 09:13:56 +02:00
Chris Boesch
1ac46d7a42 Merge pull request 'Fix patches for 106 and 107' (#88) from wp433 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/88
2024-05-04 23:27:01 +00:00
Chris Boesch
165cc199ca
Fix patches for 106 and 107 2024-05-05 01:16:23 +02:00
Chris Boesch
e182d1f19d Merge pull request 'fix: typos in exercises 094 and 098' (#87) from d-hain/ziglings-exercises:typo-fix-094-098 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/87
2024-05-04 22:46:16 +00:00
Chris Boesch
09e2f37a50 Merge branch 'main' into typo-fix-094-098 2024-05-04 22:45:32 +00:00
Chris Boesch
27db3112f9 Merge pull request 'fix: typo: % instead of @ for a builtin function' (#85) from d-hain/ziglings-exercises:094_c_math-typo-fix into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/85
2024-05-04 22:34:11 +00:00
David Hain
8cb2a5aa3c fix: some grammatical errors 2024-05-04 22:53:04 +02:00
David Hain
c936c5e123 fix: many grammatical errors 2024-05-04 22:35:07 +02:00
David Hain
5c2354a1bf fix: typo: removed extra s 2024-05-04 21:12:54 +02:00
David Hain
4dbd056100 fix: typo: % instead of @ for a builtin function 2024-05-04 18:51:00 +02:00
Chris Boesch
9ce4a7d6f0 Merge pull request 'Update .woodpecker/eowyn.yaml' (#83) from wp-patch-2 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/83
2024-04-24 14:58:05 +00:00
Chris Boesch
b484be9ac1 Update .woodpecker/eowyn.yaml
Add pull command
2024-04-24 14:40:01 +00:00
Chris Boesch
a2a0a6e891 Merge pull request 'Update .woodpecker/eowyn.yaml' (#82) from chrboesch-wp-patch-1 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/82
2024-04-24 14:31:07 +00:00
Chris Boesch
e7eaa080b6 Update .woodpecker/eowyn.yaml
Add tag "latest"
2024-04-24 14:20:57 +00:00
Chris Boesch
ce0a6cc91c Merge pull request 'Switch to new zig dev release 0.13' (#81) from r013 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/81
2024-04-20 20:37:30 +00:00
Chris Boesch
c94eb33e44
Switch to new zig dev release 0.13 2024-04-20 22:35:14 +02:00
Chris Boesch
8f36619bd7 Merge pull request 'fixing little typo on exercise 107_files2.zig' (#80) from susubub/exercises:little-typo_107 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/80
2024-04-18 17:55:02 +00:00
susubub
aa74dde367 fixing little typo on exercise 107_files2.zig 2024-04-17 20:04:43 -03:00
Chris Boesch
9432c2b0fd Merge pull request 'Fixed woodpecker warnings' (#79) from pr78 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/79
2024-04-10 21:02:13 +00:00
Chris Boesch
f4f8eb7ff1
Fixed woodpecker warnings 2024-04-10 22:56:33 +02:00
Chris Boesch
72e3d6ebdc Update .woodpecker/eowyn.yml 2024-04-10 18:38:59 +00:00
Chris Boesch
3c9c55df8e Merge pull request 'Additional timer in thread start added' (#77) from I75 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/77
2024-04-10 17:21:18 +00:00
Chris Boesch
376a839672 Merge branch 'main' into I75 2024-04-10 17:16:14 +00:00
Chris Boesch
ba2a9622c4
Additional timer in thread start added 2024-04-10 19:13:46 +02:00
Chris Boesch
2122c477a0 Merge pull request 'Greater gradation of timers built into the threads' (#76) from I75 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/76
2024-04-10 14:18:01 +00:00
Chris Boesch
7732cd7716
Greater gradation of timers built into the threads 2024-04-10 16:06:23 +02:00
Chris Boesch
564916db81 Update README.md 2024-04-03 07:51:19 +00:00
Chris Boesch
84864d808f Merge pull request 'Zig version changed' (#73) from pr72 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/73
2024-04-03 07:47:46 +00:00
Chris Boesch
7875a0f9aa
Zig version changed 2024-04-03 00:37:33 +02:00
Chris Boesch
c0ff1b70c1 Merge pull request 'WIP - fix breaking zig change to @fieldParentPtr' (#72) from kamidev/exercises:fix_zig_breaking_pr_19470 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/72
2024-04-02 22:19:17 +00:00
kamidev
f06c1f27d1
Fix breaking zig change to @fieldParentPtr parameters
See https://github.com/ziglang/zig/pull/19470
2024-03-31 17:02:29 +02:00
Chris Boesch
ba4709b20f Merge pull request 'fix typo' (#70) from i69 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/70
2024-03-28 20:53:46 +00:00
Chris Boesch
e06cdc0b70 Merge branch 'main' into i69 2024-03-28 20:42:35 +00:00
Chris Boesch
86ac326885
fix typo 2024-03-28 21:33:16 +01:00
Chris Boesch
20919722ff Merge pull request 'added exercise/106_files.zig' (#66) from dizzyi_solo/exercises:main into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/66
2024-03-27 18:54:51 +00:00
Chris Boesch
db21ab9855 Merge branch 'main' into main 2024-03-27 18:50:52 +00:00
Alan CHUNG
05589f8ba1 added format parameter {d} 2024-03-27 16:53:19 +08:00
Alan CHUNG
223fc79e44 106 & 107 2024-03-27 16:40:24 +08:00
Alan CHUNG
69bc9a0723 Pass CI test locally 2024-03-26 14:33:25 +08:00
Alan CHUNG
5f74c7f911 specify directory on patch file 106 2024-03-26 14:05:16 +08:00
Alan CHUNG
2c44f3e4ff specify directory on patch file 106 2024-03-26 14:03:54 +08:00
Alan CHUNG
92ea6718b2 remove header of patch files of 106 2024-03-26 14:01:12 +08:00
Alan CHUNG
9bf7a84e56 106_files.patches actual 2024-03-26 13:53:29 +08:00
Alan CHUNG
9ce889b438 106_files.zig actual test 2024-03-26 13:51:59 +08:00
Alan CHUNG
74a6e60e17 add patch files for 106_files.zig 2024-03-25 16:39:45 +08:00
Alan CHUNG
23b11a7509 106_files.zig format 2024-03-25 16:36:15 +08:00
Alan CHUNG
66d08f1e1f modified build.zig 2024-03-25 16:24:42 +08:00
Dizzyi
ec6f6c5870 added exercise/106_files.zig 2024-03-25 01:11:33 +08:00
Chris Boesch
a3de4e3d0f Update .woodpecker/eowyn.yml 2024-03-24 15:57:39 +00:00
Chris Boesch
0d1c76a410 Update .woodpecker/eowyn.yml 2024-03-24 15:55:43 +00:00
Chris Boesch
8e6612a59d Update .woodpecker/eowyn.yml
fix warning
2024-03-24 15:45:53 +00:00
Chris Boesch
95cfeaa606 Update exercises/105_threading2.zig
Fixed typo.
2024-03-23 15:57:33 +00:00
Chris Boesch
dabd9a5a0a Merge pull request 'Added second threading exercise.' (#65) from threading2 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/65
2024-03-23 15:48:08 +00:00
Chris Boesch
d65e3f3f9a
Added second threading exercise. 2024-03-23 16:42:27 +01:00
Chris Boesch
cdaa246131 Merge pull request 'Fixed the renaming of std.os to std.posix' (#64) from fix_63 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/64
2024-03-21 23:28:30 +00:00
Chris Boesch
2b9e3da5c8
Fixed the renaming of std.os to std.posix 2024-03-22 00:25:01 +01:00
Chris Boesch
2092f35127 Merge pull request 'Changes for a new Zig version.' (#60) from version_change into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/60
2024-03-14 23:11:06 +00:00
Chris Boesch
abed92c05e Changes for a new Zig version. 2024-03-15 00:00:17 +01:00
Chris Boesch
5728ccc8eb Merge pull request 'fix exercise 82 output' (#58) from dolichomps/exercises:main into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/58
2024-03-14 22:41:29 +00:00
Chris Boesch
a87e7c895e Merge pull request 'Improved the explanation about passing arguments and added an example.' (#59) from issue51 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/59
2024-03-14 22:40:30 +00:00
Chris Boesch
9844123dd1 Improved the explanation about passing arguments and added an example. 2024-03-14 23:37:14 +01:00
dolichomps
c8f081f3e8 fix exercise 82 output
zig commit bd24e66 changed the floating point formatting implementation so output for exercise 82 no longer matched
2024-03-14 02:28:07 +00:00
Chris Boesch
e3877321b6 Merge pull request 'Minor corrections to the "contributing"' (#56) from contrib into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/56
2024-03-12 20:03:17 +00:00
Chris Boesch
08cc60ba59 Minor corrections to the "contributing" 2024-03-12 20:59:29 +01:00
Chris Boesch
6b46b26c22 Merge pull request 'Fixed unicode literal' (#55) from i52 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/55
2024-03-08 00:09:54 +00:00
Chris Boesch
d0519d18fa Fixed unicode literal 2024-03-08 01:07:57 +01:00
Chris Boesch
9e9cf40453 Merge pull request 'Added threading exercise' (#54) from 104_threading into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/54
2024-03-05 08:22:40 +00:00
Chris Boesch
6984345d0a Added threading exercise 2024-03-05 09:15:57 +01:00
Chris Boesch
277304454a Merge pull request 'Added notes to exercise 94 c_math.' (#53) from 094_c-math into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/53
2024-02-28 12:06:56 +00:00
Chris Boesch
9e48c9a339 Added notes to exercise 94 c_math. 2024-02-28 13:01:11 +01:00
Chris Boesch
48b2032024 Merge pull request 'Zig version adjusted.' (#50) from build_fix into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/50
2024-02-16 15:04:27 +00:00
Chris Boesch
55b2ac4c5f Zig version adjusted. 2024-02-16 15:19:10 +01:00
Chris Boesch
099d0bba93 Merge pull request 'Text improvement' (#48) from chrboesch-patch-1 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/48
2024-02-11 14:12:07 +00:00
Chris Boesch
8257ccb5c8 Text improvement
closes #47
2024-02-11 14:07:37 +00:00
Chris Boesch
4b1ae6117c Merge pull request 'Fix zig_exe location in Build struct' (#45) from asd/ziglings:main into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/45
2024-02-06 18:36:50 +00:00
Alexander Saltanov
755911747f Fix zig_exe location in Build struct
Reflect Zig breaking changes as of 105db13536
2024-02-06 00:06:19 +03:00
Chris Boesch
fa22e861d5 Merge pull request 'added space, missing after end-of-sentence dot.' (#40) from anthon/exercises:missing-space-1 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/40
2024-01-13 15:14:07 +00:00
Chris Boesch
7bfd7adce8 Update exercises/093_hello_c.zig
small typo
2024-01-13 14:27:58 +00:00
Anthon
58dff3f504 added space, missing after end-of-sentence dot. 2024-01-10 06:16:44 +00:00
Chris Boesch
0d46acfa02 Merge pull request 'Zig 0.12.0-dev.2043 compatability changes for test runner' (#35) from drglove/exercises:zig-2043-changes into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/35
2024-01-05 13:52:09 +00:00
drglove
15de3785a3 Bump ziglang version in Version Changes header 2024-01-05 08:43:31 +00:00
drglove
7d23ddc1f6 Update version changes with 2043. 2024-01-05 08:27:52 +00:00
drglove
ba9447d2c6 Bump version to match required changes. 2024-01-05 08:24:29 +00:00
drglove
7a0cbb131f Use std.Build.LazyPath over now removed std.Build.FileSource.
See corresponding ziglang change here: https://github.com/ziglang/zig/issues/16353
2024-01-05 08:17:09 +00:00
drglove
528a8645f8 Fix casing of std.build -> std.Build in tests. 2024-01-05 08:15:51 +00:00
Chris Boesch
b7dfa4cd1d Merge pull request 'Correct comment to match code in 076_sentinels' (#33) from mttrb/ziglings:076-comment into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/33
2024-01-04 20:47:06 +00:00
Matthew Robinson
1ed03cf0a1 Fix formatting of comment 2024-01-01 02:16:39 +08:00
Matthew Robinson
1a001b9eb7 Correct comment to match code in 076_sentinels 2024-01-01 01:41:31 +08:00
Chris Boesch
e7c106ba3a Merge pull request 'Fix minor typo' (#32) from babaiserror/exercises:typo into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/32
2023-12-30 16:34:16 +00:00
babaiserror
2fb7da53e7 Fix minor typo 2023-12-29 22:59:39 -05:00
Chris Boesch
72e15c9ef3 Merge pull request 'Removed ci/compat.sh as it is included in build.zig again' (#30) from ci into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/30
2023-11-21 23:01:10 +00:00
Chris Boesch
492e5f5c40 Removed ci/compat.sh as it is included in build.zig again 2023-11-21 23:51:28 +01:00
Chris Boesch
5eafe16e97 Merge pull request 'Fix two minor typos' (#29) from A-h-m-e-d/exercises:typos into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/29

Thanks!
2023-11-21 20:49:55 +00:00
Ahmed
46e3a38dbc Fix two minor typos 2023-11-21 19:09:47 +02:00
Chris Boesch
f987a06ccc Merge pull request 'Converted var to const if there is no mutation in the var.' (#28) from var_const into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/28
2023-11-21 14:26:23 +00:00
Chris Boesch
b0511bb3c7 Fixed patch hunk 2023-11-21 15:22:36 +01:00
Chris Boesch
7679f93f68 Converted var to const if there is no mutation in var.
This is checked from compiler version 0.12.0-dev.1664
2023-11-21 15:01:22 +01:00
Chris Boesch
b7015c2d9d Merge pull request 'fixed variable declaration by changing it to a const, since it's never mutated' (#27) from zev/exercises:main into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/27
2023-11-21 13:20:51 +00:00
Zev Averbach
063a74c59a fixed variable declaration by changing it to a const, since it's never mutated 2023-11-21 12:00:34 +01:00
Chris Boesch
f29c0692d5 Added link to 'Zig in Depth' 2023-11-19 14:51:24 +00:00
Chris Boesch
afe5511455 Merge pull request 'Changed three dots to colons, see #23' (#25) from pr23 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/25
2023-11-07 14:23:12 +00:00
Chris Boesch
cab5ee87bf Changed three dots to colons, see #23 2023-11-07 15:18:00 +01:00
Chris Boesch
5a259a943f Merge pull request 'Change the task so that the exercise contains two errors again.' (#24) from i22 into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/24
2023-11-06 18:55:54 +00:00
Chris Boesch
55b58fea56 Change the task so that the exercise contains two errors again. 2023-11-06 19:50:47 +01:00
Chris Boesch
08d294f2b8 Merge pull request 'fixed build: renamed child.exec to run' (#19) from fix_build into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/19
2023-10-24 10:42:25 +00:00
Chris Boesch
6446542867 Update .woodpecker/eowyn.yml
force pulling
2023-10-24 10:23:10 +00:00
Chris Boesch
8a1fbea5c9 fixed build: renamed exec to run 2023-10-24 11:57:44 +02:00
Chris Boesch
633af411e6 Update README.md
insert tag hint
2023-10-24 08:43:07 +00:00
88 changed files with 785 additions and 260 deletions

View file

@ -0,0 +1,31 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/debian
{
"name": "Ziglings",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/base:bullseye",
"features": {
"ghcr.io/devcontainers-contrib/features/zig:1": {
"version": "master"
}
},
"customizations": {
"vscode": {
"extensions": [
"ziglang.vscode-zig"
]
}
}
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

1
.gitignore vendored
View file

@ -2,3 +2,4 @@
/zig-out/
/answers/
/patches/healed/
/output/

9
.woodpecker/eowyn.yaml Normal file
View file

@ -0,0 +1,9 @@
steps:
- name: eowyn
image: ziglings/ziglang:latest
pull: true
commands:
- sh ./patches/eowyn.sh
when:
event: [push, cron]
cron: daily*

View file

@ -1,11 +0,0 @@
steps:
eowyn:
image: ziglings/ziglang
commands:
- sh ./patches/eowyn.sh
when:
events:
- push
- pull-requests
- cron
cron: "Daily"

View file

@ -54,13 +54,12 @@ Ziglings. Please file an issue...or make a pull request!
## Formatting
All exercises should conform to `zig fmt`. I often forget to do
this.
All exercises should conform to `zig fmt`.
## Pull Request Workflow
Ziglings uses the "standard" Github workflow as guided by the Web
Ziglings uses the "standard" Codeberg workflow as guided by the Web
interface. Specifically:
* Fork this repository
@ -71,7 +70,7 @@ interface. Specifically:
`git push origin my-branch`
* Create a pull request from your branch to `ziglings/main`
* Your faithful Ziglings maintainers will take a look at your
request ASAP (we don't talk about May-July 2022, LOL)
request ASAP (we don't talk about May-July, LOL)
* Once the changes are reviewed, your request will be merged and
eternal Ziglings contributor glory is yours!

View file

@ -1,12 +1,4 @@
# Ziglings
# ⚠️ Ziglings has moved from GitHub to Codeberg!
You are looking at the current Ziglings repo if you are viewing
this at https://codeberg.org/ziglings/exercises/
You can also use the handy URL https://ziglings.org to get here!
***
Welcome to Ziglings! This project contains a series of tiny
broken programs (and one nasty surprise). By fixing them, you'll
@ -39,6 +31,7 @@ for more detail:
* https://ziglang.org/learn/
* https://ziglearn.org/
* https://ziglang.org/documentation/master/
* [Zig in Depth! (video series)](https://www.youtube.com/watch?v=MMtvGA1YhW4&list=PLtB7CL7EG7pCw7Xy1SQC53Gl8pI7aDg9t&pp=iAQB)
Also, the [Zig community](https://github.com/ziglang/zig/wiki/Community)
is incredibly friendly and helpful!
@ -53,7 +46,7 @@ Verify the installation and build number of `zig` like so:
```
$ zig version
0.12.0-dev.xxxx+xxxxxxxxx
0.13.0-dev.xxxx+xxxxxxxxx
```
Clone this repository with Git:
@ -75,11 +68,14 @@ reading these.
## A Note About Versions
**Hint:** To check out Ziglings for a stable release of Zig, you can use
the appropriate tag.
The Zig language is under very active development. In order to be
current, Ziglings tracks **development** builds of the Zig
compiler rather than versioned **release** builds. The last
stable release was `0.11.0`, but Ziglings needs a dev build with
pre-release version "0.12.0" and a build number at least as high
stable release was `0.12.0`, but Ziglings needs a dev build with
pre-release version "0.13.0" and a build number at least as high
as that shown in the example version check above.
It is likely that you'll download a build which is _greater_ than
@ -92,7 +88,13 @@ that if you update one, you may need to also update the other.
### Version Changes
Version-0.11.0-dev.4246+71dfce31b
Version-0.12.0-dev.3518
* *2024-03-21* zig 0.12.0-dev.3518 - change to @fieldParentPtr - see [#19470](https://github.com/ziglang/zig/pull/19470)
* *2024-03-21* zig 0.12.0-dev.3397 - rename std.os to std.posix - see [#5019](https://github.com/ziglang/zig/issues/5019)
* *2024-03-14* zig 0.12.0-dev.3302 - changes in `std.fmt` - floating-point formatting implementation - see [#19229](https://github.com/ziglang/zig/pull/19229)
* *2024-02-05* zig 0.12.0-dev.2618 - changes in `build system` - from `Step.zig_exe` to `Step.graph.zig_exe` - see [#18778](https://github.com/ziglang/zig/issues/18778)
* *2024-01-05* zig 0.12.0-dev.2043 - rename of `std.Build.FileSource` to `std.Build.LazyPath` - see [#16353](https://github.com/ziglang/zig/issues/16353)
* *2023-10-24* zig 0.12.0-dev.1243 - changes in `std.ChildProcess`: renamed exec to run - see [#5853](https://github.com/ziglang/zig/issues/5853)
* *2023-06-26* zig 0.11.0-dev.4246 - changes in compile step (now it can be null)
* *2023-06-26* zig 0.11.0-dev.3853 - removal of destination type from all cast builtins
* *2023-06-20* zig 0.11.0-dev.3747 - `@enumToInt` is now `@intFromEnum` and `@intToFloat` is now `@floatFromInt`
@ -209,13 +211,14 @@ Zig Core Language
* [X] Interfaces
* [X] Bit manipulation
* [X] Working with C
* [ ] Interfaces part 2
* [X] Threading
Zig Standard Library
* [X] String formatting
* [X] Testing
* [X] Tokenization
* [X] File handling
## Contributing

View file

@ -15,7 +15,7 @@ const print = std.debug.print;
// 1) Getting Started
// 2) Version Changes
comptime {
const required_zig = "0.11.0-dev.4246";
const required_zig = "0.12.0-dev.3518";
const current_zig = builtin.zig_version;
const min_zig = std.SemanticVersion.parse(required_zig) catch unreachable;
if (current_zig.order(min_zig) == .lt) {
@ -119,7 +119,7 @@ pub const logo =
;
pub fn build(b: *Build) !void {
if (!validate_exercises()) std.os.exit(2);
if (!validate_exercises()) std.process.exit(2);
use_color_escapes = false;
if (std.io.getStdErr().supportsAnsiEscapeCodes()) {
@ -172,7 +172,7 @@ pub fn build(b: *Build) !void {
// Named build mode: verifies a single exercise.
if (n == 0 or n > exercises.len - 1) {
print("unknown exercise number: {}\n", .{n});
std.os.exit(2);
std.process.exit(2);
}
const ex = exercises[n - 1];
@ -247,7 +247,7 @@ const ZiglingStep = struct {
fn make(step: *Step, prog_node: *std.Progress.Node) !void {
// NOTE: Using exit code 2 will prevent the Zig compiler to print the message:
// "error: the following build command failed with exit code 1:..."
const self = @fieldParentPtr(ZiglingStep, "step", step);
const self: *ZiglingStep = @alignCast(@fieldParentPtr("step", step));
if (self.exercise.skip) {
print("Skipping {s}\n\n", .{self.exercise.main_file});
@ -262,7 +262,7 @@ const ZiglingStep = struct {
print("\n{s}Ziglings hint: {s}{s}", .{ bold_text, hint, reset_text });
self.help();
std.os.exit(2);
std.process.exit(2);
};
self.run(exe_path.?, prog_node) catch {
@ -272,7 +272,7 @@ const ZiglingStep = struct {
print("\n{s}Ziglings hint: {s}{s}", .{ bold_text, hint, reset_text });
self.help();
std.os.exit(2);
std.process.exit(2);
};
// Print possible warning/debug messages.
@ -281,14 +281,14 @@ const ZiglingStep = struct {
fn run(self: *ZiglingStep, exe_path: []const u8, _: *std.Progress.Node) !void {
resetLine();
print("Checking {s}...\n", .{self.exercise.main_file});
print("Checking: {s}\n", .{self.exercise.main_file});
const b = self.step.owner;
// Allow up to 1 MB of stdout capture.
const max_output_bytes = 1 * 1024 * 1024;
var result = Child.exec(.{
const result = Child.run(.{
.allocator = b.allocator,
.argv = &.{exe_path},
.cwd = b.build_root.path.?,
@ -306,7 +306,7 @@ const ZiglingStep = struct {
}
}
fn check_output(self: *ZiglingStep, result: Child.ExecResult) !void {
fn check_output(self: *ZiglingStep, result: Child.RunResult) !void {
const b = self.step.owner;
// Make sure it exited cleanly.
@ -355,7 +355,7 @@ const ZiglingStep = struct {
print("{s}PASSED:\n{s}{s}\n\n", .{ green_text, output, reset_text });
}
fn check_test(self: *ZiglingStep, result: Child.ExecResult) !void {
fn check_test(self: *ZiglingStep, result: Child.RunResult) !void {
switch (result.term) {
.Exited => |code| {
if (code != 0) {
@ -376,7 +376,7 @@ const ZiglingStep = struct {
}
fn compile(self: *ZiglingStep, prog_node: *std.Progress.Node) !?[]const u8 {
print("Compiling {s}...\n", .{self.exercise.main_file});
print("Compiling: {s}\n", .{self.exercise.main_file});
const b = self.step.owner;
const exercise_path = self.exercise.main_file;
@ -386,7 +386,7 @@ const ZiglingStep = struct {
var zig_args = std.ArrayList([]const u8).init(b.allocator);
defer zig_args.deinit();
zig_args.append(b.zig_exe) catch @panic("OOM");
zig_args.append(b.graph.zig_exe) catch @panic("OOM");
const cmd = switch (self.exercise.kind) {
.exe => "build-exe",
@ -495,8 +495,7 @@ const PrintStep = struct {
}
fn make(step: *Step, _: *std.Progress.Node) !void {
const self = @fieldParentPtr(PrintStep, "step", step);
const self: *PrintStep = @alignCast(@fieldParentPtr("step", step));
print("{s}", .{self.message});
}
};
@ -839,7 +838,7 @@ const exercises = [_]Exercise{
},
.{
.main_file = "060_floats.zig",
.output = "Shuttle liftoff weight: 1995796kg",
.output = "Shuttle liftoff weight: 2032092kg",
},
.{
.main_file = "061_coercions.zig",
@ -939,7 +938,7 @@ const exercises = [_]Exercise{
.{
.main_file = "082_anonymous_structs3.zig",
.output =
\\"0"(bool):true "1"(bool):false "2"(i32):42 "3"(f32):3.14159202e+00
\\"0"(bool):true "1"(bool):false "2"(i32):42 "3"(f32):3.141592e0
,
.hint = "This one is a challenge! But you have everything you need.",
},
@ -1103,6 +1102,35 @@ const exercises = [_]Exercise{
\\This little poem has 15 words!
,
},
.{
.main_file = "104_threading.zig",
.output =
\\Starting work...
\\thread 1: started.
\\thread 2: started.
\\thread 3: started.
\\Some weird stuff, after starting the threads.
\\thread 2: finished.
\\thread 1: finished.
\\thread 3: finished.
\\Zig is cool!
,
},
.{
.main_file = "105_threading2.zig",
.output = "PI ≈ 3.14159265",
},
.{
.main_file = "106_files.zig",
.output = "Successfully wrote 18 bytes.",
},
.{
.main_file = "107_files2.zig",
.output =
\\AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
\\Successfully Read 18 bytes: It's zigling time!
,
},
.{
.main_file = "999_the_end.zig",
.output =

View file

@ -1,25 +0,0 @@
#!/bin/bash
# This script checks that `zig build` will return an useful error message when
# the Zig compiler is not compatible, instead of failing due to a syntax error.
#
# This script should be run on an UNIX system.
zig_version=$(zig version)
zig build -Dn=1 -Dhealed &> /dev/null 2>&1
zig_ret=$?
if [ "$zig_ret" -eq 0 ]; then
printf "zig %s unexpectedly succeeded\n" "$zig_version"
exit 1
fi
zig_error=$(zig build -Dn=1 -Dhealed 2>&1)
echo "$zig_error" | grep -q "it looks like your version of zig is too old"
zig_ret=$?
if [ "$zig_ret" -ne 0 ]; then
printf "zig %s is not compatible\n" "$zig_version"
exit 1
fi

View file

@ -16,6 +16,6 @@
//
const std = @import("std");
fn main() void {
pub fn main() void {
std.debug.print("Hello world!\n", .{});
}

View file

@ -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", .{});

View file

@ -34,12 +34,12 @@
const std = @import("std");
pub fn main() void {
const n: u8 = 50;
var n: u8 = 50;
n = n + 5;
const pi: u8 = 314159;
const pi: u32 = 314159;
const negative_eleven: u8 = -11;
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

View file

@ -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,

View file

@ -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.
//

View file

@ -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 });

View file

@ -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});

View file

@ -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});

View file

@ -24,7 +24,7 @@ pub fn main() void {
const foo = 1;
// Please fix this condition:
if (foo) {
if (foo == 1) {
// We want our program to print this message!
std.debug.print("Foo is 1!\n", .{});
} else {

View file

@ -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});
}

View file

@ -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});

View file

@ -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});
}

View file

@ -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});
}

View file

@ -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 > 3) break;
}
// Result: we want n=4

View file

@ -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(":-| ", .{});

View file

@ -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.

View file

@ -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(", ", .{});
}

View file

@ -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
}

View file

@ -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: u8) 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

View file

@ -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) u32 {
var n: u16 = 0;
var total: u16 = 1;
loop (n < number) : (n += 1) {
while (n < number) : (n += 1) {
total *= 2;
}
return ???;
return total;
}

View file

@ -9,7 +9,7 @@
// "TooSmall". Please add it where needed!
const MyNumberError = error{
TooBig,
???,
TooSmall,
TooFour,
};
@ -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) {

View file

@ -19,7 +19,7 @@ const std = @import("std");
const MyNumberError = error{TooSmall};
pub fn main() void {
var my_number: ??? = 5;
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?

View file

@ -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 {

View file

@ -59,7 +59,12 @@ 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 {

View file

@ -26,7 +26,7 @@ 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".
//
var x = detect(n);
const x = try detect(n);
return x + 5;
}

View file

@ -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.print("Hello world!\n", .{});
try stdout.print("Hello world!\n", .{});
}

View file

@ -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 ", .{});
}

View file

@ -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", .{});

View file

@ -21,8 +21,8 @@ const MyErr = error{ GetFail, IncFail };
pub fn main() void {
// We simply quit the entire program if we fail to get a number:
var a: u32 = makeNumber() catch return;
var b: u32 = makeNumber() catch return;
const a: u32 = makeNumber() catch return;
const b: u32 = makeNumber() catch return;
std.debug.print("Numbers: {}, {}\n", .{ a, b });
}
@ -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!

View file

@ -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("?", .{}),
}
}

View file

@ -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});

View file

@ -35,6 +35,7 @@ pub fn main() void {
3 => {
current_value *= current_value;
},
else => unreachable,
}
std.debug.print("{} ", .{current_value});

View file

@ -39,7 +39,7 @@ pub fn main() void {
std.debug.print("={}. ", .{value});
} 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. ", .{}),
}
}

View file

@ -6,14 +6,11 @@
// my_num=42
//
const std = @import("std");
const NumError = error{IllegalNumber};
pub fn main() void {
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const my_num: u32 = getNumber();
const my_num: u32 = try getNumber();
try stdout.print("my_num={}\n", .{my_num});
}

View file

@ -20,7 +20,7 @@
const std = @import("std");
// Please complete the enum!
const Ops = enum { ??? };
const Ops = enum { inc, dec, pow };
pub fn main() void {
const operations = [_]Ops{

View file

@ -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!
});
}

View file

@ -24,7 +24,7 @@ const std = @import("std");
pub fn main() void {
var num1: u8 = 5;
var num1_pointer: *u8 = &num1;
const num1_pointer: *u8 = &num1;
var num2: u8 = undefined;

View file

@ -51,8 +51,6 @@ fn visitElephants(first_elephant: *Elephant) void {
// We should stop once we encounter a tail that
// does NOT point to another element. What can
// we put here to make that happen?
if (e.tail == null) ???;
e = e.tail.?;
e = e.tail ???
}
}

View file

@ -24,7 +24,7 @@ const Elephant = struct {
pub fn print(self: *Elephant) void {
// Prints elephant letter and [v]isited
var v: u8 = if (self.visited) 'v' else ' ';
const v: u8 = if (self.visited) 'v' else ' ';
std.debug.print("{u}{u} ", .{ self.letter, v });
}
};

View file

@ -37,7 +37,7 @@ const Elephant = struct {
pub fn print(self: *Elephant) void {
// Prints elephant letter and [v]isited
var v: u8 = if (self.visited) 'v' else ' ';
const v: u8 = if (self.visited) 'v' else ' ';
std.debug.print("{u}{u} ", .{ self.letter, v });
}
};

View file

@ -141,9 +141,20 @@ pub fn main() void {
//
// Moving along...
//
// Passing arguments to functions is pretty much exactly like
// making an assignment to a const (since Zig enforces that ALL
// function parameters are const).
// When arguments are passed to a function,
// they are ALWAYS passed as constants within the function,
// regardless of how they were declared in the calling function.
//
// Example:
// fn foo(arg: u8) void {
// arg = 42; // Error, 'arg' is const!
// }
//
// fn bar() void {
// var arg: u8 = 12;
// foo(arg);
// ...
// }
//
// Knowing this, see if you can make levelUp() work as expected -
// it should add the specified amount to the supplied character's

View file

@ -53,8 +53,8 @@ const AntOrBee = enum { a, b };
pub fn main() void {
// We'll just make one bee and one ant to test them out:
var ant = Insect{ .still_alive = true };
var bee = Insect{ .flowers_visited = 15 };
const ant = Insect{ .still_alive = true };
const bee = Insect{ .flowers_visited = 15 };
std.debug.print("Insect report! ", .{});

View file

@ -38,8 +38,8 @@ const Insect = union(InsectStat) {
};
pub fn main() void {
var ant = Insect{ .still_alive = true };
var bee = Insect{ .flowers_visited = 16 };
const ant = Insect{ .still_alive = true };
const bee = Insect{ .flowers_visited = 16 };
std.debug.print("Insect report! ", .{});

View file

@ -21,8 +21,8 @@ const Insect = union(InsectStat) {
};
pub fn main() void {
var ant = Insect{ .still_alive = true };
var bee = Insect{ .flowers_visited = 17 };
const ant = Insect{ .still_alive = true };
const bee = Insect{ .flowers_visited = 17 };
std.debug.print("Insect report! ", .{});

View file

@ -273,7 +273,7 @@ const HermitsNotebook = struct {
// distance) than the one we'd noted before. If it is, we
// overwrite the old entry with the new one.
fn checkNote(self: *HermitsNotebook, note: NotebookEntry) void {
var existing_entry = self.getEntry(note.place);
const existing_entry = self.getEntry(note.place);
if (existing_entry == null) {
self.entries[self.end_of_entries] = note;
@ -386,7 +386,7 @@ pub fn main() void {
// "start" entry we just added) until we run out, at which point
// we'll have checked every reachable Place.
while (notebook.hasNextEntry()) {
var place_entry = notebook.getNextEntry();
const place_entry = notebook.getNextEntry();
// For every Path that leads FROM the current Place, create a
// new note (in the form of a NotebookEntry) with the

View file

@ -2,12 +2,12 @@
// Zig lets you express integer literals in several convenient
// formats. These are all the same value:
//
// const a1: u8 = 65; // decimal
// const a2: u8 = 0x41; // hexadecimal
// const a3: u8 = 0o101; // octal
// const a4: u8 = 0b1000001; // binary
// const a5: u8 = 'A'; // ASCII code point literal
// const a6: u16 = 'Ȁ'; // Unicode code points can take up to 21 bits
// const a1: u8 = 65; // decimal
// const a2: u8 = 0x41; // hexadecimal
// const a3: u8 = 0o101; // octal
// const a4: u8 = 0b1000001; // binary
// const a5: u8 = 'A'; // ASCII code point literal
// const a6: u16 = '\u{0041}'; // Unicode code points can take up to 21 bits
//
// You can also place underscores in numbers to aid readability:
//

View file

@ -39,11 +39,11 @@ const print = @import("std").debug.print;
pub fn main() void {
// The approximate weight of the Space Shuttle upon liftoff
// (including boosters and fuel tank) was 2,200 tons.
// (including boosters and fuel tank) was 4,480,000 lb.
//
// We'll convert this weight from tons to kilograms at a
// conversion of 907.18kg to the ton.
const shuttle_weight: f16 = 907.18 * 2200;
// We'll convert this weight from pound to kilograms at a
// conversion of 0.453592kg to the pound.
const shuttle_weight: f16 = 0.453592 * 4480e6;
// By default, float values are formatted in scientific
// notation. Try experimenting with '{d}' and '{d:.3}' to see

View file

@ -58,7 +58,7 @@ pub fn main() void {
// There is a difference between
// - a value, that overflowed at some point and is now corrupted
// - a single operation that overflows and maybe causes subsequent errors
// In practise we usually notice the overflowed value first and have to work
// In practice we usually notice the overflowed value first and have to work
// our way backwards to the operation that caused the overflow.
//
// If there was no overflow at all while adding 5 to a, what value would

View file

@ -38,16 +38,16 @@ pub fn main() void {
var count = 0;
count += 1;
var a1: [count]u8 = .{'A'} ** count;
const a1: [count]u8 = .{'A'} ** count;
count += 1;
var a2: [count]u8 = .{'B'} ** count;
const a2: [count]u8 = .{'B'} ** count;
count += 1;
var a3: [count]u8 = .{'C'} ** count;
const a3: [count]u8 = .{'C'} ** count;
count += 1;
var a4: [count]u8 = .{'D'} ** count;
const a4: [count]u8 = .{'D'} ** count;
print("{s} {s} {s} {s}\n", .{ a1, a2, a3, a4 });

View file

@ -83,19 +83,19 @@ const DuctError = error{UnmatchedDiameters};
pub fn main() void {
// This is a real duck!
var ducky1 = Duck{
const ducky1 = Duck{
.eggs = 0,
.loudness = 3,
};
// This is not a real duck, but it has quack() and waddle()
// abilities, so it's still a "duck".
var ducky2 = RubberDuck{
const ducky2 = RubberDuck{
.in_bath = false,
};
// This is not even remotely a duck.
var ducky3 = Duct{
const ducky3 = Duct{
.diameter = 17,
.length = 165,
.galvanized = true,

View file

@ -39,7 +39,7 @@ pub fn main() void {
// This gets the digit from the "instruction". Can you
// figure out why we subtract '0' from it?
comptime var digit = instructions[i + 1] - '0';
const digit = instructions[i + 1] - '0';
// This 'switch' statement contains the actual work done
// at runtime. At first, this doesn't seem exciting...

View file

@ -110,7 +110,7 @@ const HermitsNotebook = struct {
}
fn checkNote(self: *HermitsNotebook, note: NotebookEntry) void {
var existing_entry = self.getEntry(note.place);
const existing_entry = self.getEntry(note.place);
if (existing_entry == null) {
self.entries[self.end_of_entries] = note;
@ -180,7 +180,7 @@ pub fn main() void {
notebook.checkNote(working_note);
while (notebook.hasNextEntry()) {
var place_entry = notebook.getNextEntry();
const place_entry = notebook.getNextEntry();
for (place_entry.place.paths) |*path| {
working_note = NotebookEntry{

View file

@ -46,7 +46,7 @@ pub fn main() void {
var nums = [_:0]u32{ 1, 2, 3, 4, 5, 6 };
// And here's a zero-terminated many-item pointer:
var ptr: [*:0]u32 = &nums;
const ptr: [*:0]u32 = &nums;
// For fun, let's replace the value at position 3 with the
// sentinel value 0. This seems kind of naughty.
@ -74,8 +74,8 @@ pub fn main() void {
fn printSequence(my_seq: anytype) void {
const my_typeinfo = @typeInfo(@TypeOf(my_seq));
// The TypeInfo contained in my_type is a union. We use a
// switch to handle printing the Array or Pointer fields,
// The TypeInfo contained in my_typeinfo is a union. We use
// a switch to handle printing the Array or Pointer fields,
// depending on which type of my_seq was passed in:
switch (my_typeinfo) {
.Array => {

View file

@ -48,13 +48,13 @@ pub fn main() void {
// * circle1 should hold i32 integers
// * circle2 should hold f32 floats
//
var circle1 = ??? {
const circle1 = ??? {
.center_x = 25,
.center_y = 70,
.radius = 15,
};
var circle2 = ??? {
const circle2 = ??? {
.center_x = 25.234,
.center_y = 70.999,
.radius = 15.714,

View file

@ -96,7 +96,7 @@ const Insect = union(enum) {
};
pub fn main() !void {
var my_insects = [_]Insect{
const my_insects = [_]Insect{
Insect{ .ant = Ant{ .still_alive = true } },
Insect{ .bee = Bee{ .flowers_visited = 17 } },
Insect{ .grasshopper = Grasshopper{ .distance_hopped = 32 } },

View file

@ -40,7 +40,7 @@
// our well-known "import" for Zig
const std = @import("std");
// and here the new the import for C
// and here the new import for C
const c = @cImport({
@cInclude("unistd.h");
});

View file

@ -1,19 +1,26 @@
//
// Often, C functions are used where no equivalent Zig function exists
// yet. Since the integration of a C function is very simple, as already
// yet. Okay, that's getting less and less. ;-)
//
// Since the integration of a C function is very simple, as already
// seen in the last exercise, it naturally offers itself to use the
// very large variety of C functions for our own programs.
// As an example:
//
// Let's say we have a given angle of 765.2 degrees. If we want to
// normalize that, it means that we have to subtract X * 360 degrees
// to get the correct angle. How could we do that? A good method is
// to use the modulo function. But if we write "765.2 % 360", it won't
// work, because the standard modulo function works only with integer
// values. In the C library "math", there is a function called "fmod";
// the "f" stands for floating and means that we can solve modulo for
// real numbers. With this function, it should be possible to normalize
// our angle. Let's go.
// to get the correct angle.
// How could we do that? A good method is to use the modulo function.
// But if we write "765.2 % 360", it only works with float values
// that are known at compile time.
// In Zig, we would use @mod(a, b) instead.
//
// Let us now assume that we cannot do this in Zig, but only with
// a C function from the standard library. In the library "math",
// there is a function called "fmod"; the "f" stands for floating
// and means that we can solve modulo for real numbers. With this
// function, it should be possible to normalize our angle.
// Let's go.
const std = @import("std");

View file

@ -30,9 +30,9 @@
// std.debug.print("slice_ptr={*}\n", .{slice_ptr});
// }
// Instead of a simple integer or a constant sized slice, this
// program requires a slice to be allocated that is the same size as
// an input array.
// Instead of a simple integer or a slice with a constant size,
// this program requires allocating a slice that is the same size
// as an input array.
// Given a series of numbers, take the running average. In other
// words, each item N should contain the average of the last N
@ -52,7 +52,7 @@ fn runningAverage(arr: []const f64, avg: []f64) void {
pub fn main() !void {
// pretend this was defined by reading in user input
var arr: []const f64 = &[_]f64{ 0.3, 0.2, 0.1, 0.1, 0.4 };
const arr: []const f64 = &[_]f64{ 0.3, 0.2, 0.1, 0.1, 0.4 };
// initialize the allocator
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
@ -64,7 +64,7 @@ pub fn main() !void {
const allocator = arena.allocator();
// allocate memory for this array
var avg: []f64 = ???;
const avg: []f64 = ???;
runningAverage(arr, avg);
std.debug.print("Running Average: ", .{});

View file

@ -1,5 +1,5 @@
//
// Bit manipulations is a very powerful tool just also from Zig.
// Bit manipulation is a very powerful tool, also from Zig.
// Since the dawn of the computer age, numerous algorithms have been
// developed that solve tasks solely by moving, setting, or logically
// combining bits.
@ -8,10 +8,10 @@
// functions where possible. And it is often possible with calculations
// based on integers.
//
// Often it is not easy to understand at first glance what exactly these
// At first glance, it is often not easy to understand what exactly these
// algorithms do when only "numbers" in memory areas change outwardly.
// But it must never be forgotten that the numbers only represent the
// interpretation of the bit sequences.
// However, it should never be forgotten that the numbers only represent
// the interpretation of the bit sequences.
//
// Quasi the reversed case we have otherwise, namely that we represent
// numbers in bit sequences.
@ -20,8 +20,8 @@
//
// Zig provides all the necessary functions to change the bits inside
// a variable. It is distinguished whether the bit change leads to an
// overflow or not.The details are in the Zig documentation in section
// 10.1 "Table of Operators".
// overflow or not. The details are in the Zig documentation in section
// "Table of Operators".
//
// Here are some examples of how the bits of variables can be changed:
//

View file

@ -1,5 +1,5 @@
//
// Another useful practice for bit manipulation is setting bits as flags.
// Another useful application for bit manipulation is setting bits as flags.
// This is especially useful when processing lists of something and storing
// the states of the entries, e.g. a list of numbers and for each prime
// number a flag is set.
@ -19,9 +19,9 @@
// For example, you could take an array of bool and set the value to 'true'
// for each letter in the order of the alphabet (a=0; b=1; etc.) found in
// the sentence. However, this is neither memory efficient nor particularly
// fast. Instead we take a simpler way, very similar in principle, we define
// a variable with at least 26 bits (e.g. u32) and also set the bit for each
// letter found at the corresponding position.
// fast. Instead we choose a simpler approach that is very similar in principle:
// We define a variable with at least 26 bits (e.g. u32) and set the bit for
// each letter that is found in the corresponding position.
//
// Zig provides functions for this in the standard library, but we prefer to
// solve it without these extras, after all we want to learn something.
@ -39,7 +39,7 @@ fn isPangram(str: []const u8) bool {
// first we check if the string has at least 26 characters
if (str.len < 26) return false;
// we uses a 32 bit variable of which we need 26 bits
// we use a 32 bit variable of which we need 26 bits
var bits: u32 = 0;
// loop about all characters in the string
@ -49,7 +49,7 @@ fn isPangram(str: []const u8) bool {
// then we set the bit at the position
//
// to do this, we use a little trick:
// since the letters in the ASCI table start at 65
// since the letters in the ASCII table start at 65
// and are numbered sequentially, we simply subtract the
// first letter (in this case the 'a') from the character
// found, and thus get the position of the desired bit

View file

@ -19,10 +19,10 @@
// https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig#L29
//
// 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 a file. The latter is useful when
// These can be used in different ways, but generally 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 a file. The latter is useful when
// large amounts of data are to be processed by other programs.
//
// In Ziglings, we are concerned with the output to the console.

View file

@ -1,9 +1,9 @@
//
// The functionality of the standard library is becoming increasingly
// important in Zig. On the one hand, it is helpful to look at how
// important in Zig. First of all, it is helpful to take a look at how
// the individual functions are implemented. Because this is wonderfully
// suitable as a template for your own functions. On the other hand,
// these standard functions are part of the basic equipment of Zig.
// suitable as a template for your own functions. In addition these
// standard functions are part of the basic configuration of Zig.
//
// This means that they are always available on every system.
// Therefore it is worthwhile to deal with them also in Ziglings.

134
exercises/104_threading.zig Normal file
View file

@ -0,0 +1,134 @@
//
// Whenever there is a lot to calculate, the question arises as to how
// tasks can be carried out simultaneously. We have already learned about
// one possibility, namely asynchronous processes, in Exercises 84-91.
//
// However, the computing power of the processor is only distributed to
// the started and running tasks, which always reaches its limits when
// pure computing power is called up.
//
// For example, in blockchains based on proof of work, the miners have
// to find a nonce for a certain character string so that the first m bits
// in the hash of the character string and the nonce are zeros.
// As the miner who can solve the task first receives the reward, everyone
// tries to complete the calculations as quickly as possible.
//
// This is where multithreading comes into play, where tasks are actually
// distributed across several cores of the CPU or GPU, which then really
// means a multiplication of performance.
//
// The following diagram roughly illustrates the difference between the
// various types of process execution.
// The 'Overall Time' column is intended to illustrate how the time is
// affected if, instead of one core as in synchronous and asynchronous
// processing, a second core now helps to complete the work in multithreading.
//
// In the ideal case shown, execution takes only half the time compared
// to the synchronous single thread. And even asynchronous processing
// is only slightly faster in comparison.
//
//
// Synchronous Asynchronous
// Processing Processing Multithreading
//
// Thread 1 Thread 1 Thread 1 Thread 2
// Overall Time
//
//
// T T T T
// a a a a
// s s s s
// k k k k
//
// 1 1 1 3
//
// 5 Sec
//
// Blocking T T T
// a a a
// s s s 8 Sec
// k k k
// T
// a 2 2 4
// s
// k 10 Sec
//
// 1 T
// a
// s
// k
// T
// a 1
// s
// k
//
// 2
//
//
//
//
//
// The diagram was modeled on the one in a blog in which the differences
// between asynchronous processing and multithreading are explained in detail:
// https://blog.devgenius.io/multi-threading-vs-asynchronous-programming-what-is-the-difference-3ebfe1179a5
//
// Our exercise is essentially about clarifying the approach in Zig and
// therefore we try to keep it as simple as possible.
// Multithreading in itself is already difficult enough. ;-)
//
const std = @import("std");
pub fn main() !void {
// This is where the preparatory work takes place
// before the parallel processing begins.
std.debug.print("Starting work...\n", .{});
// These curly brackets are very important, they are necessary
// to enclose the area where the threads are called.
// Without these brackets, the program would not wait for the
// end of the threads and they would continue to run beyond the
// end of the program.
{
// Now we start the first thread, with the number as parameter
const handle = try std.Thread.spawn(.{}, thread_function, .{1});
// Waits for the thread to complete,
// then deallocates any resources created on `spawn()`.
defer handle.join();
// Second thread
const handle2 = try std.Thread.spawn(.{}, thread_function, .{-4}); // that can't be right?
defer handle2.join();
// Third thread
const handle3 = try std.Thread.spawn(.{}, thread_function, .{3});
defer ??? // <-- something is missing
// After the threads have been started,
// they run in parallel and we can still do some work in between.
std.time.sleep(1500 * std.time.ns_per_ms);
std.debug.print("Some weird stuff, after starting the threads.\n", .{});
}
// After we have left the closed area, we wait until
// the threads have run through, if this has not yet been the case.
std.debug.print("Zig is cool!\n", .{});
}
// This function is started with every thread that we set up.
// In our example, we pass the number of the thread as a parameter.
fn thread_function(num: usize) !void {
std.time.sleep(200 * num * std.time.ns_per_ms);
std.debug.print("thread {d}: {s}\n", .{ num, "started." });
// This timer simulates the work of the thread.
const work_time = 3 * ((5 - num % 3) - 2);
std.time.sleep(work_time * std.time.ns_per_s);
std.debug.print("thread {d}: {s}\n", .{ num, "finished." });
}
// This is the easiest way to run threads in parallel.
// In general, however, more management effort is required,
// e.g. by setting up a pool and allowing the threads to communicate
// with each other using semaphores.
//
// But that's a topic for another exercise.

View file

@ -0,0 +1,107 @@
//
// Now that we are familiar with the principles of multi-threading,
// let's boldly venture into a practical example from mathematics.
// We will determine the circle number PI with sufficient accuracy.
//
// There are different methods for this, and some of them are several
// hundred years old. For us, the dusty procedures are surprisingly well
// suited to our exercise. Because the mathematicians of the time didn't
// have fancy computers with which we can calculate something like this
// in seconds today.
// Whereby, of course, it depends on the accuracy, i.e. how many digits
// after the decimal point we are interested in.
// But these old procedures can still be tackled with paper and pencil,
// which is why they are easier for us to understand.
// At least for me. ;-)
//
// So let's take a mental leap back a few years.
// Around 1672 (if you want to know and read about it in detail, you can
// do so on Wikipedia, for example), various mathematicians once again
// discovered a method of approaching the circle number PI.
// There were the Scottish mathematician Gregory and the German
// mathematician Leibniz, and even a few hundred years earlier the Indian
// mathematician Madhava. All of them independently developed the same
// formula, which was published by Leibnitz in 1682 in the journal
// "Acta Eruditorum".
// This is why this method has become known as the "Leibnitz series",
// although the other names are also often used today.
// We will not go into the formula and its derivation in detail, but
// will deal with the series straight away:
//
// 4 4 4 4 4
// PI = --- - --- + --- - --- + --- ...
// 1 3 5 7 9
//
// As you can clearly see, the series starts with the whole number 4 and
// approaches the circle number by subtracting and adding smaller and
// smaller parts of 4. Pretty much everyone has learned PI = 3.14 at school,
// but very few people remember other digits, and this is rarely necessary
// in practice. Because either you don't need the precision, or you use a
// calculator in which the number is stored as a very precise constant.
// But at some point this constant was calculated and we are doing the same
// now.The question at this point is, how many partial values do we have
// to calculate for which accuracy?
//
// The answer is chewing, to get 8 digits after the decimal point we need
// 1,000,000,000 partial values. And for each additional digit we have to
// add a zero.
// Even fast computers - and I mean really fast computers - get a bit warmer
// on the CPU when it comes to really many digits. But the 8 digits are
// enough for us for now, because we want to understand the principle and
// nothing more, right?
//
// As we have already discovered, the Leibnitz series is a series with a
// fixed distance of 2 between the individual partial values. This makes
// it easy to apply a simple loop to it, because if we start with n = 1
// (which is not necessarily useful now) we always have to add 2 in each
// round.
// But wait! The partial values are alternately added and subtracted.
// This could also be achieved with one loop, but not very elegantly.
// It also makes sense to split this between two CPUs, one calculates
// the positive values and the other the negative values. And so we can
// simply start two threads and add everything up at the end and we're
// done.
// We just have to remember that if only the positive or negative values
// are calculated, the distances are twice as large, i.e. 4.
//
// So that the whole thing has a real learning effect, the first thread
// call is specified and you have to make the second.
// But don't worry, it will work out. :-)
//
const std = @import("std");
pub fn main() !void {
const count = 1_000_000_000;
var pi_plus: f64 = 0;
var pi_minus: f64 = 0;
{
// First thread to calculate the plus numbers.
const handle1 = try std.Thread.spawn(.{}, thread_pi, .{ &pi_plus, 5, count });
defer handle1.join();
// Second thread to calculate the minus numbers.
???
}
// Here we add up the results.
std.debug.print("PI ≈ {d:.8}\n", .{4 + pi_plus - pi_minus});
}
fn thread_pi(pi: *f64, begin: u64, end: u64) !void {
var n: u64 = begin;
while (n < end) : (n += 4) {
pi.* += 4 / @as(f64, @floatFromInt(n));
}
}
// If you wish, you can increase the number of loop passes, which
// improves the number of digits.
//
// But be careful:
// In order for parallel processing to really show its strengths,
// the compiler must be given the "-O ReleaseFast" flag when it
// is created. Otherwise the debug functions slow down the speed
// to such an extent that seconds become minutes during execution.
//
// And you should remove the formatting restriction in "print",
// otherwise you will not be able to see the additional digits.

92
exercises/106_files.zig Normal file
View file

@ -0,0 +1,92 @@
//
// Until now, we've only been printing our output in the console,
// which is good enough for fighting alien and hermit bookkeeping.
//
// However, many other task require some interaction with the file system,
// which is the underlying structure for organizing files on your computer.
//
// The File System provide a hierarchical structure for storing files
// by organizing files into directories, which hold files and other directories,
// thus creating a tree structure for navigating.
//
// Fortunately, zig standard library provide a simple api for interacting
// with the file system, see the detail documentation here
//
// https://ziglang.org/documentation/master/std/#std.fs
//
// In this exercise, we'll try to
// - create a new directory
// - open a file in the directory
// - write to the file.
//
// import std as always
const std = @import("std");
pub fn main() !void {
// first we get the current working directory
const cwd: std.fs.Dir = std.fs.cwd();
// then we'll try to make a new directory /output/
// to put our output files.
cwd.makeDir("output") catch |e| switch (e) {
// there are chance you might want to run this
// program more than once and the path might already
// been created, so we'll have to handle this error
// by doing nothing
//
// we want to catch error.PathAlreadyExists and do nothing
??? => {},
// if is any other unexpected error we just propagate it through
else => return e,
};
// then we'll try to open our freshly created directory
// wait a minute
// opening a directory might fail!
// what should we do here?
var output_dir: std.fs.Dir = cwd.openDir("output", .{});
defer output_dir.close();
// we try to open the file `zigling.txt`,
// and propagate the error up if there are any errors
const file: std.fs.File = try output_dir.createFile("zigling.txt", .{});
// it is a good habit to close a file after you are done with it
// so that other programs can read it and prevent data corruption
// but here we are not yet done writing to the file
// if only there were a keyword in zig that
// allows you "defer" code execute to the end of scope...
file.close();
// !you are not allowed to switch these two lines above the file closing line!
const byte_written = try file.write("It's zigling time!");
std.debug.print("Successfully wrote {d} bytes.\n", .{byte_written});
}
// to check if you actually write to the file, you can either,
// 1. open the file on your text editor, or
// 2. print the content of the file in the console with the following command
// >> cat ./output/zigling.txt
//
//
// More on Creating files
//
// notice in:
// ... try output_dir.createFile("zigling.txt", .{});
// ^^^
// we passed this anonymous struct to the function call
//
// this is the struct `CreateFlag` with default fields
// {
// read: bool = false,
// truncate: bool = true,
// exclusive: bool = false,
// lock: Lock = .none,
// lock_nonblocking: bool = false,
// mode: Mode = default_mode
// }
//
// Question:
// - what should you do if you want to also read the file after opening it?
// - go to documentation of the struct `std.fs.Dir` here
// https://ziglang.org/documentation/master/std/#std.fs.Dir
// - can you find a function for opening a file? how about deleting a file?
// - what kind of options can you use with those functions?

52
exercises/107_files2.zig Normal file
View file

@ -0,0 +1,52 @@
//
// Prerequisite :
// - exercise/106_files.zig, or
// - create a file {project_root}/output/zigling.txt
// with content `It's zigling time!`(18 byte total)
//
// Now there no point in writing to a file if we don't read from it am I right?
// let's write a program to read the content of the file that we just created.
//
// I am assuming that you've created the appropriate files for this to work.
//
// Alright, bud, lean in close here's the game plan.
// - First, we open the {project_root}/output/ directory
// - Secondly, we open file `zigling.txt` in that directory
// - then, we initalize an array of characters with all letter 'A', and print it
// - After that, we read the content of the file to the array
// - Finally, we print out the read content
const std = @import("std");
pub fn main() !void {
// Get the current working directory
const cwd = std.fs.cwd();
// try to open ./output assuming you did your 106_files exercise
var output_dir = try cwd.openDir("output", .{});
defer output_dir.close();
// try to open the file
const file = try output_dir.openFile("zigling.txt", .{});
defer file.close();
// initalize 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 initalization below
var content = ['A']*64;
// this should print out : `AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`
std.debug.print("{s}\n", .{content});
// okay, seems like a threat of violence is not the answer in this case
// 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 vaild in this case
const bytes_read = zig_read_the_file_or_i_will_fight_you(&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
});
}

View file

@ -1,11 +1,11 @@
--- exercises/025_errors5.zig 2023-10-03 22:15:22.122241138 +0200
+++ answers/025_errors5.zig 2023-10-05 20:04:06.952764946 +0200
--- exercises/025_errors5.zig 2023-11-21 14:22:48.159250165 +0100
+++ answers/025_errors5.zig 2023-11-21 14:25:01.338277886 +0100
@@ -26,7 +26,7 @@
// This function needs to return any error which might come back from detect().
// Please use a "try" statement rather than a "catch".
//
- var x = detect(n);
+ var x = try detect(n);
- const x = detect(n);
+ const x = try detect(n);
return x + 5;
}

View file

@ -1,5 +1,5 @@
--- exercises/046_optionals2.zig 2023-10-03 22:15:22.122241138 +0200
+++ answers/046_optionals2.zig 2023-10-05 20:04:07.049433424 +0200
--- exercises/046_optionals2.zig 2024-05-10 23:11:25.796632478 +0200
+++ answers/046_optionals2.zig 2024-05-10 23:10:16.115335668 +0200
@@ -21,7 +21,7 @@
const Elephant = struct {
@ -9,12 +9,11 @@
visited: bool = false,
};
@@ -51,7 +51,7 @@
@@ -51,6 +51,6 @@
// We should stop once we encounter a tail that
// does NOT point to another element. What can
// we put here to make that happen?
- if (e.tail == null) ???;
+ if (e.tail == null) break;
e = e.tail.?;
- e = e.tail ???
+ e = e.tail orelse break;
}
}

View file

@ -1,5 +1,5 @@
--- exercises/051_values.zig 2023-10-03 22:15:22.122241138 +0200
+++ answers/051_values.zig 2023-10-05 20:04:07.072767194 +0200
--- exercises/051_values.zig 2024-03-14 23:25:42.695020607 +0100
+++ answers/051_values.zig 2024-03-14 23:28:34.525109174 +0100
@@ -87,7 +87,7 @@
// Let's assign the std.debug.print function to a const named
// "print" so that we can use this new name later!
@ -9,7 +9,7 @@
// Now let's look at assigning and pointing to values in Zig.
//
@@ -152,13 +152,13 @@
@@ -163,13 +163,13 @@
print("XP before:{}, ", .{glorp.experience});
// Fix 1 of 2 goes here:

View file

@ -1,11 +1,11 @@
--- exercises/060_floats.zig 2023-10-03 22:15:22.125574535 +0200
+++ answers/060_floats.zig 2023-10-05 20:04:07.112767942 +0200
--- exercises/060_floats.zig 2023-11-06 19:45:03.609687304 +0100
+++ answers/060_floats.zig 2023-11-06 19:44:49.249419994 +0100
@@ -43,7 +43,7 @@
//
// We'll convert this weight from tons to kilograms at a
// conversion of 907.18kg to the ton.
- const shuttle_weight: f16 = 907.18 * 2200;
+ const shuttle_weight: f32 = 907.18 * 2200.0;
// We'll convert this weight from pound to kilograms at a
// conversion of 0.453592kg to the pound.
- const shuttle_weight: f16 = 0.453592 * 4480e6;
+ const shuttle_weight: f32 = 0.453592 * 4.480e6;
// By default, float values are formatted in scientific
// notation. Try experimenting with '{d}' and '{d:.3}' to see

View file

@ -1,5 +1,5 @@
--- exercises/067_comptime2.zig 2023-10-03 22:15:22.125574535 +0200
+++ answers/067_comptime2.zig 2023-10-05 20:04:07.146101899 +0200
--- exercises/067_comptime2.zig 2023-11-21 14:36:12.080295365 +0100
+++ answers/067_comptime2.zig 2023-11-21 15:11:50.814098876 +0100
@@ -35,7 +35,7 @@
// In this contrived example, we've decided to allocate some
// arrays using a variable count! But something's missing...
@ -8,4 +8,4 @@
+ comptime var count = 0;
count += 1;
var a1: [count]u8 = .{'A'} ** count;
const a1: [count]u8 = .{'A'} ** count;

View file

@ -1,5 +1,5 @@
--- exercises/075_quiz8.zig 2023-10-03 22:15:22.125574535 +0200
+++ answers/075_quiz8.zig 2023-10-05 20:04:07.182769252 +0200
--- exercises/075_quiz8.zig 2023-11-21 14:48:15.440702720 +0100
+++ answers/075_quiz8.zig 2023-11-21 14:50:23.453311616 +0100
@@ -49,7 +49,11 @@
//
// Please fill in the body of this function!

View file

@ -1,18 +1,18 @@
--- exercises/080_anonymous_structs.zig 2023-10-03 22:15:22.125574535 +0200
+++ answers/080_anonymous_structs.zig 2023-10-05 20:04:07.202769626 +0200
--- exercises/080_anonymous_structs.zig 2023-11-21 14:52:54.312749682 +0100
+++ answers/080_anonymous_structs.zig 2023-11-21 14:52:43.909225238 +0100
@@ -48,13 +48,13 @@
// * circle1 should hold i32 integers
// * circle2 should hold f32 floats
//
- var circle1 = ??? {
+ var circle1 = Circle(i32){
- const circle1 = ??? {
+ const circle1 = Circle(i32){
.center_x = 25,
.center_y = 70,
.radius = 15,
};
- var circle2 = ??? {
+ var circle2 = Circle(f32){
- const circle2 = ??? {
+ const circle2 = Circle(f32){
.center_x = 25.234,
.center_y = 70.999,
.radius = 15.714,

View file

@ -1,6 +1,6 @@
--- exercises/094_c_math.zig 2023-10-22 14:00:02.909379696 +0200
+++ answers/094_c_math.zig 2023-10-22 14:02:46.709025235 +0200
@@ -19,7 +19,7 @@
--- exercises/094_c_math.zig 2024-02-28 12:50:35.789939935 +0100
+++ answers/094_c_math.zig 2024-02-28 12:53:57.910309471 +0100
@@ -26,7 +26,7 @@
const c = @cImport({
// What do we need here?

View file

@ -1,11 +1,11 @@
--- exercises/096_memory_allocation.zig 2023-10-03 22:15:22.125574535 +0200
+++ answers/096_memory_allocation.zig 2023-10-05 20:04:07.276104333 +0200
--- exercises/096_memory_allocation.zig 2023-11-21 14:55:33.805678390 +0100
+++ answers/096_memory_allocation.zig 2023-11-21 14:56:00.236163484 +0100
@@ -64,7 +64,7 @@
const allocator = arena.allocator();
// allocate memory for this array
- var avg: []f64 = ???;
+ var avg: []f64 = try allocator.alloc(f64, arr.len);
- const avg: []f64 = ???;
+ const avg: []f64 = try allocator.alloc(f64, arr.len);
runningAverage(arr, avg);
std.debug.print("Running Average: ", .{});

View file

@ -0,0 +1,17 @@
--- exercises/104_threading.zig 2024-04-10 19:12:29.878856370 +0200
+++ answers/104_threading.zig 2024-04-10 19:11:22.304265713 +0200
@@ -97,12 +97,12 @@
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});
defer handle2.join();
// Third thread
const handle3 = try std.Thread.spawn(.{}, thread_function, .{3});
- defer ??? // <-- something is missing
+ defer handle3.join();
// After the threads have been started,
// they run in parallel and we can still do some work in between.

View file

@ -0,0 +1,13 @@
--- exercises/105_threading2.zig 2024-03-23 16:35:14.754540802 +0100
+++ answers/105_threading2.zig 2024-03-23 16:38:00.577539733 +0100
@@ -81,8 +81,8 @@
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});

View file

@ -0,0 +1,29 @@
--- exercises/106_files.zig 2024-05-05 00:48:25.808548611 +0200
+++ answers/106_files.zig 2024-05-05 01:00:40.742969819 +0200
@@ -35,7 +35,7 @@
// by doing nothing
//
// we want to catch error.PathAlreadyExists and do nothing
- ??? => {},
+ error.PathAlreadyExists => {},
// if is any other unexpected error we just propagate it through
else => return e,
};
@@ -44,7 +44,7 @@
// 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 @@
// but here we are not yet done writing to the file
// if only there were a keyword in zig that
// allows you "defer" code execute to the end of scope...
- file.close();
+ defer file.close();
// !you are not allowed to switch these two lines above the file closing line!
const byte_written = try file.write("It's zigling time!");

View file

@ -0,0 +1,26 @@
--- exercises/107_files2.zig 2024-05-05 00:48:25.808548611 +0200
+++ answers/107_files2.zig 2024-05-05 01:14:03.866062288 +0200
@@ -33,7 +33,7 @@
// initalize 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 initalization 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 @@
// 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 vaild 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
});
}

View file

@ -8,8 +8,8 @@ const mem = std.mem;
const Allocator = std.mem.Allocator;
const Child = std.process.Child;
const Build = std.build;
const FileSource = std.Build.FileSource;
const Build = std.Build;
const LazyPath = std.Build.LazyPath;
const Reader = fs.File.Reader;
const RunStep = std.Build.RunStep;
const Step = Build.Step;
@ -33,7 +33,7 @@ pub fn addCliTests(b: *std.Build, exercises: []const Exercise) *Step {
const n = ex.number();
const cmd = b.addSystemCommand(&.{
b.zig_exe,
b.graph.zig_exe,
"build",
"-Dhealed",
b.fmt("-Dhealed-path={s}", .{tmp_path}),
@ -69,7 +69,7 @@ pub fn addCliTests(b: *std.Build, exercises: []const Exercise) *Step {
// TODO: when an exercise is modified, the cache is not invalidated.
const cmd = b.addSystemCommand(&.{
b.zig_exe,
b.graph.zig_exe,
"build",
"-Dhealed",
b.fmt("-Dhealed-path={s}", .{tmp_path}),
@ -99,7 +99,7 @@ pub fn addCliTests(b: *std.Build, exercises: []const Exercise) *Step {
const n = ex.number();
const cmd = b.addSystemCommand(&.{
b.zig_exe,
b.graph.zig_exe,
"build",
b.fmt("-Dn={}", .{n}),
});
@ -132,9 +132,9 @@ fn createCase(b: *Build, name: []const u8) *Step {
const CheckNamedStep = struct {
step: Step,
exercise: Exercise,
stderr: FileSource,
stderr: LazyPath,
pub fn create(owner: *Build, exercise: Exercise, stderr: FileSource) *CheckNamedStep {
pub fn create(owner: *Build, exercise: Exercise, stderr: LazyPath) *CheckNamedStep {
const self = owner.allocator.create(CheckNamedStep) catch @panic("OOM");
self.* = .{
.step = Step.init(.{
@ -152,7 +152,7 @@ const CheckNamedStep = struct {
fn make(step: *Step, _: *std.Progress.Node) !void {
const b = step.owner;
const self = @fieldParentPtr(CheckNamedStep, "step", step);
const self: *CheckNamedStep = @alignCast(@fieldParentPtr("step", step));
const ex = self.exercise;
const stderr_file = try fs.cwd().openFile(
@ -180,12 +180,12 @@ const CheckNamedStep = struct {
const CheckStep = struct {
step: Step,
exercises: []const Exercise,
stderr: FileSource,
stderr: LazyPath,
pub fn create(
owner: *Build,
exercises: []const Exercise,
stderr: FileSource,
stderr: LazyPath,
) *CheckStep {
const self = owner.allocator.create(CheckStep) catch @panic("OOM");
self.* = .{
@ -204,7 +204,7 @@ const CheckStep = struct {
fn make(step: *Step, _: *std.Progress.Node) !void {
const b = step.owner;
const self = @fieldParentPtr(CheckStep, "step", step);
const self: *CheckStep = @alignCast(@fieldParentPtr("step", step));
const exercises = self.exercises;
const stderr_file = try fs.cwd().openFile(
@ -327,7 +327,7 @@ const FailStep = struct {
fn make(step: *Step, _: *std.Progress.Node) !void {
const b = step.owner;
const self = @fieldParentPtr(FailStep, "step", step);
const self: *FailStep = @alignCast(@fieldParentPtr("step", step));
try step.result_error_msgs.append(b.allocator, self.error_msg);
return error.MakeFailed;
@ -370,7 +370,7 @@ const HealStep = struct {
fn make(step: *Step, _: *std.Progress.Node) !void {
const b = step.owner;
const self = @fieldParentPtr(HealStep, "step", step);
const self: *HealStep = @alignCast(@fieldParentPtr("step", step));
return heal(b.allocator, self.exercises, self.work_path);
}