/* I before E except after C (Rosetta code) in Picat. http://rosettacode.org/wiki/I_before_E_except_after_C """ The phrase "I before E, except after C" is a widely known mnemonic which is supposed to help when spelling English words. https://en.wikipedia.org/wiki/I_before_E_except_after_C Task Using the word list from http://wiki.puzzlers.org/pub/wordlists/unixdict.txt, check if the two sub-clauses of the phrase are plausible individually: - "I before E when not preceded by C" - "E before I when preceded by C" If both sub-phrases are plausible then the original phrase can be said to be plausible. Something is plausible if the number of words having the feature is more than two times the number of words having the opposite feature (where feature is 'ie' or 'ei' preceded or not by 'c' as appropriate). Stretch goal As a stretch goal use the entries from the table of Word Frequencies in Written and Spoken English: based on the British National Corpus, (selecting those rows with three space or tab separated words only), to see if the phrase is plausible when word frequencies are taken into account. Show your output here as well as your program. """ This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. main => go. go => Words = read_file_lines("unixdict.txt"), IEWords = [Word : Word in Words, find(Word,"ie",_,_)], EIWords = [Word : Word in Words, find(Word,"ei",_,_)], % cie vs not cie [CIE_len, CIE_not_len] = partition_len(IEWords,"cie"), println([cie=CIE_len,cie_not=CIE_not_len]), % cei vs not cei [CEI_len, CEI_not_len] = partition_len(EIWords,"cei"), println([cei=CEI_len,cei_not=CEI_not_len]), nl, printf("I before E when not preceeded by C (%d vs %d): %w\n", CIE_not_len,CEI_not_len,plausible(CIE_not_len,CEI_not_len)), printf("E before I when preceeded by C (%d cs %d): %w\n", CEI_len,CIE_len,plausible(CEI_len,CIE_len)). plausible(Len1,Len2) = cond(Len1 / Len2 > 2,"plausible","not plausible"). partition_len(Words,Sub) = [True.len, False.len] => True = [], False = [], foreach(Word in Words) if find(Word,Sub,_,_) then True := [Word|True] else False := [Word|False] end end.