## NPR Sunday Puzzle

### February 19, 2013

[ Today is the fourth anniversary of Programming Praxis, which published five exercises on February 19, 2009. I remember getting 6 hits that day, all of them from one friend that I told about the blog. I get a few more hits now. Many thanks to all of my readers, whose comments and emails inspire me to continue. — Phil ]

We haven’t done a word puzzle for a while. Here is one from the NPR Sunday Puzzle:

Think of two familiar, unhyphenated, eight-letter words that contain the letters A, B, C, D, E and F, plus two others, in any order. What words are these?

Your task is to write a program to find the two words. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

### 15 Responses to “NPR Sunday Puzzle”

1. […] today’s Programming Praxis exercise, our goal is to find two words that consist of the letters A through F […]

```import Data.List

npr :: String -> Bool
npr s = length s == 8 && null ("abcdef" \\ s)

main :: IO ()
main = mapM_ print . filter npr . lines =<< readFile "en_US.dic"
```
3. […] Question is from here: […]

4. Jussi Piitulainen said

Happy birthday.

``` grep -E -x '.{8}' /usr/share/dict/british-english | grep a | grep b | grep c | grep d | grep e | grep f ```

5. […] Pages: 1 2 […]

6. Mike said

Python solution:

```abcdef = set('abcdef')

with open("/12dicts/2of12.txt", "rt") as f:
lines = (line.strip() for line in f)
words = [w for w in lines if len(w) == 8 and abcdef.issubset(w)]
```
7. jpverkamp said

Happy Birthday! Your efforts are most appreciated. :)

Here’s a quick Racket version: NPR Sunday Puzzle

```; find all words containing _chars_ with _length_ characters
(define (words-containing chars [length (length chars)])
(with-input-from-file DICTIONARY
(lambda ()
(for/list ([word (in-lines)]
#:when (and (= length (string-length word))
(andmap (lambda (c) (string-contains? word c)) chars)))
word))))
```

I’ll admit to being a fan of Racket’s `for` family of macros. They certainly make things like this much easier.

8. in python, not as pretty as Mike’s version

```def npr_sunday():
with open("..\wordsEn.txt", "rt") as wordlist:
for word in wordlist:
word = word.strip()
reqs = 'abcdef'
extratwo = ''
for ch in word:
if ch in reqs:
reqs = reqs.replace(ch, '')
elif len(extratwo) < 2:
extratwo = extratwo + ch
else:
break
if reqs == '' and len(extratwo) == 2 and len(word) == 8:
yield word
```
9. Rafa said

argv = sys.argv
fPtr = open(sys.argv, ‘r’)

content = map(lambda x: x.replace(‘\n’,”), fPtr.readlines())
content = filter(lambda x:len(x)==8, content)

for i in range(ord(‘a’),ord(‘g’)):
content = filter(lambda x:chr(i) in x, content)

print content

10. Here’s my solution in C# (Hopefully the link works this time!)

11. Scott said

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.util.Arrays;
import java.util.ArrayList;

public class FindWord {
public static void main(String[] args){
printCorrectWords(getEigthLetterWords());
}

private static void printCorrectWords(ArrayList words) {

for(int i=0;i<words.size();i++){
char[] sepChar = words.get(i).toCharArray();
Arrays.sort(sepChar);
sepChar = removeDoubles(sepChar);

if(sepChar=='a')
if(sepChar=='b')
if(sepChar=='c')
if(sepChar=='d')
if(sepChar=='e')
if(sepChar=='f')
System.out.println(words.get(i));
}
}

private static char[] removeDoubles(char[] sep) {
boolean[] map = new boolean;
char[] result = new char;
int j=0;

for(int i=0;i<sep.length;i++)
map[((int) sep[i]-97)] = true;
for(int i=0;i<25;i++)
if(map[i])
result[j++] = (char) (i+97);

return result;
}

private static ArrayList getEigthLetterWords() {
ArrayList eigthLetterWords = new ArrayList();
try{
FileInputStream fstream = new FileInputStream(“dictionary.txt”);
DataInputStream in = new DataInputStream(fstream);
String str;
while ((str = br.readLine()) != null)
if(str.length()==8)
in.close();
}catch (Exception e){}

return eigthLetterWords;
}
}

12. James said

cat /usr/share/dict/american-english | grep -E “^.{8}\$” | grep -E “a+” | grep -E “b+” | grep -E “c+” | grep -E “d+” | grep -E “e+” | grep -E “f+”

13. gulden said

perl -nle ‘print if /^\w{8}\$/ and /a/ and /b/ and /c/ and /d/ and /e/ and /f/ ‘ /usr/share/dict/linux.words

14. brooknovak said

C# solution using bitwise logic. Since A-F is a contiguous, we can use simple arithmetic to quickly check whether a word has all the required letters + 2 others.

```public static void FindWords(string dictPath) {
if (dictPath == null)
throw new ArgumentNullException ("dictPath");

int found = 0;
string word;
if (word.Length == 8) {
int flags = 0;
int other = 0;
foreach (char c in word.ToLower()) {
if (other > 2)
break;
int rem = 'f' - c;
if (rem >= 0 && rem <= 5) {
int newFlags = flags | (1 << rem);
if (newFlags == flags)
other++;
else
flags = newFlags;
} else {
other++;
}
}
if (other == 2 && flags == 63) {
found ++;
Console.WriteLine ("Found: " + word);
if (found == 2)
return;
}
}
}
}
}
```