import java.io.*;
import java.util.*;

/** A possible hash function. Experiment to see how hash functions scatter 
    randomly a set of names.
 */
public class Hash
{
    /** Given a string name, return its hash in the range
        0 .. n-1.
     */
    public static int hash(String name, int n) {
	final int PRIME = 503;
	int val = 0;
	for (int k = 0; k < name.length(); k++) {
	    char c = name.charAt(k); 
	    val = PRIME*val + (int)c;
	}
	return Math.abs(val % n);
    }

    public static void main(String[] args) {
	if (args.length != 1) {
	    System.out.println("usage: java Hash filename");
	    return;
	}
	ArrayList<String> a = new ArrayList<String>();
	try {
	    Scanner sc = null;
	    try {
		sc = new Scanner(new File (args[0]));
		while (sc.hasNext()) {
		    String name = sc.next();
		    a.add(name);
		}
	    } finally {
		if (sc != null)
		    sc.close();
	    }
	} catch (FileNotFoundException e) {
	    System.out.println(e.getMessage());
	    e.printStackTrace();
	    return;
	} catch (IOException e) {
	    System.out.println(e.getMessage());
	    e.printStackTrace();
	    return;
	}
	System.out.println("   Name       our.hash");
	int n = (int)(a.size()*1.25);
	for (String name: a)
	    System.out.printf("%9s  %8d\n", name, hash(name, n));
    }
}
/* The output of the program, on a sample test file, is
   Name       our.hash
 bojarsky         4
     camp         8
   hariry        14
      kim        12
  liberty         3
lunagaria         8
mavrichev         0
    patel        14
  pearson         1
    vogel        11
 williams        14
   wisner        13
Note that there are 12 names. In correspondence we have 9 hash values
in the range 0..14. Six names have a unique hash. Two names share the
hash 8. Three names share the hash 14.
*/
