import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * The key is to find the duplicates in pattern
 * I cannot came out a better solution than using RegEx
 * <p/>
 * Created by Kevin on 10/28/14.
 */
public class WordPattern {

    /**
     * @param pattern
     * @param input
     * @return
     */
    static int wordpattern(String pattern, String input) {
        if (pattern == null || input == null || pattern.isEmpty() || input.isEmpty())
            return 0;

        HashMap<Character, Integer> chrMap = new HashMap<>();
        HashSet<Character> mapped = new HashSet<>();
        // first scan the pattern
        char[] patternChrs = pattern.toCharArray();
        int group = 0;  // group index
        for (int i = 0; i < patternChrs.length; i++) {
            if (!chrMap.containsKey(patternChrs[i])) {
                chrMap.put(patternChrs[i], ++group);
            }
        }

        StringBuilder sb = new StringBuilder();
        sb.append("^");
        for (int i=0; i< patternChrs.length;i++) {
            if (!mapped.contains(patternChrs[i])) {
                sb.append("(.+)");
                mapped.add(patternChrs[i]);
            } else {
                sb.append("\\").append(chrMap.get(patternChrs[i]));
            }
        }
        sb.append("$");

        Pattern regex = Pattern.compile(sb.toString());
        Matcher matcher = regex.matcher(input);
        if (matcher.find()) {
            for (int i=1; i<=group;i++) {
                for (int j=i+1;j<=group; j++) {
                    if (matcher.group(i).equals(matcher.group(j)))
                        return 0;
                }
            }
            return 1;
        }
        return 0;
    }


    /**
     *
     * Java 7 version, use named group directly
     *
     * @param pattern
     * @param input
     * @return
     */
    static int wordpattern2(String pattern, String input) {
        if (pattern == null || input == null || pattern.isEmpty() || input.isEmpty())
            return 0;

        HashSet<Character> charSet = new HashSet();
        StringBuilder sb = new StringBuilder();
        sb.append("^");
        // first scan the pattern
        char[] patternChrs = pattern.toCharArray();
        for (char chr:patternChrs) {
            if (!charSet.contains(chr)) {
                charSet.add(chr);
                sb.append("(?<").append(chr).append(">.+)");
            } else {
                sb.append("\\k<").append(chr).append(">");
            }
        }
        sb.append("$");

        Pattern regex = Pattern.compile(sb.toString());
        Matcher matcher = regex.matcher(input);
        if (matcher.find()) {
            Character[] chrs = new Character[charSet.size()];
            chrs = charSet.toArray(chrs);
            for (int i=0; i< chrs.length;i++) {
                for (int j=i+1; j<chrs.length;j++) {
                    if (matcher.group(""+chrs[i]).equals(matcher.group(""+chrs[j])))
                        return 0;
                }
            }
            return 1;
        }
        return 0;
    }
}
