Zig: completed Collatz Conjecture and Isogram

This commit is contained in:
Andrew Scott 2024-08-03 18:19:52 -04:00
parent 563d208eef
commit 3f28e82a4e
Signed by: a
GPG key ID: 7CD5A5977E4931C1
12 changed files with 385 additions and 0 deletions

View file

@ -0,0 +1,22 @@
{
"authors": [
"massivelivefun"
],
"contributors": [
"ee7"
],
"files": {
"solution": [
"collatz_conjecture.zig"
],
"test": [
"test_collatz_conjecture.zig"
],
"example": [
".meta/example.zig"
]
},
"blurb": "Calculate the number of steps to reach 1 using the Collatz conjecture.",
"source": "An unsolved problem in mathematics named after mathematician Lothar Collatz",
"source_url": "https://en.wikipedia.org/wiki/3x_%2B_1_problem"
}

View file

@ -0,0 +1 @@
{"track":"zig","exercise":"collatz-conjecture","id":"246eebc2ac2e4981be47574fc2b1b0cf","url":"https://exercism.org/tracks/zig/exercises/collatz-conjecture","handle":"Chomp1295","is_requester":true,"auto_approve":false}

View file

@ -0,0 +1,53 @@
# Help
## Running the tests
Write your code in `<exercise_name>.zig`.
To run the tests for an exercise, run:
```bash
zig test test_exercise_name.zig
```
in the exercise's root directory (replacing `exercise_name` with the name of the exercise).
## Submitting your solution
You can submit your solution using the `exercism submit collatz_conjecture.zig` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Zig track's documentation](https://exercism.org/docs/tracks/zig)
- The [Zig track's programming category on the forum](https://forum.exercism.org/c/programming/zig)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
- [The Zig Programming Language Documentation][documentation] is a great overview of all of the language features that Zig provides to those who use it.
- [Zig Guide][zig-guide] is an excellent primer that explains the language features that Zig has to offer.
- [Ziglings][ziglings] is highly recommended.
Learn Zig by fixing tiny broken programs.
- [The Zig Programming Language Discord][discord-zig] is the main [Discord][discord].
It provides a great way to get in touch with the Zig community at large, and get some quick, direct help for any Zig related problem.
- [#zig][irc] on irc.freenode.net is the main Zig IRC channel.
- [/r/Zig][reddit] is the main Zig subreddit.
- [Stack Overflow][stack-overflow] can be used to discover code snippets and solutions to problems that may have already asked and maybe solved by others.
[discord]: https://discordapp.com
[discord-zig]: https://discord.com/invite/gxsFFjE
[documentation]: https://ziglang.org/documentation/master
[irc]: https://webchat.freenode.net/?channels=%23zig
[reddit]: https://www.reddit.com/r/Zig
[stack-overflow]: https://stackoverflow.com/questions/tagged/zig
[zig-guide]: https://zig.guide/
[ziglings]: https://codeberg.org/ziglings/exercises

View file

@ -0,0 +1,67 @@
# Collatz Conjecture
Welcome to Collatz Conjecture on Exercism's Zig Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
The Collatz Conjecture or 3x+1 problem can be summarized as follows:
Take any positive integer n.
If n is even, divide n by 2 to get n / 2.
If n is odd, multiply n by 3 and add 1 to get 3n + 1.
Repeat the process indefinitely.
The conjecture states that no matter which number you start with, you will always reach 1 eventually.
Given a number n, return the number of steps required to reach 1.
## Examples
Starting with n = 12, the steps would be as follows:
0. 12
1. 6
2. 3
3. 10
4. 5
5. 16
6. 8
7. 4
8. 2
9. 1
Resulting in 9 steps.
So for input n = 12, the return value would be 9.
## Error handling
For this exercise you must add an error set `ComputationError` that contains the `IllegalArgument` error.
Remember to make it public!
The `steps` function must return `ComputationError.IllegalArgument` when its input is equal to zero.
Later exercises will usually omit explicit instructions like this.
In general, Exercism expects you to read the test file when implementing your solution.
For more details about errors in Zig, see:
- [Learning Zig - Errors][learning-zig-errors]
- [Ziglings - Exercise 21][ziglings-exercise-21]
- [Zighelp - Errors][zighelp-errors]
[learning-zig-errors]: https://www.openmymind.net/learning_zig/language_overview_2/#errors
[zighelp-errors]: https://zighelp.org/chapter-1/#errors
[ziglings-exercise-21]: https://codeberg.org/ziglings/exercises/src/commit/0d46acfa02d0c29fdfb3651e82a77284dd8f2e00/exercises/021_errors.zig
## Source
### Created by
- @massivelivefun
### Contributed to by
- @ee7
### Based on
An unsolved problem in mathematics named after mathematician Lothar Collatz - https://en.wikipedia.org/wiki/3x_%2B_1_problem

View file

@ -0,0 +1,19 @@
// Please implement the `ComputationError.IllegalArgument` error.
pub const ComputationError = error{IllegalArgument};
pub fn steps(number: usize) anyerror!usize {
if (number < 1) return ComputationError.IllegalArgument;
var count: usize = 0;
var temp: usize = number;
while (temp > 1) : (count += 1) {
if (temp % 2 == 0) {
temp /= 2;
} else {
temp = temp * 3 + 1;
}
}
return count;
}

View file

@ -0,0 +1,35 @@
const std = @import("std");
const testing = std.testing;
const collatz_conjecture = @import("collatz_conjecture.zig");
const ComputationError = collatz_conjecture.ComputationError;
test "zero steps for one" {
const expected: usize = 0;
const actual = try collatz_conjecture.steps(1);
try testing.expectEqual(expected, actual);
}
test "divide if even" {
const expected: usize = 4;
const actual = try collatz_conjecture.steps(16);
try testing.expectEqual(expected, actual);
}
test "even and odd steps" {
const expected: usize = 9;
const actual = try collatz_conjecture.steps(12);
try testing.expectEqual(expected, actual);
}
test "large number of even and odd steps" {
const expected: usize = 152;
const actual = try collatz_conjecture.steps(1_000_000);
try testing.expectEqual(expected, actual);
}
test "zero is an error" {
const expected = ComputationError.IllegalArgument;
const actual = collatz_conjecture.steps(0);
try testing.expectError(expected, actual);
}

View file

@ -0,0 +1,19 @@
{
"authors": [
"massivelivefun"
],
"files": {
"solution": [
"isogram.zig"
],
"test": [
"test_isogram.zig"
],
"example": [
".meta/example.zig"
]
},
"blurb": "Determine if a word or phrase is an isogram.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Isogram"
}

View file

@ -0,0 +1 @@
{"track":"zig","exercise":"isogram","id":"445c8a98e0724f5ab514881b68c8d01c","url":"https://exercism.org/tracks/zig/exercises/isogram","handle":"Chomp1295","is_requester":true,"auto_approve":false}

53
zig/isogram/HELP.md Normal file
View file

@ -0,0 +1,53 @@
# Help
## Running the tests
Write your code in `<exercise_name>.zig`.
To run the tests for an exercise, run:
```bash
zig test test_exercise_name.zig
```
in the exercise's root directory (replacing `exercise_name` with the name of the exercise).
## Submitting your solution
You can submit your solution using the `exercism submit isogram.zig` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Zig track's documentation](https://exercism.org/docs/tracks/zig)
- The [Zig track's programming category on the forum](https://forum.exercism.org/c/programming/zig)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
- [The Zig Programming Language Documentation][documentation] is a great overview of all of the language features that Zig provides to those who use it.
- [Zig Guide][zig-guide] is an excellent primer that explains the language features that Zig has to offer.
- [Ziglings][ziglings] is highly recommended.
Learn Zig by fixing tiny broken programs.
- [The Zig Programming Language Discord][discord-zig] is the main [Discord][discord].
It provides a great way to get in touch with the Zig community at large, and get some quick, direct help for any Zig related problem.
- [#zig][irc] on irc.freenode.net is the main Zig IRC channel.
- [/r/Zig][reddit] is the main Zig subreddit.
- [Stack Overflow][stack-overflow] can be used to discover code snippets and solutions to problems that may have already asked and maybe solved by others.
[discord]: https://discordapp.com
[discord-zig]: https://discord.com/invite/gxsFFjE
[documentation]: https://ziglang.org/documentation/master
[irc]: https://webchat.freenode.net/?channels=%23zig
[reddit]: https://www.reddit.com/r/Zig
[stack-overflow]: https://stackoverflow.com/questions/tagged/zig
[zig-guide]: https://zig.guide/
[ziglings]: https://codeberg.org/ziglings/exercises

29
zig/isogram/README.md Normal file
View file

@ -0,0 +1,29 @@
# Isogram
Welcome to Isogram on Exercism's Zig Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Determine if a word or phrase is an isogram.
An isogram (also known as a "non-pattern word") is a word or phrase without a repeating letter, however spaces and hyphens are allowed to appear multiple times.
Examples of isograms:
- lumberjacks
- background
- downstream
- six-year-old
The word _isograms_, however, is not an isogram, because the s repeats.
## Source
### Created by
- @massivelivefun
### Based on
Wikipedia - https://en.wikipedia.org/wiki/Isogram

26
zig/isogram/isogram.zig Normal file
View file

@ -0,0 +1,26 @@
pub const std = @import("std");
pub fn cmp(context: void, a: u8, b: u8) bool {
_ = context;
if (a < b) {
return true;
}
return false;
}
pub fn isIsogram(str: []const u8) bool {
const len = str.len;
if (len == 0) return true;
var buf = [_]u8{0} ** 256;
const lower = std.ascii.lowerString(&buf, str);
std.mem.sort(u8, lower, {}, cmp);
for (0..len - 1) |i| {
if (lower[i] == lower[i + 1] and std.ascii.isAlphabetic(lower[i])) {
return false;
}
}
return true;
}

View file

@ -0,0 +1,60 @@
const std = @import("std");
const testing = std.testing;
const isogram = @import("isogram.zig");
test "empty string" {
try testing.expect(isogram.isIsogram(""));
}
test "isogram with only lower case characters" {
try testing.expect(isogram.isIsogram("isogram"));
}
test "word with one duplicated character" {
try testing.expect(!isogram.isIsogram("eleven"));
}
test "word with one duplicated character from the end of the alphabet" {
try testing.expect(!isogram.isIsogram("zzyzx"));
}
test "longest reported english isogram" {
try testing.expect(isogram.isIsogram("subdermatoglyphic"));
}
test "word with duplicated character in mixed case" {
try testing.expect(!isogram.isIsogram("Alphabet"));
}
test "word with duplicated character in mixed case, lowercase first" {
try testing.expect(!isogram.isIsogram("alphAbet"));
}
test "hypothetical isogrammic word with hyphen" {
try testing.expect(isogram.isIsogram("thumbscrew-japingly"));
}
test "hypothetical word with duplicated character following hyphen" {
try testing.expect(!isogram.isIsogram("thumbscrew-jappingly"));
}
test "isogram with duplicated hyphen" {
try testing.expect(isogram.isIsogram("six-year-old"));
}
test "made-up name that is an isogram" {
try testing.expect(isogram.isIsogram("Emily Jung Schwartzkopf"));
}
test "duplicated character in the middle" {
try testing.expect(!isogram.isIsogram("accentor"));
}
test "same first and last characters" {
try testing.expect(!isogram.isIsogram("angola"));
}
test "word with duplicated character and with two hyphens" {
try testing.expect(!isogram.isIsogram("up-to-date"));
}