diff --git a/haskell/04-hanoi/README.md b/haskell/04-hanoi/README.md new file mode 100644 index 0000000..53f5a1c --- /dev/null +++ b/haskell/04-hanoi/README.md @@ -0,0 +1,13 @@ +# Assignment - Tower of Hanoi {.alert} + +The Tower of Hanoi is a classic mathematical puzzle that involves three rods and a number of disks of different sizes. +The puzzle starts with all the disks stacked in ascending order of size on one rod (the source rod), with the smallest disk on top. +The objective is to move the entire stack to another rod (the destination rod), following these rules: + +1. Only one disk can be moved at a time. +2. Each move consists of taking the top disk from one rod and placing it on another rod. +3. No disk may be placed on top of a smaller disk. + +**Your task:** + +Implement a function that solves the Tower of Hanoi problem for `n` disks. The rods are represented as Chars (e.g. 'a','b','c'). The result shall be a list of moving instructions. Add your implementation to the file `04-hanoi/hanoi.hs` that already contains a test and a helper function that creates the move instruction for a single move. \ No newline at end of file diff --git a/haskell/04-hanoi/hanoi.hs b/haskell/04-hanoi/hanoi.hs new file mode 100644 index 0000000..5f64857 --- /dev/null +++ b/haskell/04-hanoi/hanoi.hs @@ -0,0 +1,70 @@ +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} + +{-# HLINT ignore "Use void" #-} +import Test.HUnit + +-- some helper function that describes a single move +move :: Int -> Char -> Char -> String +move n src dst = "move disk " ++ show n ++ " from " ++ [src] ++ " to " ++ [dst] + +-- transfers a number of disks (the Int) from a source (the first Char) rod to a destination (the second Char) rod via a temp (the third char) rod +-- returns a list of required operations +hanoi :: (Int,Char,Char,Char) -> [String] + +--TODO: implement here + +-- Source, Destination, Temp +hanoiTests :: [((Int, Char, Char, Char), [String])] +hanoiTests = + [ ( (1, 'a', 'c', 'b'), + [ "move disk 1 from a to c" + ] + ), + ( (1, 'b', 'a', 'c'), + [ "move disk 1 from b to a" + ] + ), + ( (2, 'a', 'c', 'b'), + [ "move disk 1 from a to b", + "move disk 2 from a to c", + "move disk 1 from b to c" + ] + ), + ( (3, 'a', 'c', 'b'), + [ "move disk 1 from a to c", + "move disk 2 from a to b", + "move disk 1 from c to b", + "move disk 3 from a to c", + "move disk 1 from b to a", + "move disk 2 from b to c", + "move disk 1 from a to c" + ] + ), + ( (4, 'a', 'c', 'b'), + [ "move disk 1 from a to b", + "move disk 2 from a to c", + "move disk 1 from b to c", + "move disk 3 from a to b", + "move disk 1 from c to a", + "move disk 2 from c to b", + "move disk 1 from a to b", + "move disk 4 from a to c", + "move disk 1 from b to c", + "move disk 2 from b to a", + "move disk 1 from c to a", + "move disk 3 from b to c", + "move disk 1 from a to b", + "move disk 2 from a to c", + "move disk 1 from b to c" + ] + ) + ] + +hanoiTestCases :: [Test] +hanoiTestCases = map (\(input, expected) -> TestCase (assertEqual ("hanoi " ++ show input) expected (hanoi input))) hanoiTests + +tests :: Test +tests = TestList hanoiTestCases + +main :: IO () +main = runTestTT tests >> return ()