Left-Handed Words
December 6, 2013
This exercise cries out for a regular-expression solution. Here is an awk one-liner:
awk '/^[QWERTASDFGZXCVB]*$/' words
If you don’t want to use regular expressions, you could define the alphabet like this:
(define left (string->list "QWERTASDFGZXCVB"))
Then a function left? determines if a word is left-handed, using the all? function from the Standard Prelude:
(define (left? word)
(all? (lambda (c) (member c left))
(string->list word)))
Then it’s just a matter of reading a word list and discarding those words that aren’t left?:
(with-input-from-file "words"
(lambda ()
(do ((word (read) (read))) ((eof-object? word))
(when (left? (symbol->string word))
(display word) (newline)))))
Either of the two functions prints the word list instantly; there is no discernible difference in the time taken, since the computation is I/O bound.
You can see the program at http://programmingpraxis.codepad.org/JKXQRIS5.
This grep takes running text as input and prints each match on its own line. The -o does that.
grep -Eio '\b[qwertasdfgzxcvb]+\b'
I wanted to use the -w option but it had a problem with a couple of (right-handed) Finnish letters. It’s possible that the boundary markers in the above expression still have a related problem with the same letters. Maybe in yet another decade letters will finally be letters, reliably.
Finnish seems to be a fairly right-handed language. We use all of the right-handed letters all the time (except the Swedish å), we don’t use qwzxc natively at all, and bf are somewhat marginal.
In Python. A good opportunity to look at regular expressions. I seldom use these.
import re p = re.compile(r'\b[QWERTASDFGZXCVB]+\b', re.IGNORECASE) with open(fname) as f: for w in p.findall(f.read()): print wI decided to forgo regular expressions for a simple set.
left_chars = set('qwertasdfgzxcv')
left_words = []
for word in open('/usr/share/dict/words'):
if all([c in left_chars for c in word.strip().lower()]):
left_words.append(word)
print(left_words)
def valid_word(word1):
validW = “qwertasdfgzxcvb”
for index1 in range(len(word1)):
if word1[index1] not in validW:
return False
elif index1 == len(word1)-1:
print word1
valid_word(“farter”)
(defun left-handed-letter-p (c) (find c "qwertasdfgzxcvb" :test #'char-equal)) (defun left-handed-word-p (word) (every #'left-handed-letter-p word)) (defun dict-file-to-left-handed-words (file) (with-open-file (dict file) (loop :for line := (read-line dict nil :eof) :until (eq line :eof) :if (left-handed-word-p line) :collect line))) (length (dict-file-to-left-handed-words "/usr/share/dict/words")) => 2797In Haskell.
http://codepad.org/Dqtj2BhE
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LeftHandWords {
public boolean isLeftHandWord(String word) {
Pattern pattern = Pattern.compile("[yuiophjklnm]");
Matcher matcher = pattern.matcher(word);
if (matcher.find()) {
System.out.println("It’s not a left-handed word.");
System.out
.printf("I found the text \"%s\" starting at index %d and ending at index %d.%n",
matcher.group(), matcher.start(), matcher.end());
return true;
} else {
System.out.println("It’s a left-handed word.");
return false;
}
}
public static void main(String[] args) {
LeftHandWords lhw = new LeftHandWords();
lhw.isLeftHandWord("hello");
}
}
import java.util.regex.Matcher; import java.util.regex.Pattern; public class LeftHandWords { public boolean isLeftHandWord(String word) { Pattern pattern = Pattern.compile("[yuiophjklnm]"); Matcher matcher = pattern.matcher(word); if (matcher.find()) { System.out.println("It's not a left-handed word."); System.out .printf("I found the text \"%s\" starting at index %d and ending at index %d.%n", matcher.group(), matcher.start(), matcher.end()); return true; } else { System.out.println("It's a left-handed word."); return false; } } public static void main(String[] args) { LeftHandWords lhw = new LeftHandWords(); lhw.isLeftHandWord("hello"); } }Clojure…
(def keys #{"q" "w" "e" "r" "t" "a" "s" "d" "f" "g" "z" "x" "c" "v" "b"}) (defn all-true? [props] (every? true? props)) (defn left-hand-word? [word] (all-true? (map (fn [x] (contains? keys x)) (drop 1 (clojure.string/split word #"")))))In guile scheme: http://community.schemewiki.org/?left-handed
easier clojure:
(map #(every? #{\q \w \e \r \t \a \s \d \f \g \z \x \c \v \b} %) ["hello" "fast" "zylophone" "sweatervest" "south" "zebras"])