From 3f28e82a4ef81f864daab7aa6d55a9c3f7559ea0 Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Sat, 3 Aug 2024 18:19:52 -0400 Subject: [PATCH] Zig: completed Collatz Conjecture and Isogram --- zig/collatz-conjecture/.exercism/config.json | 22 ++++++ .../.exercism/metadata.json | 1 + zig/collatz-conjecture/HELP.md | 53 +++++++++++++++ zig/collatz-conjecture/README.md | 67 +++++++++++++++++++ zig/collatz-conjecture/collatz_conjecture.zig | 19 ++++++ .../test_collatz_conjecture.zig | 35 ++++++++++ zig/isogram/.exercism/config.json | 19 ++++++ zig/isogram/.exercism/metadata.json | 1 + zig/isogram/HELP.md | 53 +++++++++++++++ zig/isogram/README.md | 29 ++++++++ zig/isogram/isogram.zig | 26 +++++++ zig/isogram/test_isogram.zig | 60 +++++++++++++++++ 12 files changed, 385 insertions(+) create mode 100644 zig/collatz-conjecture/.exercism/config.json create mode 100644 zig/collatz-conjecture/.exercism/metadata.json create mode 100644 zig/collatz-conjecture/HELP.md create mode 100644 zig/collatz-conjecture/README.md create mode 100644 zig/collatz-conjecture/collatz_conjecture.zig create mode 100644 zig/collatz-conjecture/test_collatz_conjecture.zig create mode 100644 zig/isogram/.exercism/config.json create mode 100644 zig/isogram/.exercism/metadata.json create mode 100644 zig/isogram/HELP.md create mode 100644 zig/isogram/README.md create mode 100644 zig/isogram/isogram.zig create mode 100644 zig/isogram/test_isogram.zig diff --git a/zig/collatz-conjecture/.exercism/config.json b/zig/collatz-conjecture/.exercism/config.json new file mode 100644 index 0000000..442e62e --- /dev/null +++ b/zig/collatz-conjecture/.exercism/config.json @@ -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" +} diff --git a/zig/collatz-conjecture/.exercism/metadata.json b/zig/collatz-conjecture/.exercism/metadata.json new file mode 100644 index 0000000..54967bb --- /dev/null +++ b/zig/collatz-conjecture/.exercism/metadata.json @@ -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} \ No newline at end of file diff --git a/zig/collatz-conjecture/HELP.md b/zig/collatz-conjecture/HELP.md new file mode 100644 index 0000000..d024922 --- /dev/null +++ b/zig/collatz-conjecture/HELP.md @@ -0,0 +1,53 @@ +# Help + +## Running the tests + +Write your code in `.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 \ No newline at end of file diff --git a/zig/collatz-conjecture/README.md b/zig/collatz-conjecture/README.md new file mode 100644 index 0000000..a0409d6 --- /dev/null +++ b/zig/collatz-conjecture/README.md @@ -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 \ No newline at end of file diff --git a/zig/collatz-conjecture/collatz_conjecture.zig b/zig/collatz-conjecture/collatz_conjecture.zig new file mode 100644 index 0000000..7c254a0 --- /dev/null +++ b/zig/collatz-conjecture/collatz_conjecture.zig @@ -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; +} diff --git a/zig/collatz-conjecture/test_collatz_conjecture.zig b/zig/collatz-conjecture/test_collatz_conjecture.zig new file mode 100644 index 0000000..d87b5ba --- /dev/null +++ b/zig/collatz-conjecture/test_collatz_conjecture.zig @@ -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); +} diff --git a/zig/isogram/.exercism/config.json b/zig/isogram/.exercism/config.json new file mode 100644 index 0000000..736872c --- /dev/null +++ b/zig/isogram/.exercism/config.json @@ -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" +} diff --git a/zig/isogram/.exercism/metadata.json b/zig/isogram/.exercism/metadata.json new file mode 100644 index 0000000..9edf7aa --- /dev/null +++ b/zig/isogram/.exercism/metadata.json @@ -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} \ No newline at end of file diff --git a/zig/isogram/HELP.md b/zig/isogram/HELP.md new file mode 100644 index 0000000..d614c70 --- /dev/null +++ b/zig/isogram/HELP.md @@ -0,0 +1,53 @@ +# Help + +## Running the tests + +Write your code in `.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 \ No newline at end of file diff --git a/zig/isogram/README.md b/zig/isogram/README.md new file mode 100644 index 0000000..06834b7 --- /dev/null +++ b/zig/isogram/README.md @@ -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 \ No newline at end of file diff --git a/zig/isogram/isogram.zig b/zig/isogram/isogram.zig new file mode 100644 index 0000000..b740b67 --- /dev/null +++ b/zig/isogram/isogram.zig @@ -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; +} diff --git a/zig/isogram/test_isogram.zig b/zig/isogram/test_isogram.zig new file mode 100644 index 0000000..8f7c219 --- /dev/null +++ b/zig/isogram/test_isogram.zig @@ -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")); +}