Add Towers of Hanoi exercise

This commit is contained in:
Camden Dixie O'Brien 2023-12-14 12:14:32 +00:00
parent 5f57627225
commit 45c27ba067

81
18_towers_of_hanoi.lua Normal file
View File

@ -0,0 +1,81 @@
-- The Towers of Hanoi is a mathematical puzzle consisting of three
-- rods and a number of disks of various diameters which can slide
-- onto any rod. Initially, all the disks are stacked in decreasing
-- size order so that they form a conical shape. The objective to
-- move the entire stack to one of the other two rods, with each move
-- consisting of taking the uppermost disk from one of the rods and
-- placing it on top of the stack on another one. A disk cannot be
-- placed on top of a disk of smaller diameter.
--
-- Write a function which generates an optimal solution to the puzzle.
-- The rods are numbered 1-3, with the stack starting on rod 1. Your
-- function should return a list of {from = <rod>, to = <rod>} tables,
-- and will receive the number of disks in the original stack as its
-- argument.
--
-- Solution --------------------------------------------------------------------
function towers_of_hanoi_solution(disk_count)
-- Your implementation here
end
-- Tests -----------------------------------------------------------------------
local luaunit = require("luaunit.luaunit")
local function disk_stack(count)
local stack = {}
for i = count, 1, -1 do table.insert(stack, i) end
return stack
end
local function assert_valid(state)
for _, rod in ipairs(state) do
local previous = rod[1]
for _, disk in ipairs(rod) do
luaunit.assertTrue(disk <= previous)
previous = disk
end
end
return true
end
local function assert_solved(state, disk_count)
luaunit.assertEquals(state[1], {})
if #state[2] ~= 0 then
luaunit.assertEquals(state[2], disk_stack(disk_count))
luaunit.assertEquals(state[3], {})
else
luaunit.assertEquals(state[2], {})
luaunit.assertEquals(state[3], disk_stack(disk_count))
end
end
local function assert_is_solution(solution, disk_count)
local state = {disk_stack(disk_count), {}, {}}
for i, move in ipairs(solution) do
local disk = table.remove(state[move.from])
table.insert(state[move.to], disk)
assert_valid(state)
end
assert_solved(state, disk_count)
end
local function test_with_count(disk_count)
local solution = towers_of_hanoi_solution(disk_count)
assert_is_solution(solution, disk_count)
luaunit.assertEquals(#solution, 2 ^ disk_count - 1)
end
function test_with_1_disk()
test_with_count(1)
end
function test_with_7_disks()
test_with_count(7)
end
function test_with_12_disks()
test_with_count(12)
end
os.exit(luaunit.LuaUnit.run())