@SuppressWarnings("unchecked") public static void main(String... args) throws Exception { Stream<String> scrabbleWordsStream = Files.lines(Paths.get("files", "ospd.txt")); Set<String> scrabbleWords = scrabbleWordsStream.map(String::toLowerCase).collect(Collectors.toSet()); Stream<String> shakespeareWordsStream = Files.lines(Paths.get("files", "words.shakespeare.txt")); Set<String> shakespeareWords = shakespeareWordsStream.map(String::toLowerCase).collect(Collectors.toSet()); System.out.println("# de mots autorisés au Scrabble : " + scrabbleWords.size()); // mots utilisés par Shakespeare Long nWords1 = shakespeareWords.stream().count(); System.out.println("# ofmots utilisés par Shakespeare : " + nWords1); // number of words used by Shakespeare and allowed at Scrabble long count = shakespeareWords.stream().map(String::toLowerCase).filter(scrabbleWords::contains).count(); System.out.println("# number of words used by Shakespeare and allowed at Scrabble = " + count); // words of Shakespeare grouped by their length Map<Integer, Long> map1 = shakespeareWords .stream() .collect(Collectors.groupingBy(String::length, Collectors.counting())); System.out.println("Words of Shakespeare grouped by their length = " + map1); // words of Shakespeare of 16 letters and more Map<Integer, List<String>> map2 = shakespeareWords .stream() .filter(word -> word.length() > 15) .collect(Collectors.groupingBy(String::length)); System.out.println("Words of Shakespeare of 16 letters and more = " + map2); // words of Shakespeare grouped by their Scrabble score // in ascending order Function<String, Integer> score = word -> word.chars().map(scrabbleLetterValueEN).sum(); Map<Integer, Long> map3 = shakespeareWords .stream() .map(String::toLowerCase) .filter(scrabbleWords::contains) .collect(Collectors.groupingBy(score, TreeMap::new, Collectors.counting())); System.out.println("Words of Shakespeare grouped by their Scrabble score = " + map3); // words of Shakespeare grouped by their Scrabble score, with a score greater than 29 // in ascending order Predicate<String> scoreGT28 = word -> score.apply(word) > 28; Map<Integer, List<String>> map4 = shakespeareWords .stream() .map(String::toLowerCase) .filter(scrabbleWords::contains) .filter(scoreGT28) .collect(Collectors.groupingBy(score, TreeMap::new, Collectors.toList())); System.out.println("Words of Shakespeare grouped by their Scrabble score = " + map4); // histogram of the letters in a given word Function<String, Map<Integer, Long>> lettersHisto = word -> word.chars() .mapToObj(Integer::new) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); // score of a given word, taking into account that the given word // might contain blank letters Function<String, Integer> scoreWithBlanks = word -> lettersHisto .apply(word) .entrySet() .stream() // Map.Entry<letters, # used> .mapToInt( entry -> scrabbleENScore[entry.getKey() - 'a'] * (int) Long.min( entry.getValue(), scrabbleENDistribution[entry.getKey() - 'a'])) .sum(); // number of blanks used for the given word Function<String, Integer> blanksUsed = word -> lettersHisto .apply(word) .entrySet() .stream() // Map.Entry<letters, # used> .mapToInt( entry -> (int) Long.max( 0L, entry.getValue() - scrabbleENDistribution[entry.getKey() - 'a'])) .sum(); System.out.println("Number of blanks in [buzzards] = " + blanksUsed.apply("buzzards")); System.out.println("Real score of [buzzards] = " + scoreWithBlanks.apply("buzzards")); System.out.println("Number of blanks in [whizzing] = " + blanksUsed.apply("whizzing")); System.out.println("Real score of [whizzing] = " + scoreWithBlanks.apply("whizzing")); // best words of Shakespeare and their scores Map<Integer, List<String>> map = shakespeareWords .stream() .filter(scrabbleWords::contains) .filter(word -> blanksUsed.apply(word) <= 2L) .filter(word -> scoreWithBlanks.apply(word) >= 24) .collect(Collectors.groupingBy(scoreWithBlanks, Collectors.toList())); System.out.println("Best words of Shakespeare : " + map); }