Balanced brackets: Difference between revisions
Content added Content deleted
Line 462: | Line 462: | ||
input is: []line 1:2 missing NEWLINE at ']' |
input is: []line 1:2 missing NEWLINE at ']' |
||
</pre> |
</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}}== |
=={{header|AutoHotkey}}== |