Ordered words: Difference between revisions
Content added Content deleted
No edit summary |
(→{{header|Python}}: Added a version using functools.reduce in place of `for` and `sort`) |
||
Line 3,097: | Line 3,097: | ||
'''Sample Output''' |
'''Sample Output''' |
||
<pre>abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty</pre> |
<pre>abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty</pre> |
||
===Python: As a fold=== |
|||
{{Works with|Python|3.7}} |
|||
<lang python>'''The longest ordered words in a list''' |
|||
from itertools import dropwhile |
|||
from functools import reduce |
|||
import urllib.request |
|||
import operator |
|||
# longestOrds :: [String] -> [String] |
|||
def longestOrds(ws): |
|||
'''The longest ordered words in a given list. |
|||
''' |
|||
lng, xs = reduce(triage, ws, (0, [])) |
|||
gt = curry(operator.gt) |
|||
return dropwhile( |
|||
compose((gt)(lng))(len), |
|||
xs |
|||
) |
|||
# triage :: (Int, [String]) -> String -> (Int, [String]) |
|||
def triage(nxs, w): |
|||
'''The maximum length seen for an ordered word, |
|||
and the long ordered words seen so far, |
|||
including this word if it is both ordered and |
|||
no shorter than the maximum so far. |
|||
''' |
|||
n, xs = nxs |
|||
lng = len(w) |
|||
return ( |
|||
(lng, xs + [w]) if ordWord(w) else nxs |
|||
) if lng >= n else nxs |
|||
# ordWord :: String -> Bool |
|||
def ordWord(w): |
|||
'''True if the word w is ordered.''' |
|||
return reduce(stillRising, w[1:], (True, w[0]))[0] |
|||
# stillRising :: (Bool, Char) -> Char -> (Bool, Char) |
|||
def stillRising(bc, x): |
|||
'''A boolean value paired with the current character. |
|||
The boolean is true if no character in the word |
|||
so far has been alphabetically lower than its |
|||
predecessor. |
|||
''' |
|||
b, c = bc |
|||
return ((x >= c) if b else b, x) |
|||
# TEST ---------------------------------------------------- |
|||
def main(): |
|||
'''Test with an on-line word list.''' |
|||
print( |
|||
'\n'.join(longestOrds( |
|||
urllib.request.urlopen( |
|||
'http://wiki.puzzlers.org/pub/wordlists/unixdict.txt' |
|||
).read().decode("utf-8").split() |
|||
)) |
|||
) |
|||
# GENERIC ------------------------------------------------- |
|||
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c |
|||
def compose(g): |
|||
'''Right to left function composition.''' |
|||
return lambda f: lambda x: g(f(x)) |
|||
# curry :: ((a, b) -> c) -> a -> b -> c |
|||
def curry(f): |
|||
'''A curried function derived |
|||
from an uncurried function.''' |
|||
return lambda a: lambda b: f(a, b) |
|||
# MAIN --- |
|||
if __name__ == '__main__': |
|||
main()</lang> |
|||
{{Out}} |
|||
<pre>abbott |
|||
accent |
|||
accept |
|||
access |
|||
accost |
|||
almost |
|||
bellow |
|||
billow |
|||
biopsy |
|||
chilly |
|||
choosy |
|||
choppy |
|||
effort |
|||
floppy |
|||
glossy |
|||
knotty</pre> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |