Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

all-your-base: Add exercise, and deprecate binary #155

Merged
merged 1 commit into from
Feb 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,8 @@
]
},
{
"slug": "binary",
"uuid": "3acf148d-df9e-4897-8c9f-c17a3ba5e4b6",
"slug": "all-your-base",
"uuid": "c95b43a3-f702-473e-bdd5-aa6708ba1ce3",
"core": false,
"unlocked_by": null,
"difficulty": 1,
Expand Down Expand Up @@ -407,6 +407,15 @@
"events",
"reactive_programming"
]
},
{
"slug": "binary",
"uuid": "3acf148d-df9e-4897-8c9f-c17a3ba5e4b6",
"core": false,
"unlocked_by": null,
"difficulty": 0,
"topics": null,
"deprecated": true
}
]
}
58 changes: 58 additions & 0 deletions exercises/all-your-base/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# All Your Base

Convert a number, represented as a sequence of digits in one base, to any other base.

Implement general base conversion. Given a number in base **a**,
represented as a sequence of digits, convert it to base **b**.

## Note

- Try to implement the conversion yourself.
Do not use something else to perform the conversion for you.

## About [Positional Notation](https://en.wikipedia.org/wiki/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^1) + (2 * 10^0)

The number 101010, *in base 2*, means:

(1 * 2^5) + (0 * 2^4) + (1 * 2^3) + (0 * 2^2) + (1 * 2^1) + (0 * 2^0)

The number 1120, *in base 3*, means:

(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!*

## Running the tests

To compile and run the tests, just run the following in your exercise directory:
```bash
$ nim c -r all_your_base_test.nim
```

## Submitting Exercises

Note that, when trying to submit an exercise, make sure the solution is in the `$EXERCISM_WORKSPACE/nim/all-your-base` directory.

You can find your Exercism workspace by running `exercism debug` and looking for the line that starts with `Exercises Directory`.

## Need help?

These guides should help you,
* [Installing Nim](https://exercism.io/tracks/nim/installation)
* [Running the Tests](https://exercism.io/tracks/nim/tests)
* [Learning Nim](https://exercism.io/tracks/nim/learning)
* [Useful Nim Resources](https://exercism.io/tracks/nim/resources)


## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.
152 changes: 152 additions & 0 deletions exercises/all-your-base/all_your_base_test.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import unittest
import all_your_base

# version 2.3.0

suite "All Your Base":
test "single bit one to decimal":
let inputDigits = [1]
let inputBase = 2
let outputBase = 10
let outputDigits = @[1]
check convert(inputDigits, inputBase, outputBase) == outputDigits

test "binary to single decimal":
let inputDigits = [1, 0, 1]
let inputBase = 2
let outputBase = 10
let outputDigits = @[5]
check convert(inputDigits, inputBase, outputBase) == outputDigits

test "single decimal to binary":
let inputDigits = [5]
let inputBase = 10
let outputBase = 2
let outputDigits = @[1, 0, 1]
check convert(inputDigits, inputBase, outputBase) == outputDigits

test "binary to multiple decimal":
let inputDigits = [1, 0, 1, 0, 1, 0]
let inputBase = 2
let outputBase = 10
let outputDigits = @[4, 2]
check convert(inputDigits, inputBase, outputBase) == outputDigits

test "decimal to binary":
let inputDigits = [4, 2]
let inputBase = 10
let outputBase = 2
let outputDigits = @[1, 0, 1, 0, 1, 0]
check convert(inputDigits, inputBase, outputBase) == outputDigits

test "trinary to hexadecimal":
let inputDigits = [1, 1, 2, 0]
let inputBase = 3
let outputBase = 16
let outputDigits = @[2, 10]
check convert(inputDigits, inputBase, outputBase) == outputDigits

test "hexadecimal to trinary":
let inputDigits = [2, 10]
let inputBase = 16
let outputBase = 3
let outputDigits = @[1, 1, 2, 0]
check convert(inputDigits, inputBase, outputBase) == outputDigits

test "15-bit integer":
let inputDigits = [3, 46, 60]
let inputBase = 97
let outputBase = 73
let outputDigits = @[6, 10, 45]
check convert(inputDigits, inputBase, outputBase) == outputDigits

test "empty list":
let inputDigits: array[0, int] = []
let inputBase = 2
let outputBase = 10
let outputDigits = @[0]
check convert(inputDigits, inputBase, outputBase) == outputDigits

test "single zero":
let inputDigits = [0]
let inputBase = 10
let outputBase = 2
let outputDigits = @[0]
check convert(inputDigits, inputBase, outputBase) == outputDigits

test "multiple zeros":
let inputDigits = [0, 0, 0]
let inputBase = 10
let outputBase = 2
let outputDigits = @[0]
check convert(inputDigits, inputBase, outputBase) == outputDigits

test "leading zeros":
let inputDigits = [0, 6, 0]
let inputBase = 7
let outputBase = 10
let outputDigits = @[4, 2]
check convert(inputDigits, inputBase, outputBase) == outputDigits

test "input base is one":
let inputDigits = [0]
let inputBase = 1
let outputBase = 10
expect ValueError:
discard convert(inputDigits, inputBase, outputBase)

test "input base is zero":
let inputDigits: array[0, int] = []
let inputBase = 0
let outputBase = 10
expect ValueError:
discard convert(inputDigits, inputBase, outputBase)

test "input base is negative":
let inputDigits = [1]
let inputBase = -2
let outputBase = 10
expect ValueError:
discard convert(inputDigits, inputBase, outputBase)

test "negative digit":
let inputDigits = [1, -1, 1, 0, 1, 0]
let inputBase = 2
let outputBase = 10
expect ValueError:
discard convert(inputDigits, inputBase, outputBase)

test "invalid positive digit":
let inputDigits = [1, 2, 1, 0, 1, 0]
let inputBase = 2
let outputBase = 10
expect ValueError:
discard convert(inputDigits, inputBase, outputBase)

test "output base is one":
let inputDigits = [1, 0, 1, 0, 1, 0]
let inputBase = 2
let outputBase = 1
expect ValueError:
discard convert(inputDigits, inputBase, outputBase)

test "output base is zero":
let inputDigits = [7]
let inputBase = 10
let outputBase = 0
expect ValueError:
discard convert(inputDigits, inputBase, outputBase)

test "output base is negative":
let inputDigits = [1]
let inputBase = 2
let outputBase = -7
expect ValueError:
discard convert(inputDigits, inputBase, outputBase)

test "both bases are negative":
let inputDigits = [1]
let inputBase = -2
let outputBase = -7
expect ValueError:
discard convert(inputDigits, inputBase, outputBase)
23 changes: 23 additions & 0 deletions exercises/all-your-base/example.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import algorithm, math

func convert*(digits: openArray[int], fromBase: int, toBase: int): seq[int] =
if fromBase < 2:
raise newException(ValueError, "Invalid input base: " & $fromBase)
if toBase < 2:
raise newException(ValueError, "Invalid output base: " & $toBase)
for d in digits:
if d >= fromBase or d < 0:
raise newException(ValueError, "Invalid input digit: " & $d)

# Convert to base 10
var n: int
for i, d in digits:
n += d * fromBase^(digits.high - i)

# Convert base 10 to digits in the output base
if n == 0:
return @[0]
while n > 0:
result &= n mod toBase
n = n div toBase
result.reverse