package com.madbean.kata8.readable; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.HashSet; import java.util.Set; /** * My attempt at a "fast" Kata 8 * * @author Matt Quail * @see Kata 8 */ public class KataEightFast { private static final int FIND_WORD_SIZE = 6; private static final File WORDLIST_FILE = new File("d:/matt/dev/kata8/wordlist.txt"); /** * An array of Sets. The set at index 'i' contains words of length 'i'. */ private ArrayList wordSets = new ArrayList(10); public static void main(String[] args) throws IOException { KataEightFast program = new KataEightFast(); program.readwords(); program.scanForConcatenatedWords(); } private void readwords() throws IOException { BufferedReader in = new BufferedReader(new FileReader(WORDLIST_FILE)); String word; while (null != (word = in.readLine())) { // the example in Kata 8 suggests that we are ment to // ignore case; so just make everything lowercase word = word.toLowerCase(); int len = word.length(); // grow wordSets to length 'len', initing with HashSets for (int i = wordSets.size(); i <= len; i++) { wordSets.add(new HashSet()); } Set set = (Set) wordSets.get(len); set.add(word); } in.close(); } private void scanForConcatenatedWords() { int matchCount = 0; Set findWords = (Set) wordSets.get(FIND_WORD_SIZE); for (Iterator i = findWords.iterator(); i.hasNext();) { String word = (String) i.next(); // look at the leading substrings of 'word' (and the // corresponding trailing substring), and see if said // leading and trailing substrings are actual words final int leadingMinLen = 1; final int leadingMaxLen = word.length() - 1; for (int leadingSize = leadingMinLen; leadingSize <= leadingMaxLen; leadingSize++) { String leadingWord = word.substring(0, leadingSize); String trailingWord = word.substring(leadingSize); Set leadingSet = (Set) wordSets.get(leadingWord.length()); Set trailingSet = (Set) wordSets.get(trailingWord.length()); if (leadingSet.contains(leadingWord) && trailingSet.contains(trailingWord)) { // 'word' is the concatenation of 'leadingWord' and 'trailingWord' System.out.println(leadingWord + " + " + trailingWord + " = " + word); matchCount++; } } } System.out.println("number found: " + matchCount); } }