add all-your-base exercise and canonical tests

This commit is contained in:
Hunter McMillen 2017-10-10 13:11:30 -04:00
parent b4c2346263
commit 8f59849a69
7 changed files with 3472 additions and 0 deletions

View file

@ -0,0 +1 @@
module AllYourBase exposing (..)

View file

@ -0,0 +1,68 @@
module AllYourBase exposing (..)
import List
fromBase : Int -> List Int -> Maybe Int
fromBase base =
let
f x m =
case m of
Nothing ->
Nothing
Just n ->
if x >= 0 && x < base then
Just (n * base + x)
else
Nothing
in
List.foldl f (Just 0)
toBase : Int -> Int -> List Int
toBase base =
let
divMod a b =
( a // b, a % b )
swap ( a, b ) =
( b, a )
unfold f b =
case f b of
Just ( a, b_ ) ->
a :: unfold f b_
Nothing ->
[]
f x =
case x of
0 ->
Nothing
_ ->
Just (swap (divMod x base))
in
List.reverse << (unfold f)
rebase : Int -> List Int -> Int -> Maybe (List Int)
rebase inBase digits outBase =
let
length =
List.length digits
numZeros =
List.length (List.filter (\x -> x == 0) digits)
in
if inBase < 2 || outBase < 2 || length == 0 || length == numZeros then
Nothing
else
case fromBase inBase digits of
Just v ->
Just (toBase outBase v)
Nothing ->
Nothing

View file

@ -0,0 +1,65 @@
# 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!*
## Elm Installation
Refer to the [Exercism help page](http://exercism.io/languages/elm) for Elm
installation and learning resources.
## Writing the Code
The first time you start an exercise, you'll need to ensure you have the
appropriate dependencies installed.
```bash
$ npm install
```
Execute the tests with:
```bash
$ npm test
```
Automatically run tests again when you save changes:
```bash
$ npm run watch
```
As you work your way through the test suite, be sure to remove the `skip <|`
calls from each test until you get them all passing!
## Submitting Incomplete Solutions
It's possible to submit an incomplete solution so you can see how others have completed the exercise.

View file

@ -0,0 +1,15 @@
{
"version": "1.0.0",
"summary": "helpful summary of your project, less than 80 characters",
"repository": "https://github.com/user/project.git",
"license": "BSD3",
"source-directories": [
"."
],
"exposed-modules": [],
"dependencies": {
"elm-lang/core": "5.1.1 <= v < 6.0.0",
"elm-lang/html": "2.0.0 <= v < 3.0.0"
},
"elm-version": "0.18.0 <= v < 0.19.0"
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,53 @@
module Tests exposing (..)
import Test exposing (..)
import Expect
import AllYourBase exposing (rebase)
tests : Test
tests =
describe "all-your-base"
[ test "single bit one to decimal" <|
\() -> Expect.equal (Just [ 1 ]) (rebase 2 [ 1 ] 10)
, test "binary to single decimal" <|
\() -> Expect.equal (Just [ 5 ]) (rebase 2 [ 1, 0, 1 ] 10)
, test "single decimal to binary" <|
\() -> Expect.equal (Just [ 1, 0, 1 ]) (rebase 10 [ 5 ] 2)
, test "binary to multiple decimal" <|
\() -> Expect.equal (Just [ 4, 2 ]) (rebase 2 [ 1, 0, 1, 0, 1, 0 ] 10)
, test "decimal to binary" <|
\() -> Expect.equal (Just [ 1, 0, 1, 0, 1, 0 ]) (rebase 10 [ 4, 2 ] 2)
, test "trinary to hexadecimal" <|
\() -> Expect.equal (Just [ 2, 10 ]) (rebase 3 [ 1, 1, 2, 0 ] 16)
, test "hexadecimal to trinary" <|
\() -> Expect.equal (Just [ 1, 1, 2, 0 ]) (rebase 16 [ 2, 10 ] 3)
, test "15-bit integer" <|
\() -> Expect.equal (Just [ 6, 10, 45 ]) (rebase 97 [ 3, 46, 60 ] 73)
, test "empty list" <|
\() -> Expect.equal Nothing (rebase 2 [] 10)
, test "single zero" <|
\() -> Expect.equal Nothing (rebase 10 [ 0 ] 2)
, test "multiple zeros" <|
\() -> Expect.equal Nothing (rebase 10 [ 0, 0, 0 ] 2)
, test "leading zeros" <|
\() -> Expect.equal (Just [ 4, 2 ]) (rebase 7 [ 0, 6, 0 ] 10)
, test "first base is one" <|
\() -> Expect.equal Nothing (rebase 1 [] 10)
, test "first base is zero" <|
\() -> Expect.equal Nothing (rebase 0 [] 10)
, test "first base is negative" <|
\() -> Expect.equal Nothing (rebase -1 [] 10)
, test "negative digit" <|
\() -> Expect.equal Nothing (rebase 2 [ 1, -1, 1, 0, 1, 0 ] 10)
, test "invalid positive digit" <|
\() -> Expect.equal Nothing (rebase 2 [ 1, 2, 1, 0, 1, 0 ] 10)
, test "second base is one" <|
\() -> Expect.equal Nothing (rebase 10 [] 1)
, test "second base is zero" <|
\() -> Expect.equal Nothing (rebase 10 [ 1 ] 0)
, test "second base is negative" <|
\() -> Expect.equal Nothing (rebase 10 [ 1 ] -1)
, test "both bases are negative" <|
\() -> Expect.equal Nothing (rebase -1 [ 1 ] -1)
]

View file

@ -0,0 +1,16 @@
{
"version": "3.0.0",
"summary": "Exercism problems in Elm.",
"repository": "https://github.com/exercism/elm.git",
"license": "BSD3",
"source-directories": [
".",
".."
],
"exposed-modules": [],
"dependencies": {
"elm-lang/core": "5.0.0 <= v < 6.0.0",
"elm-community/elm-test": "4.0.0 <= v < 5.0.0"
},
"elm-version": "0.18.0 <= v < 0.19.0"
}