ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

# samdup123's solution

## to All Your Base in the Lua Track

Published at Jul 13 2018 · 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!

## Running the tests

To run the tests, run the command `busted` from within the exercise directory.

## Further information

For more detailed information about the Lua track, including how to get help if you're having trouble, please visit the exercism.io Lua language page.

## Submitting Incomplete Solutions

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

### all-your-base_spec.lua

``````local all_your_base = require 'all-your-base'

describe('all-your-base', function()
it('should convert a single binary digit to a single decimal digit', function()
assert.are.same({ 1 }, all_your_base.convert({ 1 }, 2).to(10))
end)

it('should convert multiple binary digits to a single decimal digit', function()
assert.are.same({ 5 }, all_your_base.convert({ 1, 0, 1 }, 2).to(10))
end)

it('should convert a single decimal digit to binary', function()
assert.are.same({ 1, 0, 1 }, all_your_base.convert({ 5 }, 10).to(2))
end)

it('should convert binary to decimal', function()
assert.are.same({ 1, 0, 1, 0, 1, 0 }, all_your_base.convert({ 4, 2 }, 10).to(2))
end)

it('should convert decimal to binary', function()
assert.are.same({ 4, 2 }, all_your_base.convert({ 1, 0, 1, 0, 1, 0 }, 2).to(10))
end)

it('should convert trinary to hexadecimal', function()
assert.are.same({ 2, 10 }, all_your_base.convert({ 1, 1, 2, 0 }, 3).to(16))
end)

it('should convert hexadecimal to trinary', function()
assert.are.same({ 1, 1, 2, 0 }, all_your_base.convert({ 2, 10 }, 16).to(3))
end)

it('should convert between large bases', function()
assert.are.same({ 6, 10, 45 }, all_your_base.convert({ 3, 46, 60 }, 97).to(73))
end)

it('should convert no digits to 0', function()
assert.are.same({ 0 }, all_your_base.convert({ }, 2).to(10))
end)

it('should convert no digits to 0', function()
assert.are.same({ 0 }, all_your_base.convert({ }, 10).to(2))
end)

it('should convert multiple 0 digits to 0', function()
assert.are.same({ 0 }, all_your_base.convert({ 0, 0, 0 }, 10).to(2))
end)

assert.are.same({ 4, 2 }, all_your_base.convert({ 0, 6, 0 }, 7).to(10))
end)

it('should not allow negative digits', function()
assert.has_error(function()
all_your_base.convert({ 1, -1, 1, 0, 1, 0 }, 2).to(10)
end, 'negative digits are not allowed')
end)

it('should not allow digits that are out of range', function()
assert.has_error(function()
all_your_base.convert({ 1, 2, 1, 0, 1, 0 }, 2).to(10)
end, 'digit out of range')
end)

it('should not allow an input base less than 2', function()
assert.has_error(function()
all_your_base.convert({ 1, 0, 1, 0, 1, 0 }, -1).to(10)
end, 'invalid input base')

assert.has_error(function()
all_your_base.convert({ 1, 0, 1, 0, 1, 0 }, 0).to(10)
end, 'invalid input base')

assert.has_error(function()
all_your_base.convert({ 1, 0, 1, 0, 1, 0 }, 1).to(10)
end, 'invalid input base')
end)

it('should not allow an output base less than 2', function()
assert.has_error(function()
all_your_base.convert({ 1, 0, 1, 0, 1, 0 }, 2).to(-1)
end, 'invalid output base')

assert.has_error(function()
all_your_base.convert({ 1, 0, 1, 0, 1, 0 }, 2).to(0)
end, 'invalid output base')

assert.has_error(function()
all_your_base.convert({ 1, 0, 1, 0, 1, 0 }, 2).to(1)
end, 'invalid output base')
end)
end)``````
``````local function to_decimal(num_tbl, old_base)
local new_num = 0
for index, digit in ipairs(num_tbl) do
assert(digit >= 0, 'negative digits are not allowed')
assert(digit < old_base, 'digit out of range')
new_num = new_num + digit * (old_base^(#num_tbl - index))
end
return new_num
end

local function to_new_base(num, new_base)
local new_num = {}
while num > 0 do
table.insert(new_num, 1, num % new_base)
num = num // new_base
end
if #new_num == 0 then return {0} else return new_num end
end

local function convert_num(old_num_tbl, base)
if base < 2 then error('invalid input base') end
return {
to = function(new_base)
assert(new_base > 1, 'invalid output base')
end}
end

return {convert = convert_num}``````