ABC words: Difference between revisions

Content added Content deleted
(Added AppleScript solutions.)
Line 328: Line 328:
prefabricate quarterback razorback roadblock sabbatical
prefabricate quarterback razorback roadblock sabbatical
snapback strabismic syllabic tabernacle tablecloth </pre>
snapback strabismic syllabic tabernacle tablecloth </pre>

=={{header|AppleScript}}==
===Core language===
This is a fairly simple solution, hard-coded for "a", "b", and "c". The 'offset' commands are performed by AppleScript's StandardAdditions OSAX, so the time taken by the multiple communications between the script and the OSAX makes the code comparatively slow. Still, the overall running time with the specified file on my current machine is less than 1.5 seconds.
<lang applescript>on abcWords(wordFile)
-- The word file text is assumed to be UTF-8 encoded and to have one word per line.
script o
property wordList : paragraphs of (read wordFile as «class utf8»)
end script
set output to {}
repeat with thisWord in o's wordList
set thisWord to thisWord's contents
if ((thisWord contains "c") and ¬
(text 1 thru (offset of "c" in thisWord) of thisWord contains "b") and ¬
(text 1 thru (offset of "b" in thisWord) of thisWord contains "a")) then ¬
set end of output to thisWord
end repeat
return output
end abcWords

return abcWords(((path to desktop as text) & "www.rosettacode.org:unixdict.txt") as alias)</lang>

{{output}}
<lang applescript>{"aback", "abacus", "abc", "abdicate", "abduct", "abeyance", "abject", "abreact", "abscess", "abscissa", "abscissae", "absence", "abstract", "abstracter", "abstractor", "adiabatic", "aerobacter", "aerobic", "albacore", "alberich", "albrecht", "algebraic", "alphabetic", "ambiance", "ambuscade", "aminobenzoic", "anaerobic", "arabic", "athabascan", "auerbach", "diabetic", "diabolic", "drawback", "fabric", "fabricate", "flashback", "halfback", "iambic", "lampblack", "leatherback", "metabolic", "nabisco", "paperback", "parabolic", "playback", "prefabricate", "quarterback", "razorback", "roadblock", "sabbatical", "snapback", "strabismic", "syllabic", "tabernacle", "tablecloth"}</lang>

The following alternative uses delimiters and text items instead and is considerably faster at around 0.25 seconds. Also, for the hell of it, it takes the characters (or even longer substrings) that the returned words must contain as a parameter. Same output here as above.

<lang applescript>on abcWords(wordFile, theLetters)
-- The word file text is assumed to be UTF-8 encoded and to have one word per line.
script o
property wordList : paragraphs of (read wordFile as «class utf8»)
end script
set output to {}
set letterCount to (count theLetters)
set astid to AppleScript's text item delimiters
repeat with thisWord in o's wordList
set thisWord to thisWord's contents
set thisLetter to end of theLetters
if (thisWord contains thisLetter) then
set matched to true
repeat with c from (letterCount - 1) to 1 by -1
set AppleScript's text item delimiters to thisLetter
set thisLetter to item c of theLetters
set matched to (thisWord's first text item contains thisLetter)
if (not matched) then exit repeat
end repeat
if (matched) then set end of output to thisWord
end if
end repeat
set AppleScript's text item delimiters to astid
return output
end abcWords

return abcWords(((path to desktop as text) & "www.rosettacode.org:unixdict.txt") as alias, {"a", "b", "c"})</lang>

===AppleScriptObjC===
This is faster still at 0.01 seconds and uses AppleScriptObjC to access the regex facilities provided by macOS's Foundation framework. It too takes the characters the returned words must contain as a parameter, but, unlike the script above, doesn't recognise longer substring inputs as units in themselves. Same output as with the two "Core language" scripts above.
<lang applescript>use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"
use scripting additions

on abcWords(wordFile, theLetters)
-- This NSString method used here guesses the word file's text encoding itself.
set wordText to current application's class "NSString"'s stringWithContentsOfFile:(POSIX path of wordFile) ¬
usedEncoding:(missing value) |error|:(missing value)
-- Assuming one word per line, build a regex pattern to match words containing the specified letters in the given order.
set theLetters to join(theLetters, "")
set pattern to "(?mi)^"
repeat with c from 1 to (count theLetters)
set pattern to pattern & (("[^" & text c thru end of theLetters) & ("\\v]*+" & character c of theLetters))
end repeat
set pattern to pattern & ".*+$"
set regexObj to current application's class "NSRegularExpression"'s ¬
regularExpressionWithPattern:(pattern) options:(0) |error|:(missing value)
set wordMatches to regexObj's matchesInString:(wordText) options:(0) range:({0, wordText's |length|()})
set matchRanges to wordMatches's valueForKey:("range")
set output to {}
repeat with thisRange in matchRanges
set end of output to (wordText's substringWithRange:(thisRange)) as text
end repeat
return output
end abcWords

on join(lst, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delim
set txt to lst as text
set AppleScript's text item delimiters to astid
return txt
end join

return abcWords(((path to desktop as text) & "www.rosettacode.org:unixdict.txt") as alias, {"a", "b", "c"})</lang>


=={{header|Arturo}}==
=={{header|Arturo}}==