diff --git a/homework.cabal b/homework.cabal index 42d5278..fbb1fb3 100644 --- a/homework.cabal +++ b/homework.cabal @@ -34,7 +34,6 @@ library ghc-options: -Wall -Werror -Wcompat -Widentities -Wincomplete-patterns -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-home-modules -Wname-shadowing -Wpartial-fields -Wredundant-constraints -Wunused-packages -Wunused-type-patterns build-depends: base >=4.14 && <5 - , unordered-containers default-language: Haskell2010 executable homework diff --git a/lib/Homework/Ch01/Hanoi.hs b/lib/Homework/Ch01/Hanoi.hs index 193dc8a..9a8cfc1 100644 --- a/lib/Homework/Ch01/Hanoi.hs +++ b/lib/Homework/Ch01/Hanoi.hs @@ -1,26 +1,38 @@ module Homework.Ch01.Hanoi where -import qualified Data.HashMap.Strict as HashMap - newtype Peg = Peg () data Move = Move {moveFrom :: String, moveTo :: String} deriving (Eq, Show) -data Disc = Disc {discSize :: Int} +data Disc = Disc {discSize :: Int} deriving (Eq, Show, Ord) + +type Pegs = [(String, [Disc])] hanoi :: Int -> String -> String -> String -> Either String [Move] hanoi numDisks pegLabelA pegLabelB pegLabelC = - let _pegs = - HashMap.fromList - [ (pegLabelA, fillPegWithDiscs), - (pegLabelB, []), - (pegLabelC, []) - ] - in Right - [ Move "a" "c", - Move "a" "b", - Move "c" "b" + let pegs = + [ (pegLabelA, fillPegWithDiscs numDisks), + (pegLabelB, []), + (pegLabelC, []) ] - where - fillPegWithDiscs :: [Disc] - fillPegWithDiscs = Disc <$> [1 .. numDisks] -- start here: make sure this is initialized correctly + in Right $ snd $ move pegs + +move :: Pegs -> (Pegs, [Move]) +move pegs = + let (firstPegLabel, firstPeg) = head pegs + (lastPegLabel, lastPeg) = last pegs + firstPegDisc = last firstPeg + lastPegDisc = last lastPeg + canMove = firstPegDisc < lastPegDisc + in if canMove + then + ( [ (firstPegLabel, init firstPeg), + head $ tail pegs, + (lastPegLabel, lastPeg <> [firstPegDisc]) + ], + [Move firstPegLabel lastPegLabel] + ) + else (pegs, []) + +fillPegWithDiscs :: Int -> [Disc] +fillPegWithDiscs numDisks = Disc <$> reverse [1 .. numDisks] diff --git a/package.yaml b/package.yaml index 300726f..0944f7a 100644 --- a/package.yaml +++ b/package.yaml @@ -16,8 +16,8 @@ dependencies: library: source-dirs: lib - dependencies: - - unordered-containers + # dependencies: + # - unordered-containers executables: homework: diff --git a/test/Homework/Ch01/HanoiSpec.hs b/test/Homework/Ch01/HanoiSpec.hs index 26e28d7..25ab31a 100644 --- a/test/Homework/Ch01/HanoiSpec.hs +++ b/test/Homework/Ch01/HanoiSpec.hs @@ -4,11 +4,23 @@ import Homework.Ch01.Hanoi import Test.Hspec spec :: Spec -spec = describe "hanoi" $ do - it "can solve for stack of 2 and three pegs" $ do - hanoi 2 "a" "b" "c" - `shouldBe` Right - [ Move "a" "c", - Move "a" "b", - Move "c" "b" - ] +spec = describe "Hanoi" $ do + describe "hanoi" $ do + it "can solve for a stack of 1 and three pegs" $ do + hanoi 1 "a" "b" "c" + `shouldBe` Right + [Move "a" "c"] + it "can solve for stack of 3 and three pegs" $ do + hanoi 3 "a" "b" "c" + `shouldBe` Right + [ Move "a" "c", + Move "a" "b", + Move "c" "b" + ] + describe "fillPegWithDiscs" $ do + it "creates a list of disks from biggest to smallest" $ do + fillPegWithDiscs 3 + `shouldBe` [ Disc 3, + Disc 2, + Disc 1 + ]