Change e letters to i in words: Difference between revisions

Content deleted Content added
Added Rust solution
Nig (talk | contribs)
Added two AppleScript solutions.
Line 173: Line 173:
welles -> willis
welles -> willis
</pre>
</pre>

=={{header|AppleScript}}==
===Core language only===
A ''literal'' implementation of the task using only vanilla AppleScript takes about two minutes to run on my current machine, most of the time being taken with checking the many changed words against the huge original list. The time's reduced to just under ten seconds here by instead checking the words against a much smaller list containing only words which may actually match. To this end, the original list is worked through in descending lexical order so that words containing "i" are encountered before any containing "e" from which they can be derived. Words containing "i" but not "e" are stored. Words containing "e" are modified and the results only checked against the "i" words stored so far.

<lang applescript>use AppleScript version "2.3.1" -- Mac OS X 10.9 (Mavericks) or later.
use sorter : script "Custom Iterative Ternary Merge Sort" -- <https://macscripter.net/viewtopic.php?pid=194430#p194430>
use scripting additions

on task(minWordLength)
set dictPath to (path to desktop as text) & "unixdict.txt"
script o
property wordList : paragraphs of (read file dictPath as «class utf8»)
property iWords : {}
property output : {}
end script
set wordCount to (count o's wordList)
tell sorter to sort(o's wordList, 1, wordCount, {}) -- Not actually needed with unixdict.txt.
set astid to AppleScript's text item delimiters
repeat with i from wordCount to 1 by -1
set thisWord to item i of o's wordList
if ((count thisWord) < minWordLength) then
else if (thisWord contains "e") then
set AppleScript's text item delimiters to "e"
set tis to thisWord's text items
set AppleScript's text item delimiters to "i"
set changedWord to tis as text
if (changedWord is in o's iWords) then set beginning of o's output to {thisWord, changedWord}
else if (thisWord contains "i") then
set end of o's iWords to thisWord
end if
end repeat
set AppleScript's text item delimiters to astid
return o's output
end task

task(6)</lang>

{{output}}
<lang applescript>{{"analyses", "analysis"}, {"atlantes", "atlantis"}, {"bellow", "billow"}, {"breton", "briton"}, {"clench", "clinch"}, {"convect", "convict"}, {"crises", "crisis"}, {"diagnoses", "diagnosis"}, {"enfant", "infant"}, {"enquiry", "inquiry"}, {"frances", "francis"}, {"galatea", "galatia"}, {"harden", "hardin"}, {"heckman", "hickman"}, {"inequity", "iniquity"}, {"inflect", "inflict"}, {"jacobean", "jacobian"}, {"marten", "martin"}, {"module", "moduli"}, {"pegging", "pigging"}, {"psychoses", "psychosis"}, {"rabbet", "rabbit"}, {"sterling", "stirling"}, {"synopses", "synopsis"}, {"vector", "victor"}, {"welles", "willis"}}</lang>

===AppleScriptObjC===
The Foundation framework has very fast filters for arrays, but a similar reduction of checklist size can be applied. The order of words doesn't matter here, but it turns out that modifying them with vanilla AppleScript is faster than using Foundation methods. This version only takes about half a second. Same result as above:

<lang applescript>use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"
use scripting additions

on task(minWordLength)
set |⌘| to current application
set dictPath to (POSIX path of (path to desktop)) & "unixdict.txt"
set dictText to |⌘|'s class "NSString"'s stringWithContentsOfFile:(dictPath) ¬
usedEncoding:(missing value) |error|:(missing value)
set newlineSet to |⌘|'s class "NSCharacterSet"'s newlineCharacterSet()
set wordArray to dictText's lowercaseString()'s componentsSeparatedByCharactersInSet:(newlineSet)
set filter to |⌘|'s class "NSPredicate"'s ¬
predicateWithFormat:("(self MATCHES '.{" & minWordLength & ",}+') && (self CONTAINS 'e')")
script o
property eWords : (wordArray's filteredArrayUsingPredicate:(filter)) as list
property changes : {}
end script
set astid to AppleScript's text item delimiters
repeat with thisWord in o's eWords
set thisWord to thisWord's contents
set AppleScript's text item delimiters to "e"
set tis to thisWord's text items
set AppleScript's text item delimiters to "i"
set end of o's changes to {thisWord, tis as text}
end repeat
set AppleScript's text item delimiters to astid
set filter to |⌘|'s class "NSPredicate"'s ¬
predicateWithFormat:("(self MATCHES '.{" & minWordLength & ",}+') && (self CONTAINS 'i') && !(self CONTAINS 'e')")
set iWords to wordArray's filteredArrayUsingPredicate:(filter)
set output to |⌘|'s class "NSMutableArray"'s arrayWithArray:(o's changes)
set filter to |⌘|'s class "NSPredicate"'s predicateWithFormat_("self[1] IN %@", iWords)
tell output to filterUsingPredicate:(filter)
return output as list
end task

task(6)</lang>

=={{header|AWK}}==
=={{header|AWK}}==
<lang AWK>
<lang AWK>