diff --git a/config.json b/config.json index 0d7d920..cc21cff 100644 --- a/config.json +++ b/config.json @@ -730,6 +730,14 @@ "practices": [], "prerequisites": [], "difficulty": 5 + }, + { + "slug": "all-your-base", + "name": "All Your Base", + "uuid": "b3bfbbd9-a0f4-4cbf-848b-f889bb0241a0", + "practices": [], + "prerequisites": [], + "difficulty": 3 } ] }, 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..27e5880 --- /dev/null +++ b/exercises/practice/all-your-base/.meta/config.json @@ -0,0 +1,17 @@ +{ + "authors": [ + "glennj" + ], + "files": { + "solution": [ + "all-your-base.coffee" + ], + "test": [ + "all-your-base.spec.coffee" + ], + "example": [ + ".meta/example.coffee" + ] + }, + "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/example.coffee b/exercises/practice/all-your-base/.meta/example.coffee new file mode 100644 index 0000000..77b1475 --- /dev/null +++ b/exercises/practice/all-your-base/.meta/example.coffee @@ -0,0 +1,20 @@ +allYourBase = ({inputBase, outputBase, digits}) -> + throw new Error "input base must be >= 2" unless inputBase >= 2 + throw new Error "output base must be >= 2" unless outputBase >= 2 + + if digits.some ((d) => d < 0 or d >= inputBase) + throw new Error "all digits must satisfy 0 <= d < input base" + + decimal = digits.reduce ((dec, d) => dec * inputBase + d), 0 + + if decimal is 0 + [0] + else + outputDigits = [] + while decimal > 0 + outputDigits.unshift decimal % outputBase + decimal //= outputBase + outputDigits + + +module.exports = allYourBase 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/all-your-base.coffee b/exercises/practice/all-your-base/all-your-base.coffee new file mode 100644 index 0000000..2677273 --- /dev/null +++ b/exercises/practice/all-your-base/all-your-base.coffee @@ -0,0 +1,3 @@ +allYourBase = (args) -> + +module.exports = allYourBase diff --git a/exercises/practice/all-your-base/all-your-base.spec.coffee b/exercises/practice/all-your-base/all-your-base.spec.coffee new file mode 100644 index 0000000..8841b4a --- /dev/null +++ b/exercises/practice/all-your-base/all-your-base.spec.coffee @@ -0,0 +1,191 @@ +allYourBase = require './all-your-base' + +describe "AllYourBase", -> + it "single bit one to decimal", -> + actual = allYourBase { + inputBase: 2, + outputBase: 10, + digits: [1] + } + expected = [1] + expect(actual).toEqual expected + + xit "binary to single decimal", -> + actual = allYourBase { + inputBase: 2, + outputBase: 10, + digits: [1, 0, 1] + } + expected = [5] + expect(actual).toEqual expected + + xit "single decimal to binary", -> + actual = allYourBase { + inputBase: 10, + outputBase: 2, + digits: [5] + } + expected = [1, 0, 1] + expect(actual).toEqual expected + + xit "binary to multiple decimal", -> + actual = allYourBase { + inputBase: 2, + outputBase: 10, + digits: [1, 0, 1, 0, 1, 0] + } + expected = [4, 2] + expect(actual).toEqual expected + + xit "decimal to binary", -> + actual = allYourBase { + inputBase: 10, + outputBase: 2, + digits: [4, 2] + } + expected = [1, 0, 1, 0, 1, 0] + expect(actual).toEqual expected + + xit "trinary to hexadecimal", -> + actual = allYourBase { + inputBase: 3, + outputBase: 16, + digits: [1, 1, 2, 0] + } + expected = [2, 10] + expect(actual).toEqual expected + + xit "hexadecimal to trinary", -> + actual = allYourBase { + inputBase: 16, + outputBase: 3, + digits: [2, 10] + } + expected = [1, 1, 2, 0] + expect(actual).toEqual expected + + xit "15-bit integer", -> + actual = allYourBase { + inputBase: 97, + outputBase: 73, + digits: [3, 46, 60] + } + expected = [6, 10, 45] + expect(actual).toEqual expected + + xit "empty list", -> + actual = allYourBase { + inputBase: 2, + outputBase: 10, + digits: [] + } + expected = [0] + expect(actual).toEqual expected + + xit "single zero", -> + actual = allYourBase { + inputBase: 10, + outputBase: 2, + digits: [0] + } + expected = [0] + expect(actual).toEqual expected + + xit "multiple zeros", -> + actual = allYourBase { + inputBase: 10, + outputBase: 2, + digits: [0, 0, 0] + } + expected = [0] + expect(actual).toEqual expected + + xit "leading zeros", -> + actual = allYourBase { + inputBase: 7, + outputBase: 10, + digits: [0, 6, 0] + } + expected = [4, 2] + expect(actual).toEqual expected + + xit "input base is one", -> + expect -> + allYourBase { + inputBase: 1, + outputBase: 10, + digits: [0] + } + .toThrow new Error "input base must be >= 2" + + xit "input base is zero", -> + expect -> + allYourBase { + inputBase: 0, + outputBase: 10, + digits: [] + } + .toThrow new Error "input base must be >= 2" + + xit "input base is negative", -> + expect -> + allYourBase { + inputBase: -2, + outputBase: 10, + digits: [0] + } + .toThrow new Error "input base must be >= 2" + + xit "negative digit", -> + expect -> + allYourBase { + inputBase: 2, + outputBase: 10, + digits: [1, -1, 1, 0, 1, 0] + } + .toThrow new Error "all digits must satisfy 0 <= d < input base" + + xit "invalid positive digit", -> + expect -> + allYourBase { + inputBase: 2, + outputBase: 10, + digits: [1, 2, 1, 0, 1, 0] + } + .toThrow new Error "all digits must satisfy 0 <= d < input base" + + xit "output base is one", -> + expect -> + allYourBase { + inputBase: 2, + outputBase: 1, + digits: [1, 0, 1, 0, 1, 0] + } + .toThrow new Error "output base must be >= 2" + + xit "output base is zero", -> + expect -> + allYourBase { + inputBase: 10, + outputBase: 0, + digits: [7] + } + .toThrow new Error "output base must be >= 2" + + xit "output base is negative", -> + expect -> + allYourBase { + inputBase: 2, + outputBase: -7, + digits: [1] + } + .toThrow new Error "output base must be >= 2" + + xit "both bases are negative", -> + expect -> + allYourBase { + inputBase: -2, + outputBase: -7, + digits: [1] + } + .toThrow new Error "input base must be >= 2"