-- DISJOINT ORDER ------------------------------------------------------------ -- disjointOrder :: String -> String -> String on disjointOrder(m, n) set {ms, ns} to map(my |words|, {m, n}) unwords(flatten(zip(segments(ms, ns), ns & ""))) end disjointOrder -- segments :: [String] -> [String] -> [String] on segments(ms, ns) script segmentation on |λ|(a, x) set wds to |words| of a if wds contains x then {parts:(parts of a) & ¬ [current of a], current:[], |words|:deleteFirst(x, wds)} ¬ else {parts:(parts of a), current:(current of a) & x, |words|:wds} end if end |λ| end script tell foldl(segmentation, {|words|:ns, parts:[], current:[]}, ms) (parts of it) & [current of it] end tell end segments -- TEST ---------------------------------------------------------------------- on run script order on |λ|(rec) tell rec [its m, its n, my disjointOrder(its m, its n)] end tell end |λ| end script arrowTable(map(order, [¬ {m:"the cat sat on the mat", n:"mat cat"}, ¬ {m:"the cat sat on the mat", n:"cat mat"}, ¬ {m:"A B C A B C A B C", n:"C A C A"}, ¬ {m:"A B C A B D A B E", n:"E A D A"}, ¬ {m:"A B", n:"B"}, {m:"A B", n:"B A"}, ¬ {m:"A B B A", n:"B A"}])) -- the cat sat on the mat -> mat cat -> the mat sat on the cat -- the cat sat on the mat -> cat mat -> the cat sat on the mat -- A B C A B C A B C -> C A C A -> C B A C B A A B C -- A B C A B D A B E -> E A D A -> E B C A B D A B A -- A B -> B -> A B -- A B -> B A -> B A -- A B B A -> B A -> B A B A end run -- GENERIC FUNCTIONS --------------------------------------------------------- -- Formatting test results -- arrowTable :: [[String]] -> String on arrowTable(rows) script leftAligned script width on |λ|(a, b) (length of a) - (length of b) end |λ| end script on |λ|(col) set widest to length of maximumBy(width, col) script padding on |λ|(s) justifyLeft(widest, space, s) end |λ| end script map(padding, col) end |λ| end script script arrows on |λ|(row) intercalate(" -> ", row) end |λ| end script intercalate(linefeed, ¬ map(arrows, ¬ transpose(map(leftAligned, transpose(rows))))) end arrowTable -- concatMap :: (a -> [b]) -> [a] -> [b] on concatMap(f, xs) script append on |λ|(a, b) a & b end |λ| end script foldl(append, {}, map(f, xs)) end concatMap -- deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a] on deleteBy(fnEq, x, xs) if length of xs > 0 then set {h, t} to uncons(xs) if |λ|(x, h) of mReturn(fnEq) then t else {h} & deleteBy(fnEq, x, t) end if else {} end if end deleteBy -- deleteFirst :: a -> [a] -> [a] on deleteFirst(x, xs) script Eq on |λ|(a, b) a = b end |λ| end script deleteBy(Eq, x, xs) end deleteFirst -- flatten :: Tree a -> [a] on flatten(t) if class of t is list then concatMap(my flatten, t) else t end if end flatten -- foldl :: (a -> b -> a) -> a -> [b] -> a on foldl(f, startValue, xs) tell mReturn(f) set v to startValue set lng to length of xs repeat with i from 1 to lng set v to |λ|(v, item i of xs, i, xs) end repeat return v end tell end foldl -- intercalate :: 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 -- justifyLeft :: Int -> Char -> Text -> Text on justifyLeft(n, cFiller, strText) if n > length of strText then text 1 thru n of (strText & replicate(n, cFiller)) else strText end if end justifyLeft -- map :: (a -> b) -> [a] -> [b] on map(f, xs) tell mReturn(f) set lng to length of xs set lst to {} repeat with i from 1 to lng set end of lst to |λ|(item i of xs, i, xs) end repeat return lst end tell end map -- maximumBy :: (a -> a -> Ordering) -> [a] -> a on maximumBy(f, xs) set cmp to mReturn(f) script max on |λ|(a, b) if a is missing value or cmp's |λ|(a, b) < 0 then b else a end if end |λ| end script foldl(max, missing value, xs) end maximumBy -- minimum :: [a] -> a on minimum(xs) script min on |λ|(a, x) if x < a or a is missing value then x else a end if end |λ| end script foldl(min, missing value, xs) end minimum -- Lift 2nd class handler function into 1st class script wrapper -- mReturn :: Handler -> Script on mReturn(f) if class of f is script then f else script property |λ| : f end script end if end mReturn -- Egyptian multiplication - progressively doubling a list, appending -- stages of doubling to an accumulator where needed for binary -- assembly of a target length -- replicate :: Int -> a -> [a] on replicate(n, a) set out to {} if n < 1 then return out set dbl to {a} repeat while (n > 1) if (n mod 2) > 0 then set out to out & dbl set n to (n div 2) set dbl to (dbl & dbl) end repeat return out & dbl end replicate -- transpose :: [[a]] -> [[a]] on transpose(xss) script column on |λ|(_, iCol) script row on |λ|(xs) item iCol of xs end |λ| end script map(row, xss) end |λ| end script map(column, item 1 of xss) end transpose -- uncons :: [a] -> Maybe (a, [a]) on uncons(xs) if length of xs > 0 then {item 1 of xs, rest of xs} else missing value end if end uncons -- unwords :: [String] -> String on unwords(xs) intercalate(space, xs) end unwords -- words :: String -> [String] on |words|(s) words of s end |words| -- zip :: [a] -> [b] -> [(a, b)] on zip(xs, ys) script pair on |λ|(x, i) [x, item i of ys] end |λ| end script map(pair, items 1 thru minimum([length of xs, length of ys]) of xs) end zip