🎉 Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io 🎉 # SergiiVlasiuk's solution

## to All Your Base in the Scala Track

Published at Aug 27 2019 · 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!

The Scala exercises assume an SBT project scheme. The exercise solution source should be placed within the exercise directory/src/main/scala. The exercise unit tests can be found within the exercise directory/src/test/scala.

To run the tests simply run the command `sbt test` in the exercise directory.

For more detailed info about the Scala track see the help page.

## Submitting Incomplete Solutions

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

### AllYourBaseTest.scala

``````import org.scalatest.{Matchers, FunSuite}

/** @version 2.3.0 */
class AllYourBaseTest extends FunSuite with Matchers {

test("single bit one to decimal") {
AllYourBase.rebase(2, List(1), 10) should be(Some(List(1)))
}

test("binary to single decimal") {
pending
AllYourBase.rebase(2, List(1, 0, 1), 10) should be(Some(List(5)))
}

test("single decimal to binary") {
pending
AllYourBase.rebase(10, List(5), 2) should be(Some(List(1, 0, 1)))
}

test("binary to multiple decimal") {
pending
AllYourBase.rebase(2, List(1, 0, 1, 0, 1, 0), 10) should be(
Some(List(4, 2)))
}

test("decimal to binary") {
pending
AllYourBase.rebase(10, List(4, 2), 2) should be(
Some(List(1, 0, 1, 0, 1, 0)))
}

pending
AllYourBase.rebase(3, List(1, 1, 2, 0), 16) should be(Some(List(2, 10)))
}

pending
AllYourBase.rebase(16, List(2, 10), 3) should be(Some(List(1, 1, 2, 0)))
}

test("15-bit integer") {
pending
AllYourBase.rebase(97, List(3, 46, 60), 73) should be(Some(List(6, 10, 45)))
}

test("empty list") {
pending
AllYourBase.rebase(2, List(), 10) should be(Some(List(0)))
}

test("single zero") {
pending
AllYourBase.rebase(10, List(0), 2) should be(Some(List(0)))
}

test("multiple zeros") {
pending
AllYourBase.rebase(10, List(0, 0, 0), 2) should be(Some(List(0)))
}

pending
AllYourBase.rebase(7, List(0, 6, 0), 10) should be(Some(List(4, 2)))
}

test("input base is one") {
pending
AllYourBase.rebase(1, List(0), 10) should be(None)
}

test("input base is zero") {
pending
AllYourBase.rebase(0, List(), 10) should be(None)
}

test("input base is negative") {
pending
AllYourBase.rebase(-2, List(1), 10) should be(None)
}

test("negative digit") {
pending
AllYourBase.rebase(2, List(1, -1, 1, 0, 1, 0), 10) should be(None)
}

test("invalid positive digit") {
pending
AllYourBase.rebase(2, List(1, 2, 1, 0, 1, 0), 10) should be(None)
}

test("output base is one") {
pending
AllYourBase.rebase(2, List(1, 0, 1, 0, 1, 0), 1) should be(None)
}

test("output base is zero") {
pending
AllYourBase.rebase(10, List(7), 0) should be(None)
}

test("output base is negative") {
pending
AllYourBase.rebase(2, List(1), -7) should be(None)
}

test("both bases are negative") {
pending
AllYourBase.rebase(-2, List(1), -7) should be(None)
}
}``````
``````object AllYourBase {
def rebase(fromBase: Int, digits: List[Int], toBase: Int): Option[List[Int]] = {
val invalidBase = fromBase < 2 || toBase < 2
lazy val toDecimalValue: Int = digits.foldLeft(0)((total, digit) => (total * fromBase) + digit)

def invalidDigit(digit: Int): Boolean = digit < 0 || digit >= fromBase

def convertBase(decimal: Int): List[Int] =
if (decimal < toBase) decimal :: Nil
else (decimal % toBase)::convertBase(decimal / toBase)

if (digits.exists(invalidDigit) || invalidBase) None
else Some(convertBase(toDecimalValue).reverse)
}
}``````