Longest common prefix: Difference between revisions
Content added Content deleted
m (format) |
m (→JS ES6: Updated primitives and output.) |
||
Line 1,856: | Line 1,856: | ||
===ES6=== |
===ES6=== |
||
<lang javascript>(() => { |
<lang javascript>(() => { |
||
"use strict"; |
|||
// -------------- LONGEST COMMON PREFIX -------------- |
|||
// lcp :: (Eq a) => [[a]] -> [a] |
// lcp :: (Eq a) => [[a]] -> [a] |
||
const lcp = xs => { |
const lcp = xs => { |
||
const go = |
const go = ws => |
||
ws.some(isNull) ? ( |
|||
[] |
[] |
||
) : |
) : [ws.map(head)].concat( |
||
map( |
go(ws.map(tail)) |
||
⚫ | |||
); |
); |
||
return concat(map( |
|||
return takeWhile(allSame)( |
|||
go(xs.map(s => [...s])) |
|||
⚫ | |||
go(map(chars, xs)) |
|||
) |
) |
||
) |
.map(head) |
||
⚫ | |||
}; |
}; |
||
// |
// ---------------------- TEST ----------------------- |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
].map(showPrefix).join("\n"); |
|||
// showPrefix :: [String] -> String |
// showPrefix :: [String] -> String |
||
const showPrefix = xs => |
const showPrefix = xs => |
||
`${show(xs)} -> ${show(lcp(xs))}`; |
|||
⚫ | |||
⚫ | |||
const strResults = unlines(map( |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
[""], |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
// console.log(strResults), |
|||
⚫ | |||
); |
|||
}; |
|||
// |
// ---------------- GENERIC FUNCTIONS ---------------- |
||
// allSame :: [a] -> Bool |
// allSame :: [a] -> Bool |
||
Line 1,908: | Line 1,903: | ||
0 === xs.length || (() => { |
0 === xs.length || (() => { |
||
const x = xs[0]; |
const x = xs[0]; |
||
return xs.every(y => x === y) |
return xs.every(y => x === y); |
||
})(); |
})(); |
||
// chars :: String -> [Char] |
|||
const chars = s => s.split(''); |
|||
// |
// head :: [a] -> a |
||
const head = xs => |
|||
xs.length ? ( |
|||
xs[0] |
|||
⚫ | |||
const unit = 'string' !== typeof xs[0] ? ( |
|||
[] |
|||
) : ''; |
|||
return unit.concat.apply(unit, xs); |
|||
})() : []; |
|||
// cons :: a -> [a] -> [a] |
|||
const cons = (x, xs) => [x].concat(xs); |
|||
// head :: [a] -> a |
|||
const head = xs => xs.length ? xs[0] : undefined; |
|||
// isNull :: [a] -> Bool |
// isNull :: [a] -> Bool |
||
// isNull :: String -> Bool |
// isNull :: String -> Bool |
||
const isNull = xs => |
const isNull = xs => |
||
// True if xs is empty. |
|||
1 > xs.length; |
|||
) : undefined; |
|||
// map :: (a -> b) -> [a] -> [b] |
|||
const map = (f, xs) => |
|||
⚫ | |||
xs |
|||
) : xs.split('')).map(f); |
|||
// show :: a -> String |
// show :: a -> String |
||
const show = JSON.stringify; |
const show = JSON.stringify; |
||
// tail :: [a] -> [a] |
// tail :: [a] -> [a] |
||
const tail = xs => |
const tail = xs => |
||
⚫ | |||
⚫ | |||
⚫ | |||
// takeWhile :: (a -> Bool) -> [a] -> [a] |
// takeWhile :: (a -> Bool) -> [a] -> [a] |
||
const takeWhile = p => |
|||
xs => { |
|||
const |
const i = xs.findIndex(x => !p(x)); |
||
return 0 < lng ? xs.slice( |
|||
0, |
|||
until( |
|||
i => lng === i || !p(xs[i]), |
|||
i => 1 + i, |
|||
0 |
|||
) |
|||
) : []; |
|||
}; |
|||
return -1 !== i ? ( |
|||
xs.slice(0, i) |
|||
⚫ | |||
⚫ | |||
// until :: (a -> Bool) -> (a -> a) -> a -> a |
|||
const until = (p, f, x) => { |
|||
let v = x; |
|||
while (!p(v)) v = f(v); |
|||
return v; |
|||
}; |
|||
// MAIN --- |
// MAIN --- |
||
Line 1,977: | Line 1,948: | ||
})();</lang> |
})();</lang> |
||
{{Out}} |
{{Out}} |
||
<pre>["interspecies","interstellar","interstate"] |
<pre>["interspecies","interstellar","interstate"] -> "inters" |
||
["throne","throne"] |
["throne","throne"] -> "throne" |
||
["throne","dungeon"] |
["throne","dungeon"] -> "" |
||
["cheese"] |
["cheese"] -> "cheese" |
||
[""] |
[""] -> "" |
||
["prefix","suffix"] |
["prefix","suffix"] -> "" |
||
["foo","foobar"] |
["foo","foobar"] -> "foo"</pre> |
||
=={{header|jq}}== |
=={{header|jq}}== |