Skip to main content
Tweeted twitter.com/StackCodeReview/status/906643427395346432
edited tags
Link
200_success
  • 145.7k
  • 22
  • 191
  • 481
Slight improvements
Source Link
-- pop is a head that defaults to zero
pop :: (Integral a) => [a] -> a
pop [] = 0
pop (x:_) = x

-- rest is a tail for pop
rest :: (Integral a) => [a] -> [a]
rest [] = []
rest (_:x) = x

-- topadd adds an Integer to the top of a [Integer]
topadd :: [Integer] -> Integer -> [Integer]
topadd [] x = [x]
topadd (a:[]) x = [a+x]
topadd (a:b) x = (a+x):b

-- ir is a helper function of interior
ir :: [Char]String -> Integer -> [Char]String
ir x 0 = ""
ir ('{':x) y = "{" ++ (ir x (y+1))
ir ('}':x) y = "}" ++ (ir x (y-1))
ir (a:x)   y = [a] ++ (ir x   y  )

-- interior finds the inside of a loop {x}... -> x
interior :: [Char]String -> [Char]String
interior x = init (ir x 1)

-- ex is a helper function for exterior
ex :: [Char]String -> Integer -> [Char]String
ex x 0 = x
ex ('{':x) y = ex x (y+1)
ex ('}':x) y = ex x (y-1)
ex  (a:x)  y = ex x y

-- exterior finds all the code after a loop {...}x -> x
exterior :: [Char]String -> [Char]String
exterior x = ex x 1

-- bf is the implementation of brain-flak
bf :: [Char]String -> ([Integer],[Integer],[Integer]) -> ([Integer],[Integer],[Integer])
bf []          (x,y,z)= (x,y,z)
bf ('(':')':a) (x,y,z)= bf a (x,y,((pop z+1):rest z))
bf ('<':'>':a) (x,y,z)= bf a (y,x,z)
bf ('{':'}':a) (x,y,z)= bf a ((rest x),y,(topadd z (pop x)))
bf ('[':']':a) (x,y,z)= bf a (x,y,(topadd z (toInteger (length x))))
bf ('(':a)     (x,y,z)= bf a (x,y,(0:z))
bf ('<':a)     (x,y,z)= bf a (x,y,(0:z))
bf ('[':a)     (x,y,z)= bf a (x,y,(0:z))
bf (')':a) (x,y,(h:z))= bf a ((h:x),y,(topadd z h))
bf (']':a) (x,y,(h:z))= bf a (x,y,(topadd z (-h)))
bf ('>':a) (x,y,(_:z))= bf a (x,y,z)
bf ('{':a)      t     = bf (exterior a) (loop (interior a) t)
bf (_:a)        t     = bf a t

-- loop runs the same code until the TOS is zero
loop :: [Char]String -> ([Integer],[Integer],[Integer]) -> ([Integer],[Integer],[Integer])
loop s ([],y,z)  = ([],y,z)
loop s (0:x,y,z) = (0:x,y,z)
loop s x         = loop s (bf s x)
 
-- first finds the first element of a 3 tuple
first :: (a,b,c) -> a
first (a,_,_) = a

-- bl is an helper function of balance
bl :: [Char]String -> [Char]String -> Bool
bl [] [] = True
bl [] _  = False
bl ('(':x) y   = bl x (')':y) 
bl ('[':x) y   = bl x (']':y) 
bl ('<':x) y   = bl x ('>':y) 
bl ('{':x) y   = bl x ('}':y) 
bl  _ [] = False
bl (a:x) (b:y) = (a == b) && (bl x y)

-- balanced checks if a particular String is balanced
balanced :: [Char]String -> Bool
balanced x = bl x []

-- Implements Brain-Flak
brainflak :: [Char]String -> [Integer] -> [Integer]
brainflak s x
 | balanced source = first(\(a,_,_) -> a) (bf source (x,[],[]))
 | otherwise  = error "Unbalanced braces."
 where source = [a|a <- s, elem a "()[]<>{}"]
-- pop is a head that defaults to zero
pop :: (Integral a) => [a] -> a
pop [] = 0
pop (x:_) = x

-- rest is a tail for pop
rest :: (Integral a) => [a] -> [a]
rest [] = []
rest (_:x) = x

-- topadd adds an Integer to the top of a [Integer]
topadd :: [Integer] -> Integer -> [Integer]
topadd [] x = [x]
topadd (a:[]) x = [a+x]
topadd (a:b) x = (a+x):b

-- ir is a helper function of interior
ir :: [Char] -> Integer -> [Char]
ir x 0 = ""
ir ('{':x) y = "{" ++ (ir x (y+1))
ir ('}':x) y = "}" ++ (ir x (y-1))
ir (a:x)   y = [a] ++ (ir x   y  )

-- interior finds the inside of a loop {x}... -> x
interior :: [Char] -> [Char]
interior x = init (ir x 1)

-- ex is a helper function for exterior
ex :: [Char] -> Integer -> [Char]
ex x 0 = x
ex ('{':x) y = ex x (y+1)
ex ('}':x) y = ex x (y-1)
ex  (a:x)  y = ex x y

-- exterior finds all the code after a loop {...}x -> x
exterior :: [Char] -> [Char]
exterior x = ex x 1

-- bf is the implementation of brain-flak
bf :: [Char] -> ([Integer],[Integer],[Integer]) -> ([Integer],[Integer],[Integer])
bf []          (x,y,z)= (x,y,z)
bf ('(':')':a) (x,y,z)= bf a (x,y,((pop z+1):rest z))
bf ('<':'>':a) (x,y,z)= bf a (y,x,z)
bf ('{':'}':a) (x,y,z)= bf a ((rest x),y,(topadd z (pop x)))
bf ('[':']':a) (x,y,z)= bf a (x,y,(topadd z (toInteger (length x))))
bf ('(':a)     (x,y,z)= bf a (x,y,(0:z))
bf ('<':a)     (x,y,z)= bf a (x,y,(0:z))
bf ('[':a)     (x,y,z)= bf a (x,y,(0:z))
bf (')':a) (x,y,(h:z))= bf a ((h:x),y,(topadd z h))
bf (']':a) (x,y,(h:z))= bf a (x,y,(topadd z (-h)))
bf ('>':a) (x,y,(_:z))= bf a (x,y,z)
bf ('{':a)      t     = bf (exterior a) (loop (interior a) t)
bf (_:a)        t     = bf a t

-- loop runs the same code until the TOS is zero
loop :: [Char] -> ([Integer],[Integer],[Integer]) -> ([Integer],[Integer],[Integer])
loop s ([],y,z)  = ([],y,z)
loop s (0:x,y,z) = (0:x,y,z)
loop s x         = loop s (bf s x)
 
-- first finds the first element of a 3 tuple
first :: (a,b,c) -> a
first (a,_,_) = a

-- bl is an helper function of balance
bl :: [Char] -> [Char] -> Bool
bl [] [] = True
bl [] _  = False
bl ('(':x) y   = bl x (')':y) 
bl ('[':x) y   = bl x (']':y) 
bl ('<':x) y   = bl x ('>':y) 
bl ('{':x) y   = bl x ('}':y) 
bl  _ [] = False
bl (a:x) (b:y) = (a == b) && (bl x y)

-- balanced checks if a particular String is balanced
balanced :: [Char] -> Bool
balanced x = bl x []

-- Implements Brain-Flak
brainflak :: [Char] -> [Integer] -> [Integer]
brainflak s x
 | balanced source = first (bf source (x,[],[]))
 | otherwise  = error "Unbalanced braces."
 where source = [a|a <- s, elem a "()[]<>{}"]
-- pop is a head that defaults to zero
pop :: (Integral a) => [a] -> a
pop [] = 0
pop (x:_) = x

-- rest is a tail for pop
rest :: (Integral a) => [a] -> [a]
rest [] = []
rest (_:x) = x

-- topadd adds an Integer to the top of a [Integer]
topadd :: [Integer] -> Integer -> [Integer]
topadd [] x = [x]
topadd (a:[]) x = [a+x]
topadd (a:b) x = (a+x):b

-- ir is a helper function of interior
ir :: String -> Integer -> String
ir x 0 = ""
ir ('{':x) y = "{" ++ (ir x (y+1))
ir ('}':x) y = "}" ++ (ir x (y-1))
ir (a:x)   y = [a] ++ (ir x   y  )

-- interior finds the inside of a loop {x}... -> x
interior :: String -> String
interior x = init (ir x 1)

-- ex is a helper function for exterior
ex :: String -> Integer -> String
ex x 0 = x
ex ('{':x) y = ex x (y+1)
ex ('}':x) y = ex x (y-1)
ex  (a:x)  y = ex x y

-- exterior finds all the code after a loop {...}x -> x
exterior :: String -> String
exterior x = ex x 1

-- bf is the implementation of brain-flak
bf :: String -> ([Integer],[Integer],[Integer]) -> ([Integer],[Integer],[Integer])
bf []          (x,y,z)= (x,y,z)
bf ('(':')':a) (x,y,z)= bf a (x,y,((pop z+1):rest z))
bf ('<':'>':a) (x,y,z)= bf a (y,x,z)
bf ('{':'}':a) (x,y,z)= bf a ((rest x),y,(topadd z (pop x)))
bf ('[':']':a) (x,y,z)= bf a (x,y,(topadd z (toInteger (length x))))
bf ('(':a)     (x,y,z)= bf a (x,y,(0:z))
bf ('<':a)     (x,y,z)= bf a (x,y,(0:z))
bf ('[':a)     (x,y,z)= bf a (x,y,(0:z))
bf (')':a) (x,y,(h:z))= bf a ((h:x),y,(topadd z h))
bf (']':a) (x,y,(h:z))= bf a (x,y,(topadd z (-h)))
bf ('>':a) (x,y,(_:z))= bf a (x,y,z)
bf ('{':a)      t     = bf (exterior a) (loop (interior a) t)
bf (_:a)        t     = bf a t

-- loop runs the same code until the TOS is zero
loop :: String -> ([Integer],[Integer],[Integer]) -> ([Integer],[Integer],[Integer])
loop s ([],y,z)  = ([],y,z)
loop s (0:x,y,z) = (0:x,y,z)
loop s x         = loop s (bf s x)
 
-- bl is an helper function of balance
bl :: String -> String -> Bool
bl [] [] = True
bl [] _  = False
bl ('(':x) y   = bl x (')':y) 
bl ('[':x) y   = bl x (']':y) 
bl ('<':x) y   = bl x ('>':y) 
bl ('{':x) y   = bl x ('}':y) 
bl  _ [] = False
bl (a:x) (b:y) = (a == b) && (bl x y)

-- balanced checks if a particular String is balanced
balanced :: String -> Bool
balanced x = bl x []

-- Implements Brain-Flak
brainflak :: String -> [Integer] -> [Integer]
brainflak s x
 | balanced source = (\(a,_,_) -> a) (bf source (x,[],[]))
 | otherwise  = error "Unbalanced braces."
 where source = [a|a <- s, elem a "()[]<>{}"]
More useful title
Link

Brain Flak implementation in Haskell

added 112 characters in body
Source Link
Loading
Source Link
Loading