Balanced brackets: Difference between revisions

Line 462:
input is: []line 1:2 missing NEWLINE at ']'
</pre>
 
 
=={{header|AppleScript}}==
 
{{trans|JavaScript}}
 
<lang AppleScript>-- GENERATE AND CHECK NESTING OF SQUARE BRACKET SEQUENCES
 
-- brackets :: Int -> String
on brackets(n)
script mf
on bracket(_)
if (random number) < 0.5 then
"["
else
"]"
end if
end bracket
end script
intercalate("", map(range(1, n), mf's bracket))
end brackets
 
-- Zero-based index of the first problem (-1 if none found)
-- imbalance :: String -> Integer
on imbalance(strBrackets)
script mf
on errorIndex(xs, iDepth, iIndex)
set lngChars to length of xs
if lngChars > 0 then
if item 1 of xs = "[" then
set iNext to iDepth + 1
else
set iNext to iDepth - 1
end if
if iNext < 0 then -- closing bracket unmatched
iIndex
else
if lngChars > 1 then -- continue recursively
errorIndex(items 2 thru -1 of xs, iNext, iIndex + 1)
else -- end of string
if iNext = 0 then -- balanced - no problem
-1
else
iIndex -- position of problem
end if
end if
end if
else
if iDepth = 0 then
-1
else
iIndex
end if
end if
end errorIndex
end script
mf's errorIndex(characters of strBrackets, 0, 0)
end imbalance
 
-- TEST
 
on run
script mf
property nPairs : 6
on report(n)
set mf to my closure's mf
set strPad to my closure's strPad
set w to n * 2
set s to brackets(w)
set i to imbalance(s)
set blnOK to (i = -1)
if blnOK then
set strStatus to "OK"
else
set strStatus to "problem"
end if
set strLine to "'" & s & "'" & ¬
(items (w + 2) thru -1 of strPad) & strStatus
if blnOK then
set strPointer to ""
else
set strPointer to linefeed & nreps(space, i + 1) & "^"
end if
intercalate("", {strLine, strPointer})
end report
end script
set lngPairs to mf's nPairs
linefeed & ¬
intercalate(linefeed, ¬
map(range(0, lngPairs), ¬
mClosure(mf's report, ¬
{strPad:nreps(space, lngPairs * 2 + 4), mf:mf}))) ¬
& linefeed
end run
 
 
-- GENERIC LIBRARY FUNCTIONS
 
-- map :: [a] -> (a -> b) -> [b]
on map(xs, f)
set mf to mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to mf's lambda(item i of xs, i, xs)
end repeat
return lst
end map
 
-- Text -> [Text] -> Text
on intercalate(strText, lstText)
set {dlm, my text item delimiters} to {my text item delimiters, strText}
set strJoined to lstText as text
set my text item delimiters to dlm
return strJoined
end intercalate
 
-- range :: Int -> Int -> Int
on range(m, n)
set lng to (n - m) + 1
set base to m - 1
set lst to {}
repeat with i from 1 to lng
set end of lst to i + base
end repeat
return lst
end range
 
-- String -> Int -> String
on nreps(s, n)
set o to ""
if n < 1 then return o
repeat while (n > 1)
if (n mod 2) > 0 then set o to o & s
set n to (n div 2)
set s to (s & s)
end repeat
return o & s
end nreps
 
-- Lift 2nd class function into 1st class wrapper
-- handler function --> first class script object
on mReturn(f)
if class of f is script then return f
script
property lambda : f
end script
end mReturn
 
-- Handler -> Record -> Script
on mClosure(f, recBindings)
script
property closure : recBindings
property lambda : f
end script
end mClosure</lang>
 
{{Out}}
 
<pre>
'' OK
'[]' OK
'[[]]' OK
'[]][][' problem
^
'[[]]]]]]' problem
^
']]][][]][]' problem
^
'][[[[][[[]][' problem
^</pre>
 
=={{header|AutoHotkey}}==
9,659

edits