/* The Computer Language Benchmarks Game http://shootout.alioth.debian.org/ contributed by James McIlree */ import java.util.*; import java.io.*; import java.util.concurrent.*; public class knucleotide { String sequence; int count = 1; knucleotide(String sequence) { this.sequence = sequence; } static ArrayList<Callable< Map<String, knucleotide> > > createFragmentTasks(final String sequence, int[] fragmentLengths) { ArrayList<Callable<Map<String, knucleotide>>> tasks = new ArrayList<Callable<Map<String, knucleotide>>>(); for (int fragmentLength : fragmentLengths) { for (int index=0; index<fragmentLength; index++) { final int offset = index; final int finalFragmentLength = fragmentLength; tasks.add(new Callable<Map<String, knucleotide>>() { public Map<String, knucleotide> call() { return createFragmentMap(sequence, offset, finalFragmentLength); } }); } } return tasks; } static Map<String, knucleotide> createFragmentMap(String sequence, int offset, int fragmentLength) { HashMap<String, knucleotide> map = new HashMap<String, knucleotide>(); int lastIndex = sequence.length() - fragmentLength + 1; for (int index=offset; index<lastIndex; index+=fragmentLength) { String temp = sequence.substring(index, index + fragmentLength); knucleotide fragment = (knucleotide)map.get(temp); if (fragment != null) fragment.count++; else map.put(temp, new knucleotide(temp)); } return map; } // Destructive! static Map<String, knucleotide> sumTwoMaps(Map<String, knucleotide> map1, Map<String, knucleotide> map2) { for (Map.Entry<String, knucleotide> entry : map2.entrySet()) { knucleotide sum = (knucleotide)map1.get(entry.getKey()); if (sum != null) sum.count += entry.getValue().count; else map1.put(entry.getKey(), entry.getValue()); } return map1; } static String writeFrequencies(Map<String, knucleotide> frequencies) { ArrayList<knucleotide> list = new ArrayList<knucleotide>(frequencies.size()); int sum = 0; for (knucleotide fragment : frequencies.values()) { list.add(fragment); sum += fragment.count; } Collections.sort(list, new Comparator<knucleotide>() { public int compare(knucleotide o1, knucleotide o2) { int c = o2.count - o1.count; if (c == 0) { c = o1.sequence.compareTo(o2.sequence); } return c; } }); StringBuilder sb = new StringBuilder(); for (knucleotide k : list) sb.append(String.format("%s %.3f\n", k.sequence.toUpperCase(), (float)(k.count) * 100.0f / (double)sum)); return sb.toString(); } static String writeCount(List<Future<Map<String, knucleotide>>> futures, String nucleotideFragment) throws Exception { int count = 0; for (Future<Map<String, knucleotide>> future : futures) { knucleotide temp = future.get().get(nucleotideFragment); if (temp != null) count += temp.count; } return count + "\t" + nucleotideFragment.toUpperCase(); } public static void main (String[] args) throws Exception { String line; BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); while ((line = in.readLine()) != null) { if (line.startsWith(">THREE")) break; } StringBuilder sbuilder = new StringBuilder(); while ((line = in.readLine()) != null) { sbuilder.append(line); } ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); int[] fragmentLengths = { 1, 2, 3, 4, 6, 12, 18 }; List<Future<Map<String, knucleotide>>> futures = pool.invokeAll(createFragmentTasks(sbuilder.toString(), fragmentLengths)); pool.shutdown(); // Print the length 1 & 2 counts. We know the offsets of the tasks, so we can cheat. System.out.println(writeFrequencies(futures.get(0).get())); System.out.println(writeFrequencies(sumTwoMaps(futures.get(1).get(), futures.get(2).get()))); System.out.println(writeCount(futures, "ggt")); System.out.println(writeCount(futures, "ggta")); System.out.println(writeCount(futures, "ggtatt")); System.out.println(writeCount(futures, "ggtattttaatt")); System.out.println(writeCount(futures, "ggtattttaatttatagt")); } }