import java.util.Scanner; import java.io.*; import java.net.*; class LangClass { protected FreqRank[] freqs; private String[] langNames; protected int numLangs; protected int maxVal; static int[] ngwt; public LangClass() { int[] temp = {-1, 1, 1, 1, 1}; ngwt = temp; }; public LangClass(Scanner config, URL base) { int[] temp = {-1, 1, 1, 1, 1}; ngwt = temp; init(config, base); } public static void setNGWT(int[] newN) { if (newN.length < 5) { return; // too short } ngwt = newN; } public boolean init(Scanner cfg, URL base) { numLangs = cfg.nextInt(); langNames = new String[numLangs]; freqs = new FreqRank[numLangs]; maxVal = 0; // The penalty for a miss. This needs thought. for (int i = 0; i < numLangs; i++) { langNames[i] = cfg.next(); try { freqs[i] = new FreqRank(new Scanner(new URL(base,"data/"+langNames[i]+".frq").openStream())); } catch (MalformedURLException e) { System.out.println("I fucked up."); freqs[i] = null; } catch (IOException e) { System.out.println("Knuth fucked up."); System.out.println(e); freqs[i] = null; } maxVal += freqs[i].size(); } maxVal /= numLangs; System.out.println("Miss penalty is " +maxVal); return true; } public int[] analyze(FreqRank input, boolean universalMiss) { int[] dists = new int[numLangs]; for (int i = 0; i < numLangs; i++) { dists[i] = getDist(input, freqs[i], maxVal, universalMiss); } return dists; } public static void main(String[] args) throws FileNotFoundException { //Following line broken pending other fix. LangClass l = new LangClass(new Scanner(new File("langs.cfg")), null); int[] dists = l.analyze(Parser.analyze(new Scanner(System.in)), true); int minDist = Integer.MAX_VALUE; int minDisti = -1; int min2Dist = Integer.MAX_VALUE; int min2Disti = -1; int min3Dist = Integer.MAX_VALUE; int min3Disti = -1; for (int i = 0; i < l.numLangs; i++) { if (dists[i] < min3Dist) { min3Dist = dists[i]; min3Disti = i; if (min3Dist < min2Dist) { int temp = min3Dist; min3Dist = min2Dist; min2Dist = temp; temp = min3Disti; min3Disti = min2Disti; min2Disti = temp; if (dists[i] < minDist) { temp = min2Dist; min2Dist = minDist; minDist = temp; temp = min2Disti; min2Disti = minDisti; minDisti = temp; } } } } float conf1 = 1.0f - ((float)minDist)/min2Dist; float conf2 = ((float)minDist)/min2Dist * conf1; float conf3 = ((float)minDist)/min3Dist * conf1; System.out.println(l.langNames[minDisti] +" " +conf1); System.out.println(l.langNames[min2Disti] +" " +conf2); System.out.println(l.langNames[min3Disti] +" " +conf3); } //NB: The distance between any two points is NOT SYMMETRIC. //Thus this is NOT A METRIC. public static int getDist(FreqRank f, FreqRank g, int maxVal, boolean universalMiss) { int runTot = 0; for (int i = 0; i < f.size(); i++) { Integer d = g.getIndex(f.getString(i)); int ngl = f.getString(i).length(); int thisTime; if (universalMiss) { thisTime = ((d == null) ? maxVal : Math.abs(d-i)); } else { thisTime = ((d == null) ? g.size() : Math.abs(d-i)); } runTot += thisTime*ngwt[ngl]; } return runTot; } }