-
-
Notifications
You must be signed in to change notification settings - Fork 138
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
160 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,28 @@ | ||
# Instructions | ||
|
||
Convert a number, represented as a sequence of digits in one base, to any other base. | ||
Convert a sequence of digits in one base, representing a number, into a sequence of digits in another base, representing the same number. | ||
|
||
Implement general base conversion. Given a number in base **a**, | ||
represented as a sequence of digits, convert it to base **b**. | ||
~~~~exercism/note | ||
Try to implement the conversion yourself. | ||
Do not use something else to perform the conversion for you. | ||
~~~~ | ||
|
||
## Note | ||
## About [Positional Notation][positional-notation] | ||
|
||
- Try to implement the conversion yourself. | ||
Do not use something else to perform the conversion for you. | ||
In positional notation, a number in base **b** can be understood as a linear combination of powers of **b**. | ||
|
||
## About [Positional Notation](https://en.wikipedia.org/wiki/Positional_notation) | ||
The number 42, _in base 10_, means: | ||
|
||
In positional notation, a number in base **b** can be understood as a linear | ||
combination of powers of **b**. | ||
`(4 × 10¹) + (2 × 10⁰)` | ||
|
||
The number 42, *in base 10*, means: | ||
The number 101010, _in base 2_, means: | ||
|
||
(4 * 10^1) + (2 * 10^0) | ||
`(1 × 2⁵) + (0 × 2⁴) + (1 × 2³) + (0 × 2²) + (1 × 2¹) + (0 × 2⁰)` | ||
|
||
The number 101010, *in base 2*, means: | ||
The number 1120, _in base 3_, means: | ||
|
||
(1 * 2^5) + (0 * 2^4) + (1 * 2^3) + (0 * 2^2) + (1 * 2^1) + (0 * 2^0) | ||
`(1 × 3³) + (1 × 3²) + (2 × 3¹) + (0 × 3⁰)` | ||
|
||
The number 1120, *in base 3*, means: | ||
_Yes. Those three numbers above are exactly the same. Congratulations!_ | ||
|
||
(1 * 3^3) + (1 * 3^2) + (2 * 3^1) + (0 * 3^0) | ||
|
||
I think you got the idea! | ||
|
||
*Yes. Those three numbers above are exactly the same. Congratulations!* | ||
[positional-notation]: https://en.wikipedia.org/wiki/Positional_notation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,142 +1,226 @@ | ||
<?php | ||
|
||
/* | ||
* By adding type hints and enabling strict type checking, code can become | ||
* easier to read, self-documenting and reduce the number of potential bugs. | ||
* By default, type declarations are non-strict, which means they will attempt | ||
* to change the original type to match the type specified by the | ||
* type-declaration. | ||
* | ||
* In other words, if you pass a string to a function requiring a float, | ||
* it will attempt to convert the string value to a float. | ||
* | ||
* To enable strict mode, a single declare directive must be placed at the top | ||
* of the file. | ||
* This means that the strictness of typing is configured on a per-file basis. | ||
* This directive not only affects the type declarations of parameters, but also | ||
* a function's return type. | ||
* | ||
* For more info review the Concept on strict type checking in the PHP track | ||
* <link>. | ||
* | ||
* To disable strict typing, comment out the directive below. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
/** | ||
* These tests are adapted from the canonical data in the | ||
* `problem-specifications` repository. | ||
*/ | ||
class AllYourBaseTest extends PHPUnit\Framework\TestCase | ||
{ | ||
public static function setUpBeforeClass(): void | ||
{ | ||
require_once 'AllYourBase.php'; | ||
} | ||
|
||
/** | ||
* uuid 5ce422f9-7a4b-4f44-ad29-49c67cb32d2c | ||
* @testdox Single bit one to decimal | ||
*/ | ||
public function testSingleBitOneToDecimal(): void | ||
{ | ||
$this->assertEquals([1], rebase(2, [1], 10)); | ||
} | ||
|
||
/** | ||
* uuid 0cc3fea8-bb79-46ac-a2ab-5a2c93051033 | ||
* @testdox Binary to single decimal | ||
*/ | ||
public function testBinaryToSingleDecimal(): void | ||
{ | ||
$this->assertEquals([5], rebase(2, [1, 0, 1], 10)); | ||
} | ||
|
||
/** | ||
* uuid f12db0f9-0d3d-42c2-b3ba-e38cb375a2b8 | ||
* @testdox Single decimal to binary | ||
*/ | ||
public function testSingleDecimalToBinary(): void | ||
{ | ||
$this->assertEquals([1, 0, 1], rebase(10, [5], 2)); | ||
} | ||
|
||
/** | ||
* uuid 2c45cf54-6da3-4748-9733-5a3c765d925b | ||
* @testdox Binary to multiple decimal | ||
*/ | ||
public function testBinaryToMultipleDecimal(): void | ||
{ | ||
$this->assertEquals([4, 2], rebase(2, [1, 0, 1, 0, 1, 0], 10)); | ||
} | ||
|
||
/** | ||
* uuid 65ddb8b4-8899-4fcc-8618-181b2cf0002d | ||
* @testdox Decimal to binary | ||
*/ | ||
public function testDecimalToBinary(): void | ||
{ | ||
$this->assertEquals([1, 0, 1, 0, 1, 0], rebase(10, [4, 2], 2)); | ||
} | ||
|
||
/** | ||
* uuid 8d418419-02a7-4824-8b7a-352d33c6987e | ||
* @testdox Trinary to hexadecimal | ||
*/ | ||
public function testTrinaryToHexadecimal(): void | ||
{ | ||
$this->assertEquals([2, 10], rebase(3, [1, 1, 2, 0], 16)); | ||
} | ||
|
||
/** | ||
* uuid d3901c80-8190-41b9-bd86-38d988efa956 | ||
* @testdox Hexadecimal to trinary | ||
*/ | ||
public function testHexadecimalToTrinary(): void | ||
{ | ||
$this->assertEquals([1, 1, 2, 0], rebase(16, [2, 10], 3)); | ||
} | ||
|
||
/** | ||
* uuid 5d42f85e-21ad-41bd-b9be-a3e8e4258bbf | ||
* @testdox 15-bit integer | ||
*/ | ||
public function test15BitIntegers(): void | ||
{ | ||
$this->assertEquals([6, 10, 45], rebase(97, [3, 46, 60], 73)); | ||
} | ||
|
||
public function testEmptyListReturnsNull(): void | ||
/** | ||
* uuid d68788f7-66dd-43f8-a543-f15b6d233f83 | ||
* @testdox Empty list | ||
*/ | ||
public function testEmptyList(): void | ||
{ | ||
$this->assertEquals(null, rebase(10, [], 10)); | ||
$this->assertEquals([0], rebase(2, [], 10)); | ||
} | ||
|
||
public function testSingleZeroReturnsNull(): void | ||
/** | ||
* uuid 5e27e8da-5862-4c5f-b2a9-26c0382b6be7 | ||
* @testdox Single zero | ||
*/ | ||
public function testSingleZero(): void | ||
{ | ||
$this->assertEquals(null, rebase(10, [0], 2)); | ||
$this->assertEquals([0], rebase(10, [0], 2)); | ||
} | ||
|
||
public function testMultipleZerosReturnsNull(): void | ||
/** | ||
* uuid 2e1c2573-77e4-4b9c-8517-6c56c5bcfdf2 | ||
* @testdox Multiple zeros | ||
*/ | ||
public function testMultipleZeros(): void | ||
{ | ||
$this->assertEquals(null, rebase(10, [0, 0, 0], 2)); | ||
$this->assertEquals([0], rebase(10, [0, 0, 0], 2)); | ||
} | ||
|
||
public function testLeadingZerosReturnsNull(): void | ||
/** | ||
* uuid 3530cd9f-8d6d-43f5-bc6e-b30b1db9629b | ||
* @testdox Leading zeros | ||
*/ | ||
public function testLeadingZeros(): void | ||
{ | ||
$this->assertEquals(null, rebase(10, [0, 6, 0], 2)); | ||
$this->assertEquals([4, 2], rebase(7, [0, 6, 0], 10)); | ||
} | ||
|
||
/** | ||
* uuid a6b476a1-1901-4f2a-92c4-4d91917ae023 | ||
* @testdox Input base is one | ||
*/ | ||
public function testFirstBaseIsOne(): void | ||
{ | ||
$this->assertEquals(null, rebase(1, [6, 0], 2)); | ||
$this->expectException(InvalidArgumentException::class); | ||
$this->expectExceptionMessage('input base must be >= 2'); | ||
|
||
rebase(1, [0], 10); | ||
} | ||
|
||
/** | ||
* uuid e21a693a-7a69-450b-b393-27415c26a016 | ||
* @testdox Input base is zero | ||
*/ | ||
public function testFirstBaseIsZero(): void | ||
{ | ||
$this->assertEquals(null, rebase(0, [6, 0], 2)); | ||
$this->expectException(InvalidArgumentException::class); | ||
$this->expectExceptionMessage('input base must be >= 2'); | ||
|
||
rebase(0, [], 10); | ||
} | ||
|
||
/** | ||
* uuid 54a23be5-d99e-41cc-88e0-a650ffe5fcc2 | ||
* @testdox Input base is negative | ||
*/ | ||
public function testFirstBaseIsNegative(): void | ||
{ | ||
$this->assertEquals(null, rebase(-1, [6, 0], 2)); | ||
$this->expectException(InvalidArgumentException::class); | ||
$this->expectExceptionMessage('input base must be >= 2'); | ||
|
||
rebase(-2, [1], 10); | ||
} | ||
|
||
/** | ||
* uuid 9eccf60c-dcc9-407b-95d8-c37b8be56bb6 | ||
* @testdox Negative digit | ||
*/ | ||
public function testNegativeDigit(): void | ||
{ | ||
$this->assertEquals(null, rebase(10, [1, -1, 0], 2)); | ||
$this->expectException(InvalidArgumentException::class); | ||
$this->expectExceptionMessage('all digits must satisfy 0 <= d < input base'); | ||
|
||
rebase(2, [1, -1, 1, 0, 1, 0], 10); | ||
} | ||
|
||
/** | ||
* uuid 232fa4a5-e761-4939-ba0c-ed046cd0676a | ||
* @testdox Invalid positive digit | ||
*/ | ||
public function testInvalidPositiveDigit(): void | ||
{ | ||
$this->assertEquals(null, rebase(2, [1, 2, 0], 10)); | ||
$this->expectException(InvalidArgumentException::class); | ||
$this->expectExceptionMessage('all digits must satisfy 0 <= d < input base'); | ||
|
||
rebase(2, [1, 2, 1, 0, 1, 0], 10); | ||
} | ||
|
||
/** | ||
* uuid 14238f95-45da-41dc-95ce-18f860b30ad3 | ||
* @testdox Output base is one | ||
*/ | ||
public function testSecondBaseIsOne(): void | ||
{ | ||
$this->assertEquals(null, rebase(2, [1, 1, 0], 1)); | ||
$this->expectException(InvalidArgumentException::class); | ||
$this->expectExceptionMessage('output base must be >= 2'); | ||
|
||
rebase(2, [1, 0, 1, 0, 1, 0], 1); | ||
} | ||
|
||
/** | ||
* uuid 73dac367-da5c-4a37-95fe-c87fad0a4047 | ||
* @testdox Output base is zero | ||
*/ | ||
public function testSecondBaseIsZero(): void | ||
{ | ||
$this->assertEquals(null, rebase(2, [1, 1, 0], 0)); | ||
$this->expectException(InvalidArgumentException::class); | ||
$this->expectExceptionMessage('output base must be >= 2'); | ||
|
||
rebase(10, [7], 0); | ||
} | ||
|
||
/** | ||
* uuid 13f81f42-ff53-4e24-89d9-37603a48ebd9 | ||
* @testdox Output base is negative | ||
*/ | ||
public function testSecondBaseIsNegative(): void | ||
{ | ||
$this->assertEquals(null, rebase(2, [1, 1, 0], -1)); | ||
$this->expectException(InvalidArgumentException::class); | ||
$this->expectExceptionMessage('output base must be >= 2'); | ||
|
||
rebase(2, [1], -7); | ||
} | ||
|
||
/** | ||
* uuid 0e6c895d-8a5d-4868-a345-309d094cfe8d | ||
* @testdox Both bases are negative | ||
*/ | ||
public function testBothBasesIsNegative(): void | ||
{ | ||
$this->assertEquals(null, rebase(-3, [1, 1, 0], -1)); | ||
$this->expectException(InvalidArgumentException::class); | ||
|
||
rebase(-2, [1], -7); | ||
} | ||
} |