diff --git a/config.json b/config.json index c0ab45b..e9c5dac 100644 --- a/config.json +++ b/config.json @@ -478,6 +478,14 @@ "string_manipulation" ] }, + { + "slug": "all-your-base", + "name": "All Your Base", + "uuid": "9c1ca27b-5dd6-4169-b56a-91400d62b8ca", + "practices": [], + "prerequisites": [], + "difficulty": 4 + }, { "slug": "atbash-cipher", "name": "Atbash Cipher", diff --git a/exercises/practice/all-your-base/.docs/instructions.md b/exercises/practice/all-your-base/.docs/instructions.md new file mode 100644 index 0000000..1b688b6 --- /dev/null +++ b/exercises/practice/all-your-base/.docs/instructions.md @@ -0,0 +1,28 @@ +# Instructions + +Convert a sequence of digits in one base, representing a number, into a sequence of digits in another base, representing the same number. + +~~~~exercism/note +Try to implement the conversion yourself. +Do not use something else to perform the conversion for you. +~~~~ + +## About [Positional Notation][positional-notation] + +In positional notation, a number in base **b** can be understood as a linear combination of powers of **b**. + +The number 42, _in base 10_, means: + +`(4 × 10¹) + (2 × 10⁰)` + +The number 101010, _in base 2_, means: + +`(1 × 2⁵) + (0 × 2⁴) + (1 × 2³) + (0 × 2²) + (1 × 2¹) + (0 × 2⁰)` + +The number 1120, _in base 3_, means: + +`(1 × 3³) + (1 × 3²) + (2 × 3¹) + (0 × 3⁰)` + +_Yes. Those three numbers above are exactly the same. Congratulations!_ + +[positional-notation]: https://en.wikipedia.org/wiki/Positional_notation diff --git a/exercises/practice/all-your-base/.docs/introduction.md b/exercises/practice/all-your-base/.docs/introduction.md new file mode 100644 index 0000000..68aaffb --- /dev/null +++ b/exercises/practice/all-your-base/.docs/introduction.md @@ -0,0 +1,8 @@ +# Introduction + +You've just been hired as professor of mathematics. +Your first week went well, but something is off in your second week. +The problem is that every answer given by your students is wrong! +Luckily, your math skills have allowed you to identify the problem: the student answers _are_ correct, but they're all in base 2 (binary)! +Amazingly, it turns out that each week, the students use a different base. +To help you quickly verify the student answers, you'll be building a tool to translate between bases. diff --git a/exercises/practice/all-your-base/.meta/config.json b/exercises/practice/all-your-base/.meta/config.json new file mode 100644 index 0000000..9c640a9 --- /dev/null +++ b/exercises/practice/all-your-base/.meta/config.json @@ -0,0 +1,17 @@ +{ + "authors": [ + "keiravillekode" + ], + "files": { + "solution": [ + "source/all_your_base.d" + ], + "test": [ + "source/all_your_base.d" + ], + "example": [ + "example/all_your_base.d" + ] + }, + "blurb": "Convert a number, represented as a sequence of digits in one base, to any other base." +} diff --git a/exercises/practice/all-your-base/.meta/tests.toml b/exercises/practice/all-your-base/.meta/tests.toml new file mode 100644 index 0000000..8968c13 --- /dev/null +++ b/exercises/practice/all-your-base/.meta/tests.toml @@ -0,0 +1,73 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[5ce422f9-7a4b-4f44-ad29-49c67cb32d2c] +description = "single bit one to decimal" + +[0cc3fea8-bb79-46ac-a2ab-5a2c93051033] +description = "binary to single decimal" + +[f12db0f9-0d3d-42c2-b3ba-e38cb375a2b8] +description = "single decimal to binary" + +[2c45cf54-6da3-4748-9733-5a3c765d925b] +description = "binary to multiple decimal" + +[65ddb8b4-8899-4fcc-8618-181b2cf0002d] +description = "decimal to binary" + +[8d418419-02a7-4824-8b7a-352d33c6987e] +description = "trinary to hexadecimal" + +[d3901c80-8190-41b9-bd86-38d988efa956] +description = "hexadecimal to trinary" + +[5d42f85e-21ad-41bd-b9be-a3e8e4258bbf] +description = "15-bit integer" + +[d68788f7-66dd-43f8-a543-f15b6d233f83] +description = "empty list" + +[5e27e8da-5862-4c5f-b2a9-26c0382b6be7] +description = "single zero" + +[2e1c2573-77e4-4b9c-8517-6c56c5bcfdf2] +description = "multiple zeros" + +[3530cd9f-8d6d-43f5-bc6e-b30b1db9629b] +description = "leading zeros" + +[a6b476a1-1901-4f2a-92c4-4d91917ae023] +description = "input base is one" + +[e21a693a-7a69-450b-b393-27415c26a016] +description = "input base is zero" + +[54a23be5-d99e-41cc-88e0-a650ffe5fcc2] +description = "input base is negative" + +[9eccf60c-dcc9-407b-95d8-c37b8be56bb6] +description = "negative digit" + +[232fa4a5-e761-4939-ba0c-ed046cd0676a] +description = "invalid positive digit" + +[14238f95-45da-41dc-95ce-18f860b30ad3] +description = "output base is one" + +[73dac367-da5c-4a37-95fe-c87fad0a4047] +description = "output base is zero" + +[13f81f42-ff53-4e24-89d9-37603a48ebd9] +description = "output base is negative" + +[0e6c895d-8a5d-4868-a345-309d094cfe8d] +description = "both bases are negative" diff --git a/exercises/practice/all-your-base/dub.sdl b/exercises/practice/all-your-base/dub.sdl new file mode 100644 index 0000000..9b599c9 --- /dev/null +++ b/exercises/practice/all-your-base/dub.sdl @@ -0,0 +1,2 @@ +name "all-your-base" +buildRequirements "disallowDeprecations" diff --git a/exercises/practice/all-your-base/example/all_your_base.d b/exercises/practice/all-your-base/example/all_your_base.d new file mode 100644 index 0000000..2dca480 --- /dev/null +++ b/exercises/practice/all-your-base/example/all_your_base.d @@ -0,0 +1,33 @@ +module all_your_base; + +import std.algorithm.mutation : reverse; + +pure int[] rebase(int inputBase, immutable int[] digits, int outputBase) +{ + if (inputBase < 2) + { + throw new Exception("input base must be >= 2"); + } + if (outputBase < 2) + { + throw new Exception("output base must be >= 2"); + } + + int number = 0; + foreach(digit; digits) + { + if (digit < 0 || digit >= inputBase) + { + throw new Exception("all digits must satisfy 0 <= d < input base"); + } + number = number * inputBase + digit; + } + + int [] result; + do + { + result ~= number % outputBase; + number /= outputBase; + } while (number != 0); + return result.reverse; +} diff --git a/exercises/practice/all-your-base/source/all_your_base.d b/exercises/practice/all-your-base/source/all_your_base.d new file mode 100644 index 0000000..9ceb73b --- /dev/null +++ b/exercises/practice/all-your-base/source/all_your_base.d @@ -0,0 +1,266 @@ +module all_your_base; + +pure int[] rebase(int inputBase, immutable int[] digits, int outputBase) +{ + // implement this function +} + +unittest +{ + import std.exception : assertThrown; + + immutable int allTestsEnabled = 0; + + // Single bit one to decimal + { + immutable int[] digits = [ + 1, + ]; + int[] expected = [ + 1, + ]; + assert(rebase(2, digits, 10) == expected); + } + + static if (allTestsEnabled) + { + // Binary to single decimal + { + immutable int[] digits = [ + 1, + 0, + 1, + ]; + int[] expected = [ + 5, + ]; + assert(rebase(2, digits, 10) == expected); + } + + // Single decimal to binary + { + immutable int[] digits = [ + 5, + ]; + int[] expected = [ + 1, + 0, + 1, + ]; + assert(rebase(10, digits, 2) == expected); + } + + // Binary to multiple decimal + { + immutable int[] digits = [ + 1, + 0, + 1, + 0, + 1, + 0, + ]; + int[] expected = [ + 4, + 2, + ]; + assert(rebase(2, digits, 10) == expected); + } + + // Decimal to binary + { + immutable int[] digits = [ + 4, + 2, + ]; + int[] expected = [ + 1, + 0, + 1, + 0, + 1, + 0, + ]; + assert(rebase(10, digits, 2) == expected); + } + + // Trinary to hexadecimal + { + immutable int[] digits = [ + 1, + 1, + 2, + 0, + ]; + int[] expected = [ + 2, + 10, + ]; + assert(rebase(3, digits, 16) == expected); + } + + // Hexadecimal to trinary + { + immutable int[] digits = [ + 2, + 10, + ]; + int[] expected = [ + 1, + 1, + 2, + 0, + ]; + assert(rebase(16, digits, 3) == expected); + } + + // 15-bit integer + { + immutable int[] digits = [ + 3, + 46, + 60, + ]; + int[] expected = [ + 6, + 10, + 45, + ]; + assert(rebase(97, digits, 73) == expected); + } + + // Empty list + { + immutable int[] digits = [ + ]; + int[] expected = [ + 0, + ]; + assert(rebase(2, digits, 10) == expected); + } + + // Single zero + { + immutable int[] digits = [ + 0, + ]; + int[] expected = [ + 0, + ]; + assert(rebase(10, digits, 2) == expected); + } + + // Multiple zeros + { + immutable int[] digits = [ + 0, + 0, + 0, + ]; + int[] expected = [ + 0, + ]; + assert(rebase(10, digits, 2) == expected); + } + + // Leading zeros + { + immutable int[] digits = [ + 0, + 6, + 0, + ]; + int[] expected = [ + 4, + 2, + ]; + assert(rebase(7, digits, 10) == expected); + } + + // Input base is one + { + immutable int[] digits = [ + 0, + ]; + assertThrown(rebase(1, digits, 10)); + } + + // Input base is zero + { + immutable int[] digits = [ + ]; + assertThrown(rebase(0, digits, 10)); + } + + // Input base is negative + { + immutable int[] digits = [ + 1, + ]; + assertThrown(rebase(-2, digits, 10)); + } + + // Negative digit + { + immutable int[] digits = [ + 1, + -1, + 1, + 0, + 1, + 0, + ]; + assertThrown(rebase(2, digits, 10)); + } + + // Invalid positive digit + { + immutable int[] digits = [ + 1, + 2, + 1, + 0, + 1, + 0, + ]; + assertThrown(rebase(2, digits, 10)); + } + + // Output base is one + { + immutable int[] digits = [ + 1, + 0, + 1, + 0, + 1, + 0, + ]; + assertThrown(rebase(2, digits, 1)); + } + + // Output base is zero + { + immutable int[] digits = [ + 7, + ]; + assertThrown(rebase(10, digits, 0)); + } + + // Output base is negative + { + immutable int[] digits = [ + 1, + ]; + assertThrown(rebase(2, digits, -7)); + } + + // Both bases are negative + { + immutable int[] digits = [ + 1, + ]; + assertThrown(rebase(-2, digits, -7)); + } + } +}