Anagrams: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Haskell}}: wouldn't it be easier to just keep track of the word rather than the index?)
(added java)
Line 1: Line 1:
{{task|Text processing}}
{{task|Text processing}}
Two or more words can be composed of the same characters, but in a different order. Using the word list at http://www.puzzlers.org/pub/wordlists/unixdict.txt, find the sets of words that share the same characters that contain the most words in them.
Two or more words can be composed of the same characters, but in a different order. Using the word list at http://www.puzzlers.org/pub/wordlists/unixdict.txt, find the sets of words that share the same characters that contain the most words in them.

=={{header|Java}}==
<java>import java.net.*;
import java.io.*;
import java.util.*;
public class WordsOfEqChars {
public static void main(String[] args) throws IOException {
URL url = new URL("http://www.puzzlers.org/pub/wordlists/unixdict.txt");
InputStreamReader isr = new InputStreamReader(url.openStream());
BufferedReader reader = new BufferedReader(isr);

Map<String, Collection<String>> anagrams = new HashMap<String, Collection<String>>();
String word;
int count = 0;
while ((word = reader.readLine()) != null) {
char[] chars = word.toCharArray();
Arrays.sort(chars);
String key = new String(chars);
if (!anagrams.containsKey(key))
anagrams.put(key, new ArrayList<String>());
anagrams.get(key).add(word);
count = Math.max(count, anagrams.get(key).size());
}

reader.close();

for (Collection<String> ana : anagrams.values())
if (ana.size() >= count)
System.out.println(ana);
}
}</java>
Output:
[angel, angle, galen, glean, lange]
[elan, lane, lean, lena, neal]
[alger, glare, lager, large, regal]
[abel, able, bale, bela, elba]
[evil, levi, live, veil, vile]


== {{header|Haskell}} ==
== {{header|Haskell}} ==

Revision as of 22:41, 26 September 2008

Task
Anagrams
You are encouraged to solve this task according to the task description, using any language you may know.

Two or more words can be composed of the same characters, but in a different order. Using the word list at http://www.puzzlers.org/pub/wordlists/unixdict.txt, find the sets of words that share the same characters that contain the most words in them.

Java

<java>import java.net.*; import java.io.*; import java.util.*;

public class WordsOfEqChars {

   public static void main(String[] args) throws IOException {
       URL url = new URL("http://www.puzzlers.org/pub/wordlists/unixdict.txt");
       InputStreamReader isr = new InputStreamReader(url.openStream());
       BufferedReader reader = new BufferedReader(isr);
       Map<String, Collection<String>> anagrams = new HashMap<String, Collection<String>>();
       String word;
       int count = 0;
       while ((word = reader.readLine()) != null) {
           char[] chars = word.toCharArray();
           Arrays.sort(chars);
           String key = new String(chars);
           if (!anagrams.containsKey(key))
               anagrams.put(key, new ArrayList<String>());
           anagrams.get(key).add(word);
           count = Math.max(count, anagrams.get(key).size());
       }
       reader.close();
       for (Collection<String> ana : anagrams.values())
           if (ana.size() >= count)
               System.out.println(ana);
   }   

}</java> Output:

[angel, angle, galen, glean, lange]
[elan, lane, lean, lena, neal]
[alger, glare, lager, large, regal]
[abel, able, bale, bela, elba]
[evil, levi, live, veil, vile]

Haskell

import Data.List

groupon f x y = (f x) == (f y)

main = do
  f <- readFile "./../Puzzels/Rosetta/unixdict.txt"
  let  words = lines f
       wix = groupBy (groupon fst) . sort $ zipWith ((,).sort) words words
       mxl = foldl' ((.length).max) 0 wix
  print . map (map snd) . filter ((==mxl).length) $ wix

J

   (#~a:~:{:"1)(]/.~/:~&>)<;.2]1!:1<'unixdict.txt'
+-----+-----+-----+-----+-----+
|abel |able |bale |bela |elba |
+-----+-----+-----+-----+-----+
|alger|glare|lager|large|regal|
+-----+-----+-----+-----+-----+
|angel|angle|galen|glean|lange|
+-----+-----+-----+-----+-----+
|caret|carte|cater|crate|trace|
+-----+-----+-----+-----+-----+
|elan |lane |lean |lena |neal |
+-----+-----+-----+-----+-----+
|evil |levi |live |veil |vile |
+-----+-----+-----+-----+-----+

Python

Python 2.5 shell input (IDLE) <python>>>> import urllib >>> from collections import defaultdict >>> words = urllib.urlopen('http://www.puzzlers.org/pub/wordlists/unixdict.txt').read().split() >>> len(words) 25104 >>> anagram = defaultdict(list) # map sorted chars to anagrams >>> for word in words: anagram[str(sorted(word))].append( word )


>>> count, max_anagrams = max((len(ana), ana) for ana in anagram.itervalues()) >>> for ana in anagram.itervalues(): if len(ana) >= count: print ana


['caret', 'carte', 'cater', 'crate', 'trace'] ['alger', 'glare', 'lager', 'large', 'regal'] ['evil', 'levi', 'live', 'veil', 'vile'] ['angel', 'angle', 'galen', 'glean', 'lange'] ['elan', 'lane', 'lean', 'lena', 'neal'] ['abel', 'able', 'bale', 'bela', 'elba'] >>> count 5 >>></python>