Skip to content

Commit

Permalink
bracket-push: Add new exercise
Browse files Browse the repository at this point in the history
  • Loading branch information
lpalma authored and petertseng committed Apr 7, 2017
1 parent 479d826 commit 337c2a9
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 0 deletions.
7 changes: 7 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,13 @@
"topics": [
]
},
{
"slug": "bracket-push",
"difficulty": 5,
"topics": [
"Stack"
]
},
{
"slug": "crypto-square",
"difficulty": 5,
Expand Down
17 changes: 17 additions & 0 deletions exercises/bracket-push/examples/success-standard/package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: bracket-push

dependencies:
- base

library:
exposed-modules: Brackets
source-dirs: src
dependencies:

tests:
test:
main: Tests.hs
source-dirs: test
dependencies:
- bracket-push
- hspec
36 changes: 36 additions & 0 deletions exercises/bracket-push/examples/success-standard/src/Brackets.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module Brackets (arePaired) where

data BracketType = Opening | Closing
data Stack a = Empty | Elem a (Stack a)

push :: Char -> Stack Char -> Stack Char
push = Elem

pop :: Stack Char -> Stack Char
pop Empty = Empty
pop (Elem _ stack) = stack

arePaired :: String -> Bool
arePaired xs = checkBalance xs Empty

checkBalance :: String -> Stack Char -> Bool
checkBalance [] Empty = True
checkBalance [] _ = False
checkBalance (x:xs) stack =
case classify x of
Just Opening -> checkBalance xs $ push x stack
Just Closing -> (x `closes` stack) && checkBalance xs (pop stack)
_ -> checkBalance xs stack

classify :: Char -> Maybe BracketType
classify x
| x `elem` "([{" = Just Opening
| x `elem` ")]}" = Just Closing
| otherwise = Nothing

closes :: Char -> Stack Char -> Bool
closes _ Empty = False
closes x (Elem y _) =
x == ')' && y == '('
|| x == ']' && y == '['
|| x == '}' && y == '{'
19 changes: 19 additions & 0 deletions exercises/bracket-push/package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: bracket-push

dependencies:
- base

library:
exposed-modules: Brackets
source-dirs: src
dependencies:
# - foo # List here the packages you
# - bar # want to use in your solution.

tests:
test:
main: Tests.hs
source-dirs: test
dependencies:
- bracket-push
- hspec
4 changes: 4 additions & 0 deletions exercises/bracket-push/src/Brackets.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Brackets (arePaired) where

arePaired :: String -> Bool
arePaired xs = error "You need to implement this function."
1 change: 1 addition & 0 deletions exercises/bracket-push/stack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
resolver: lts-8.2
85 changes: 85 additions & 0 deletions exercises/bracket-push/test/Tests.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{-# LANGUAGE RecordWildCards #-}

import Data.Foldable (for_)
import Test.Hspec (Spec, describe, it, shouldBe)
import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)

import Brackets (arePaired)

main :: IO ()
main = hspecWith defaultConfig {configFastFail = True} specs

specs :: Spec
specs = describe "bracket-push" $
describe "isPaired" $ for_ cases test
where
test Case{..} = it description $ arePaired input `shouldBe` expected

-- Adapted from
-- Source: exercism/x-common/exercises/bracket-push/canonical-data.json
-- Version: 1.1.0
-- Date: 2017-04-07.

data Case = Case { description :: String
, input :: String
, expected :: Bool
}

cases :: [Case]
cases = [ Case { description = "paired square brackets"
, input = "[]"
, expected = True
}
, Case { description = "empty string"
, input = ""
, expected = True
}
, Case { description = "unpaired brackets"
, input = "[["
, expected = False
}
, Case { description = "wrong ordered brackets"
, input = "}{"
, expected = False
}
, Case { description = "wrong closing brackets"
, input = "{]"
, expected = False
}
, Case { description = "paired with whitespace"
, input = "{ }"
, expected = True
}
, Case { description = "simple nested brackets"
, input = "{[]}"
, expected = True
}
, Case { description = "several paired brackets"
, input = "{}[]"
, expected = True
}
, Case { description = "paired and nested brackets"
, input = "([{}({}[])])"
, expected = True
}
, Case { description = "unopened closing brackets"
, input = "{[)][]}"
, expected = False
}
, Case { description = "unpaired and nested brackets"
, input = "([{])"
, expected = False
}
, Case { description = "paired and wrong nested brackets"
, input = "[({]})"
, expected = False
}
, Case { description = "math expression"
, input = "(((185 + 223.85) * 15) - 543)/2"
, expected = True
}
, Case { description = "complex latex expression"
, input = "\\left(\\begin{array}{cc} \\frac{1}{3} & x\\\\ \\mathrm{e}^{x} &... x^2 \\end{array}\\right)"
, expected = True
}
]

0 comments on commit 337c2a9

Please sign in to comment.