Balanced brackets: Difference between revisions
Content added Content deleted
m (→JS Functional: Tidying) |
|||
Line 3,469: | Line 3,469: | ||
'use strict'; |
'use strict'; |
||
// ---------------- BALANCED BRACKETS ---------------- |
|||
⚫ | |||
const findUnbalancedBracket = strBrackets => strHaystack => { |
|||
⚫ | |||
⚫ | |||
const firstUnbalancedBracket = brackets => |
|||
openBracket = strBrackets[0], |
|||
haystack => { |
|||
const [openBracket, closeBracket] = [...brackets]; |
|||
const go = (xs, iDepth, iCharPosn) => |
|||
// |
// iDepth: initial nesting depth (0 = closed) |
||
// iCharPosn: starting character position |
|||
0 < xs.length ? (() => { |
|||
const |
|||
h = xs[0], |
|||
tail = xs.slice(1), |
|||
iNext = iDepth + ( |
|||
brackets.includes(h) ? ( |
|||
openBracket === h ? ( |
|||
1 |
|||
) : |
) : -1 |
||
) |
) : 0 |
||
); |
|||
return 0 > iNext ? ( |
|||
Just(iCharPosn) // Unmatched closing bracket. |
|||
) : 0 < tail.length ? go( |
|||
tail, iNext, 1 + iCharPosn |
|||
⚫ | |||
Just(iCharPosn) |
|||
) : Nothing(); |
|||
})() : 0 !== iDepth ? ( |
|||
Just(iCharPosn) |
Just(iCharPosn) |
||
) : Nothing(); |
) : Nothing(); |
||
return go([...haystack], 0, 0); |
|||
}; |
|||
⚫ | |||
return go(strHaystack.split(''), 0, 0); |
|||
}; |
|||
// |
// ---------------------- TEST ----------------------- |
||
// main :: IO () |
// main :: IO () |
||
const main = () => { |
const main = () => { |
||
Line 3,519: | Line 3,520: | ||
' '.repeat(1 + iUnMatched) + '^' |
' '.repeat(1 + iUnMatched) + '^' |
||
)( |
)( |
||
firstUnbalancedBracket('[]')(strSample) |
|||
); |
); |
||
}).join('\n') |
}).join('\n') |
||
); |
); |
||
}; |
}; |
||
// Int -> String |
// Int -> String |
||
Line 3,533: | Line 3,535: | ||
// |
// --------------------- GENERIC --------------------- |
||
// Just :: a -> Maybe a |
// Just :: a -> Maybe a |
||
Line 3,541: | Line 3,543: | ||
Just: x |
Just: x |
||
}); |
}); |
||
// Nothing :: Maybe a |
// Nothing :: Maybe a |
||
Line 3,547: | Line 3,550: | ||
Nothing: true, |
Nothing: true, |
||
}); |
}); |
||
// enumFromTo :: Int -> Int -> [Int] |
// enumFromTo :: Int -> Int -> [Int] |
||
const enumFromTo = m |
const enumFromTo = m => |
||
n => !isNaN(m) ? ( |
|||
Array.from({ |
|||
length: 1 + n - m |
|||
}, (_, i) => m + i) |
|||
) : enumFromTo_(m)(n); |
|||
// maybe :: b -> (a -> b) -> Maybe a -> b |
// maybe :: b -> (a -> b) -> Maybe a -> b |
||
const maybe = v |
const maybe = v => |
||
// Default value (v) if m is Nothing, or f(m.Just) |
|||
f => m => m.Nothing ? ( |
|||
⚫ | |||
) : f(m.Just); |
|||
// --- |
// --- |