π Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io π

# tex's solution

## to All Your Base in the PureScript Track

Published at Apr 08 2020 · 0 comments
Instructions
Test suite
Solution

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.

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!

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### Main.purs

``````module Test.Main where

import Prelude

import Effect (Effect)
import Data.Maybe (Maybe(..))
import Test.Unit.Assert as Assert
import Test.Unit (TestSuite, suite, test)
import Test.Unit.Main (runTest)
import AllYourBase (rebase)

main :: Effect Unit
main = runTest suites

suites :: TestSuite
suites = do
suite "AllYourBase.rebase" do

test "single bit one to decimal" \$
Assert.equal (Just [1])
(rebase 2 10 [1])

test "binary to single decimal" \$
Assert.equal (Just [5])
(rebase 2 10 [1,0,1])

test "single decimal to binary" \$
Assert.equal (Just [1,0,1])
(rebase 10 2 [5])

test "binary to multiple decimal" \$
Assert.equal (Just [4,2])
(rebase 2 10 [1,0,1,0,1,0])

test "decimal to binary" \$
Assert.equal (Just [1,0,1,0,1,0])
(rebase 10 2 [4,2])

Assert.equal (Just [2,10])
(rebase 3 16 [1,1,2,0])

Assert.equal (Just [1,1,2,0])
(rebase 16 3 [2,10])

test "15-bit integer" \$
Assert.equal (Just [6,10,45])
(rebase 97 73 [3,46,60])

test "empty list" \$
Assert.equal Nothing
(rebase 2 10 [])

test "single zero" \$
Assert.equal Nothing
(rebase 10 2 [0])

test "multiple zeros" \$
Assert.equal Nothing
(rebase 10 2 [0,0,0])

Assert.equal Nothing
(rebase 7 10 [0,6,0])

test "negative digit" \$
Assert.equal Nothing
(rebase 2 10 [1,-1,1,0,1,0])

test "invalid positive digit" \$
Assert.equal Nothing
(rebase 2 10 [1,2,1,0,1,0])

test "first base is one" \$
Assert.equal Nothing
(rebase 1 10 [])

test "second base is one" \$
Assert.equal Nothing
(rebase 2 1 [1,0,1,0,1,0])

test "first base is zero" \$
Assert.equal Nothing
(rebase 0 10 [])

test "second base is zero" \$
Assert.equal Nothing
(rebase 10 0 [7])

test "first base is negative" \$
Assert.equal Nothing
(rebase (-2) 10 [1])

test "second base is negative" \$
Assert.equal Nothing
(rebase 2 (-7) [1])

test "both bases are negative" \$
Assert.equal Nothing
(rebase (-2) (-7) [1])``````
``````module AllYourBase
( rebase
) where

import Prelude

import Data.Array ((:), all, foldl, head, mapWithIndex, reverse, snoc)
import Data.Foldable (sum)
import Data.Int (pow)
import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..), fst)

between' β· Int β Int β Int β Boolean
between' x y = between (x + 1) (y - 1)

rebase β· Int β Int β Array Int β Maybe (Array Int)
rebase fb tb ds
= if fb > 1 && tb > 1 && head ds > Just 0 && all (between' (-1) fb) ds
then Just \$ fst \$ foldl go (Tuple [] intVal) (getPlaceVals 0 [])
else Nothing
where
intVal = sum \$ mapWithIndex (\i d β fb `pow` i * d) \$ reverse ds
getPlaceVals i l
= if intVal >= val
then getPlaceVals (i + 1) (val : l)
else l
where val = tb `pow` i
go (Tuple acc rem) pv = Tuple (snoc acc d) (rem - d * pv)
where d = rem `div` pv``````