dictionary lookups of words composed of specified characters
I might be wrong, but I believe the answer is simple when you look at it from a different view. Let's say we want to create a function, that gives us False
if your conditions are not met. So your word must contain at least one "N", if not then it's definitely out:
isGood[str_String /; StringFreeQ[str, "N", IgnoreCase -> True]] := False;
And then you say, it can only consist of the other letters. So what will happen, if we replace in a word all your good letters by "". A word you are interested in will afterward contain nothing at all, right? Let's write this down:
isGood[str_String] :=
StringReplace[
str, {"A" -> "", "C" -> "", "D" -> "", "H" -> "", "I" -> "",
"R" -> "", "N" -> ""}, IgnoreCase -> True] === ""
Ready to rock I guess:
words = DictionaryLookup["*"];
Select[words, isGood]
(*
{"Adan", "Adana", "Adrian", "Adriana", "an", "Ana", "Anacin", \
"anarchic", "and", "Ann", "Anna", "arachnid", "Arcadian", "arcana", \
"Cain", "cairn", "can", "Canaan", "Canada", "Canadian", "canard", \
"cancan", "candid", "candida", "Cardin", "Carina", "Chadian", \
"chain", "Chan", "Chandra", "Chicana", "chin", "china", "China", \
"cinch", "circadian", "cnidarian", "CNN", "Cranach", "Dan", "Dana", \
"Darin", "darn", "Darrin", "Diana", "Diann", "Dianna", "din", "Dina", \
"Dinah", "dinar", "DNA", "drain", "Hadrian", "Hahn", "Han", "hand", \
"handcar", "Hanna", "Hannah", "Hardin", "harridan", "hind", "Hindi", \
"Ian", "Icahn", "in", "Ina", "Inca", "inch", "India", "Indian", \
"Indiana", "Indianan", "Indianian", "Indira", "Indra", "inn", "Iran", \
"Iranian", "Nadia", "nadir", "nah", "naiad", "Nair", "nan", "Nan", \
"Nara", "narc", "Narnia", "NCAA", "niacin", "Nina", "radian", "rain", \
"ran", "ranch", "rancid", "rand", "Rand", "Randi", "rind"}
*)
patt = w : Alternatives["A", "C", "D", "H", "I", "R", "N"] .. /;
StringCount[w, "N", IgnoreCase -> True] == 1;
DictionaryLookup[patt, IgnoreCase -> True]
(*
{"Adan", "Adana", "Adrian", "Adriana", "an", "Ana", "anarchic", \
"and", "arachnid", "Arcadian", "arcana", "Cain", "cairn", "can", \
"Canada", "canard", "candid", "candida", "Cardin", "Carina", \
"Chadian", "chain", "Chan", "Chandra", "Chicana", "chin", "china", \
"China", "cinch", "circadian", "Cranach", "Dan", "Dana", "Darin", \
"darn", "Darrin", "Diana", "din", "Dina", "Dinah", "dinar", "DNA", \
"drain", "Hadrian", "Hahn", "Han", "hand", "handcar", "Hardin", \
"harridan", "hind", "Hindi", "Ian", "Icahn", "in", "Ina", "Inca", \
"inch", "India", "Indira", "Indra", "Iran", "Nadia", "nadir", "nah", \
"naiad", "Nair", "Nara", "narc", "NCAA", "radian", "rain", "ran", \
"ranch", "rancid", "rand", "Rand", "Randi", "rind"}
*)
This can also be used with lists of words, using Pick[candidates, StringMatchQ[candidates, patt]]
.
After reading Mr.Wizard's answer I noticed I had missed or misread some requirements. This is my updated version:
letters = Alternatives["A", "C", "D", "H", "I", "R", "N"];
patt = w : (letters ... ~~ "N" ~~ letters ...) /; StringLength[w] == 7;
DictionaryLookup[patt, IgnoreCase -> True]
(*
{"Adriana", "candida", "Chadian", "Chandra", "Chicana", "Cranach", \
"Hadrian", "handcar", "Indiana", "Iranian"}
*)
I independently arrived at code similar to Pickett's answer:
DictionaryLookup[
x : Repeated["A"|"C"|"D"|"H"|"I"|"R"|"N", {7}] /; StringMatchQ[x, "*n*"],
IgnoreCase -> True
]
{"Adriana", "candida", "Chadian", "Chandra", "Chicana", "Cranach", "Hadrian", "handcar", "Indiana", "Iranian"}