Tuesday, August 5, 2008

TopCoder: UserName

URL

http://www.topcoder.com/stat?c=problem_statement&pm=2913&rd=5849

Problem Statement


You are implementing the member registration system of an online dating site. When a new member signs up, it is possible that she initially chooses the same username as an existing member. The system must then inform the new member of the conflict and suggest a variant of the chosen name with a number attached to the end.

If an existing member is named "FunkyMonkey", for example, and a new member wants the same username, the simplest suggestion the system can make is "FunkyMonkey1". If there is already a member by that name, the system must suggest "FunkyMonkey2", unless that variant is also taken. If all names from "FunkyMonkey1" through "FunkyMonkey9" are taken as well as the original "FunkyMonkey", the system moves on to consider "FunkyMonkey10", and so on. The goal is to use the smallest possible number in the variant. Note that each username consists of letters (the characters from 'a' to 'z' and from 'A' to 'Z') and numerals ('0' to '9').

You are given a String[], existingNames, containing all usernames that have already been registered in the system. You are also given a single String, newName, containing the username that a new member wants to use. In the event of a conflict, this member will accept the suggestion offered by your system in accordance with the principles above. Return a String containing the username finally assigned to the new member.


Definition


Class:UserName
Method:newMember
Parameters:String[], String
Returns:String
Method signature:String newMember(String[] existingNames, String newName)
(be sure your method is public)



Notes

-The constraints rule out names that end in a number with a leading zero, such as "grokster006" and "bart0".

Constraints

-existingNames contains between 1 and 50 elements, inclusive
-each element of existingNames is between 1 and 50 characters long, inclusive
-the only characters permitted in elements of existingNames are 'a' to 'z', 'A' to 'Z', and '0' to '9'
-no element of existingNames ends in a number that has a leading zero
-newName is between 1 and 50 characters long, inclusive
-the only characters permitted in newName are 'a' to 'z' and 'A' to 'Z'

Examples

0)

{"MasterOfDisaster", "DingBat", "Orpheus", "WolfMan", "MrKnowItAll"}
"TygerTyger"
Returns: "TygerTyger"
"TygerTyger" is available.
1)

{"MasterOfDisaster", "TygerTyger1", "DingBat", "Orpheus",
"TygerTyger", "WolfMan", "MrKnowItAll"}
"TygerTyger"
Returns: "TygerTyger2"
"TygerTyger" and "TygerTyger1" are taken.
2)

{"TygerTyger2000", "TygerTyger1", "MasterDisaster", "DingBat",
"Orpheus", "WolfMan", "MrKnowItAll"}
"TygerTyger"
Returns: "TygerTyger"
There are higher-numbered variants of "TygerTyger", but the base name is available.
3)

{"grokster2", "BrownEyedBoy", "Yoop", "BlueEyedGirl",
"grokster", "Elemental", "NightShade", "Grokster1"}
"grokster"
Returns: "grokster1"
Note that "Grokster1" is not the same as "grokster1".
4)

{"Bart4", "Bart5", "Bart6", "Bart7", "Bart8", "Bart9", "Bart10",
"Lisa", "Marge", "Homer", "Bart", "Bart1", "Bart2", "Bart3",
"Bart11", "Bart12"}
"Bart"
Returns: "Bart13"


Solution



import java.util.*;
public class UserName{

public String newMember(String[] existingNames, String newName){
String regex = "^"+newName+"[0-9]*$";
List<String> abc =new ArrayList<String>();
List<Integer> xyz =new ArrayList<Integer>();
for (String a: existingNames){
if (a.matches(regex)) {
abc.add(a);
xyz.add(new Integer(a.replace(newName,"0")));
}
}
if (abc.size()==0 || !abc.contains(newName)){
return newName;
}
//Collections.sort(abc);
Collections.sort(xyz);
for (int i=0;i<xyz.size();i++){
if (xyz.get(i)!=i){
return newName+(i==0?"":i);
}
}
return newName+(xyz.size());
}

public static void main(String[] args){
UserName un = new UserName();
System.out.println(un.newMember(new String[]{"MasterOfDisaster", "DingBat", "Orpheus", "WolfMan", "MrKnowItAll"},"TygerTyger"));
System.out.println(un.newMember(new String[]{"MasterOfDisaster", "TygerTyger1", "DingBat", "Orpheus",
"TygerTyger", "WolfMan", "MrKnowItAll"},"TygerTyger"));
System.out.println(un.newMember(new String[]{"TygerTyger2000", "TygerTyger1", "MasterDisaster", "DingBat", "Orpheus", "WolfMan", "MrKnowItAll"},"TygerTyger"));
System.out.println(un.newMember(new String[]{"grokster2", "BrownEyedBoy", "Yoop", "BlueEyedGirl",
"grokster", "Elemental", "NightShade", "Grokster1"},"grokster"));
System.out.println(un.newMember(new String[]{"Bart4", "Bart5", "Bart6", "Bart7", "Bart8", "Bart9", "Bart10",
"Lisa", "Marge", "Homer", "Bart", "Bart1", "Bart2", "Bart3",
"Bart11", "Bart12"},"Bart"));
}
}

TopCoder: MatchMaking

URL

http://www.topcoder.com/stat?c=problem_statement&pm=2911&rd=5849

Problem Statement

You are developing the matchmaking component of an online dating site. Prospective members must fill out a questionnaire consisting of binary questions such as Do you prefer to vacation (a) in the mountains or (b) at the seaside? and Would you rather travel (a) by plane or (b) by train?

You are to match up men with women by maximizing the number of answers each couple has in common. A man and a woman have an answer in common whenever they give the same answer to the same question. Conflicts can easily arise due to numerical ties, but you will be able to resolve all such conflicts using the following procedure. Note that there will be equal numbers of men and women, with names being unique in each sex.

Take the woman whose name comes earliest in lexicographic order, and consider the men with whom she has the greatest number of answers in common. Among these men, pick the one whose name comes earliest in lexicographic order. You have found the woman's best match. Remove this couple from the dating pool, and repeat the matching procedure until there are no more singles left.

You are given a String[], namesWomen, containing the names of single women, and another String[], answersWomen, containing their answers. The kth element of answersWomen lists the answers of the woman whose name is the kth element of namesWomen. If there are n questions in the questionnaire, then every element of answersWomen consists of n characters, each of which is either 'a' or 'b'. The answers are always given in the fixed questionnaire order. You are similarly given the String[]s namesMen and answersMen for the single men. Lastly, you are given a String, queryWoman, containing the name of a woman. Return the name of the man to whom she is matched after you have formed all couples according to the above rules.

Definition

Class:MatchMaking
Method:makeMatch
Parameters:String[], String[], String[], String[], String
Returns:String
Method signature:String makeMatch(String[] namesWomen, String[] answersWomen, String[] namesMen, String[] answersMen, String queryWoman)
(be sure your method is public)

Notes

-Lexicographic order is like dictionary order, with the difference that case matters. All uppercase letters take precedence over all lowercase letters. Thus, "boolean" comes before "boot"; "boo" comes before "boolean"; "Boot" comes before "boo"; "Zoo" comes before "boo".

Constraints

-namesWomen contains between 1 and 50 elements, inclusive
-if namesWomen consists of n elements, then answersWomen, namesMen, and answersMen consist of n elements each
-each element of namesWomen and each element of namesMen is between 1 and 50 characters long, inclusive
-the only characters that may appear in namesMen and namesWomen are 'a' to 'z' and 'A' to 'Z'
-no two elements of namesWomen are alike
-no two elements of namesMen are alike
-the first element of answersWomen is between 1 and 50 characters long, inclusive
-if the first element of answersWomen consists of m characters, then each element of answersWomen and of answersMen is m characters long
-the only characters that may appear in answersWomen and answersMen are 'a' and 'b'
-queryWoman is one of the Strings in namesWomen

Examples

0)
{"Constance", "Bertha", "Alice"}
{"aaba", "baab", "aaaa"}
{"Chip", "Biff", "Abe"}
{"bbaa", "baaa", "aaab"}
"Bertha"
Returns: "Biff"
Alice has two answers in common with Chip and three answers in common with both Abe and Biff; Abe gets lexicographic preference. Bertha also has two answers in common with Chip and three answers in common with both Abe and Biff. Since Abe has already been matched to Alice, Bertha lands Biff.
1)
{"Constance", "Bertha", "Alice"}
{"aaba", "baab", "aaaa"}
{"Chip", "Biff", "Abe"}
{"bbaa", "baaa", "aaab"}
"Constance"
Returns: "Chip"
We are dealing with the same names and answers as before. Constance is the last to go. Although she has two answers in common with Abe and Biff, they are both taken. She ends up with Chip, with whom she has only one answer in common.
2)
{"Constance", "Alice", "Bertha", "Delilah", "Emily"}
{"baabaa", "ababab", "aaabbb", "bababa", "baabba"}
{"Ed", "Duff", "Chip", "Abe", "Biff"}
{"aabaab", "babbab", "bbbaaa", "abbbba", "abaaba"}
"Constance"
Returns: "Duff"

3)
{"Constance", "Alice", "Bertha", "Delilah", "Emily"}
{"baabaa", "ababab", "aaabbb", "bababa", "baabba"}
{"Ed", "Duff", "Chip", "Abe", "Biff"}
{"aabaab", "babbab", "bbbaaa", "abbbba", "abaaba"}
"Delilah"
Returns: "Chip"

4)
{"Constance", "Alice", "Bertha", "Delilah", "Emily"}
{"baabaa", "ababab", "aaabbb", "bababa", "baabba"}
{"Ed", "Duff", "Chip", "Abe", "Biff"}
{"aabaab", "babbab", "bbbaaa", "abbbba", "abaaba"}
"Emily"
Returns: "Ed"

5)
{"anne", "Zoe"}
{"a", "a"}
{"bob", "chuck"}
{"a", "a"}
"Zoe"
Returns: "bob"

6)
{"F", "M", "S", "h", "q", "g", "r", "N", "U", "x", "H", "P",
"o", "E", "R", "z", "L", "m", "e", "u", "K", "A", "w", "Q",
"O", "v", "j", "a", "t", "p", "C", "G", "k", "c", "V", "B",
"D", "s", "n", "i", "f", "T", "I", "l", "d", "J", "y", "b"}
{"abaabbbb", "bbaabbbb", "aaabaaab", "aabbaaaa", "baabbaab",
"aaababba", "bbabbbbb", "bbbabbba", "aaabbbba", "aabbbaaa",
"abbabaaa", "babbabbb", "aaaaabba", "aaaabbaa", "abbbabaa",
"babababa", "abbaaaaa", "bbababba", "baaaaaba", "baaaaabb",
"bbbbabba", "ababbaaa", "abbbabab", "baabbbaa", "bbbaabbb",
"aababbab", "ababbabb", "abbaabba", "baabbabb", "aaabaaab",
"aabbbaba", "aabaaabb", "abababba", "aabbaaaa", "aabbabaa",
"bababaaa", "aabaaaab", "bbbbaabb", "baaababb", "abaabbab",
"aabbbaaa", "baabbaba", "bbabbbaa", "aabbbbaa", "abbbaaab",
"abababbb", "ababaaba", "bababaaa"}
{"f", "C", "v", "g", "Q", "z", "n", "c", "B", "o", "M", "F",
"u", "x", "I", "T", "K", "L", "E", "U", "w", "A", "d", "t",
"e", "R", "D", "s", "p", "q", "m", "r", "H", "j", "J", "V",
"l", "a", "k", "h", "G", "y", "i", "P", "O", "N", "b", "S"}
{"bbbaabab", "bbabaabb", "ababbbbb", "bbbababb", "baababaa",
"bbaaabab", "abbabbaa", "bbbabbbb", "aabbabab", "abbababa",
"aababbbb", "bababaab", "aaababbb", "baabbaba", "abaaaaab",
"bbaababa", "babaabab", "abbabbba", "ababbbab", "baabbbab",
"babbaaab", "abbbbaba", "bbabbbba", "baaabaab", "ababbabb",
"abbbaabb", "bbbbaabb", "bbbaaabb", "baabbaba", "bbabaaab",
"aabbbaab", "abbbbabb", "bbaaaaba", "bbbababa", "abbaabba",
"bababbbb", "aabaaabb", "babbabab", "baaaabaa", "ababbaba",
"aaabaabb", "bbaaabaa", "baaaaabb", "bbaabaab", "bbababab",
"aabaaaab", "aaaaabab", "aabbaaba"}
"U"
Returns: "x"

7)
{"q", "M", "w", "y", "p", "N", "s", "r", "a", "H", "o", "n",
"F", "m", "l", "b", "D", "j", "C", "u", "f", "I", "g", "L",
"i", "x", "A", "G", "O", "k", "h", "d", "c", "E", "B", "v",
"J", "z", "K", "e", "t"}
{"aabbaaabb", "baabababb", "bbaababba", "bbbaaaaaa", "abaaaabaa",
"bababbbab", "abbaabbaa", "aabababbb", "bababaaaa", "abbababaa",
"aabbbbbba", "bbabbabab", "babaabbba", "babbabbbb", "baaabbbbb",
"baaabaaaa", "aaabbaaab", "abbaabbbb", "abbabbbab", "bbaaaabba",
"babbaaabb", "aabbabbab", "baaababba", "ababaabab", "bbbaabbab",
"aaaabbabb", "babaaaaaa", "abbbbaaab", "aabaaabba", "bbbaaaaba",
"bbbbbbaab", "aabbaaabb", "aabaabbab", "aababaaba", "bbabbbbab",
"abbabaaab", "babaaabbb", "bababbaaa", "aabbaabaa", "baaabbabb",
"bbbbbbbbb"}
{"m", "k", "n", "q", "L", "E", "M", "l", "w", "x", "g", "e",
"i", "z", "F", "r", "a", "h", "f", "D", "J", "K", "j", "v",
"A", "t", "N", "y", "s", "c", "o", "p", "d", "b", "B", "G",
"O", "I", "u", "C", "H"}
{"bbaaabbba", "bbaaaaaab", "abaaababb", "baaaabbbb", "abbbababa",
"baaaaaaaa", "aabbbbbab", "aaaaabbba", "baabababb", "babaaabab",
"baaababaa", "bbbbaabba", "bbaabbabb", "bbaaababb", "abbabbaba",
"aababaaab", "abbbbbbaa", "aabbaabaa", "bbbaabbba", "abbabbaba",
"aaabbbaaa", "bbaabaaaa", "aabababbb", "abbbbabab", "baaabbbba",
"bababbbba", "aababbaab", "bbaabbaab", "bbbaaabbb", "babbbbabb",
"ababababb", "babaaabab", "bbaaaaaba", "aaaaabaaa", "abbaaabbb",
"bbbbababb", "baabababb", "bbaabaaaa", "aaababbbb", "abbbbbbba",
"bbaabbaaa"}
"o"
Returns: "C"



My Solution:



import java.util.*;
public class MatchMaking{

public class Person implements Comparable {
public String name;
public String answer;

public Person(String name, String answer){
this.name=name;
this.answer=answer;
}

public int compareTo(Object p){
return this.name.compareTo(((Person)p).name);
}

public String toString(){
return name+"="+answer;
}

};

public String makeMatch(String[] namesWomen, String[] answersWomen, String[] namesMen, String[] answersMen, String queryWoman){
List<Person> man = new ArrayList<Person>();
List<Person> woman = new ArrayList<Person>();
for (int i=0;i<namesWomen.length;i++){
man.add(new Person(namesMen[i],answersMen[i]));
woman.add(new Person(namesWomen[i],answersWomen[i]));
}
Collections.sort(man);
Collections.sort(woman);
//System.out.println(man);
//System.out.println(woman);
while (woman.size()!=0){
Person w = woman.get(0);
Person m = man.get(0);
int match =0;
for (int i=0;i<man.size();i++){
Person p = man.get(i);
int mix = matchAnswer(w.answer,p.answer);
if (match<mix) {
match=mix;
m=p;
}
}
if (w.name.equals(queryWoman)){
return m.name;
} else {
man.remove(m);
woman.remove(w);
}
}
return null;
}

public int matchAnswer(String a, String b){
int count=0;
for (int i=0;i<a.length();i++){
if (a.charAt(i)==b.charAt(i)) count++;
}
return count;
}

public static void main(String[] args){
MatchMaking mm = new MatchMaking();
System.out.println(
mm.makeMatch(new String[] {"Constance", "Bertha", "Alice"},
new String[] {"aaba", "baab", "aaaa"},
new String[] {"Chip", "Biff", "Abe"},
new String[] {"bbaa", "baaa", "aaab"},
"Bertha")
);

System.out.println(
mm.makeMatch(new String[] {"Constance", "Bertha", "Alice"},
new String[] {"aaba", "baab", "aaaa"},
new String[] {"Chip", "Biff", "Abe"},
new String[] {"bbaa", "baaa", "aaab"},
"Constance")
);

System.out.println(
mm.makeMatch(new String[] {"Constance", "Alice", "Bertha", "Delilah", "Emily"},
new String[] {"baabaa", "ababab", "aaabbb", "bababa", "baabba"},
new String[] {"Ed", "Duff", "Chip", "Abe", "Biff"},
new String[] {"aabaab", "babbab", "bbbaaa", "abbbba", "abaaba"},
"Constance")
);

System.out.println(
mm.makeMatch(new String[] {"Constance", "Alice", "Bertha", "Delilah", "Emily"},
new String[] {"baabaa", "ababab", "aaabbb", "bababa", "baabba"},
new String[] {"Ed", "Duff", "Chip", "Abe", "Biff"},
new String[] {"aabaab", "babbab", "bbbaaa", "abbbba", "abaaba"},
"Delilah")
);

System.out.println(
mm.makeMatch(new String[] {"Constance", "Alice", "Bertha", "Delilah", "Emily"},
new String[] {"baabaa", "ababab", "aaabbb", "bababa", "baabba"},
new String[] {"Ed", "Duff", "Chip", "Abe", "Biff"},
new String[] {"aabaab", "babbab", "bbbaaa", "abbbba", "abaaba"},
"Emily")
);

System.out.println(
mm.makeMatch(new String[] {"anne", "Zoe"},
new String[] {"a", "a"},
new String[] {"bob", "chuck"},
new String[] {"a", "a"},
"Zoe")
);

System.out.println(
mm.makeMatch(new String[] {"F", "M", "S", "h", "q", "g", "r", "N", "U", "x", "H", "P",
"o", "E", "R", "z", "L", "m", "e", "u", "K", "A", "w", "Q",
"O", "v", "j", "a", "t", "p", "C", "G", "k", "c", "V", "B",
"D", "s", "n", "i", "f", "T", "I", "l", "d", "J", "y", "b"},
new String[] {"abaabbbb", "bbaabbbb", "aaabaaab", "aabbaaaa", "baabbaab",
"aaababba", "bbabbbbb", "bbbabbba", "aaabbbba", "aabbbaaa",
"abbabaaa", "babbabbb", "aaaaabba", "aaaabbaa", "abbbabaa",
"babababa", "abbaaaaa", "bbababba", "baaaaaba", "baaaaabb",
"bbbbabba", "ababbaaa", "abbbabab", "baabbbaa", "bbbaabbb",
"aababbab", "ababbabb", "abbaabba", "baabbabb", "aaabaaab",
"aabbbaba", "aabaaabb", "abababba", "aabbaaaa", "aabbabaa",
"bababaaa", "aabaaaab", "bbbbaabb", "baaababb", "abaabbab",
"aabbbaaa", "baabbaba", "bbabbbaa", "aabbbbaa", "abbbaaab",
"abababbb", "ababaaba", "bababaaa"},
new String[] {"f", "C", "v", "g", "Q", "z", "n", "c", "B", "o", "M", "F",
"u", "x", "I", "T", "K", "L", "E", "U", "w", "A", "d", "t",
"e", "R", "D", "s", "p", "q", "m", "r", "H", "j", "J", "V",
"l", "a", "k", "h", "G", "y", "i", "P", "O", "N", "b", "S"},
new String[] {"bbbaabab", "bbabaabb", "ababbbbb", "bbbababb", "baababaa",
"bbaaabab", "abbabbaa", "bbbabbbb", "aabbabab", "abbababa",
"aababbbb", "bababaab", "aaababbb", "baabbaba", "abaaaaab",
"bbaababa", "babaabab", "abbabbba", "ababbbab", "baabbbab",
"babbaaab", "abbbbaba", "bbabbbba", "baaabaab", "ababbabb",
"abbbaabb", "bbbbaabb", "bbbaaabb", "baabbaba", "bbabaaab",
"aabbbaab", "abbbbabb", "bbaaaaba", "bbbababa", "abbaabba",
"bababbbb", "aabaaabb", "babbabab", "baaaabaa", "ababbaba",
"aaabaabb", "bbaaabaa", "baaaaabb", "bbaabaab", "bbababab",
"aabaaaab", "aaaaabab", "aabbaaba"},
"U")
);

System.out.println(
mm.makeMatch(new String[] {"q", "M", "w", "y", "p", "N", "s", "r", "a", "H", "o", "n",
"F", "m", "l", "b", "D", "j", "C", "u", "f", "I", "g", "L",
"i", "x", "A", "G", "O", "k", "h", "d", "c", "E", "B", "v",
"J", "z", "K", "e", "t"},
new String[] {"aabbaaabb", "baabababb", "bbaababba", "bbbaaaaaa", "abaaaabaa",
"bababbbab", "abbaabbaa", "aabababbb", "bababaaaa", "abbababaa",
"aabbbbbba", "bbabbabab", "babaabbba", "babbabbbb", "baaabbbbb",
"baaabaaaa", "aaabbaaab", "abbaabbbb", "abbabbbab", "bbaaaabba",
"babbaaabb", "aabbabbab", "baaababba", "ababaabab", "bbbaabbab",
"aaaabbabb", "babaaaaaa", "abbbbaaab", "aabaaabba", "bbbaaaaba",
"bbbbbbaab", "aabbaaabb", "aabaabbab", "aababaaba", "bbabbbbab",
"abbabaaab", "babaaabbb", "bababbaaa", "aabbaabaa", "baaabbabb",
"bbbbbbbbb"},
new String[] {"m", "k", "n", "q", "L", "E", "M", "l", "w", "x", "g", "e",
"i", "z", "F", "r", "a", "h", "f", "D", "J", "K", "j", "v",
"A", "t", "N", "y", "s", "c", "o", "p", "d", "b", "B", "G",
"O", "I", "u", "C", "H"},
new String[] {"bbaaabbba", "bbaaaaaab", "abaaababb", "baaaabbbb", "abbbababa",
"baaaaaaaa", "aabbbbbab", "aaaaabbba", "baabababb", "babaaabab",
"baaababaa", "bbbbaabba", "bbaabbabb", "bbaaababb", "abbabbaba",
"aababaaab", "abbbbbbaa", "aabbaabaa", "bbbaabbba", "abbabbaba",
"aaabbbaaa", "bbaabaaaa", "aabababbb", "abbbbabab", "baaabbbba",
"bababbbba", "aababbaab", "bbaabbaab", "bbbaaabbb", "babbbbabb",
"ababababb", "babaaabab", "bbaaaaaba", "aaaaabaaa", "abbaaabbb",
"bbbbababb", "baabababb", "bbaabaaaa", "aaababbbb", "abbbbbbba",
"bbaabbaaa"},
"o")
);
}
}

Monday, August 4, 2008

TopCoder: ContiguousCacheEasy Problem

Problem Statement


In order to make their newest microcontroller as cheap as possible, the ACME Widget Company designed it with a very simple cache. The processor is connected to a slow memory system that contains n bytes, numbered 0 to n - 1. The cache holds a copy of k of these bytes at a time, for fast access. It has a base address (referred to as base below), and it holds a copy of the bytes numbered base, base+1, ..., base+k-1. When a program reads a byte, the cache controller executes the following algorithm:

  1. Find a new range of k bytes which contains the requested byte, such that the difference between the old and new base addresses is minimized. Note that if the requested byte was already in the cache, then the base address will not change.
  2. Update the cache to the new range by reading from the memory system any bytes that are in the new range but not the old range, and discarding any bytes that were in the old range but not the new range.
  3. Return the requested byte to the program.

To analyze the performance of a program, you wish to know how many bytes are read from the memory system. The numbers of the bytes that the program reads are given in addresses, in the order that they are read. When the program starts, the base address is 0.


Definition


Class:ContiguousCacheEasy
Method:bytesRead
Parameters:int, int, int[]
Returns:int
Method signature:int bytesRead(int n, int k, int[] addresses)
(be sure your method is public)



Constraints

-n will be between 1 and 1,000,000, inclusive.
-k will be between 1 and n, inclusive.
-addresses will contain between 1 and 50 elements, inclusive.
-Each element of addresses will be between 0 and n-1, inclusive.

Examples

0)

100
5
{6, 0, 3, 20, 22, 16}
Returns: 13
When the program starts, the cache holds 0-4 (all ranges are inclusive). Accessing 6 updates the range to hold 2-6, reading two bytes. Accessing 0 resets the range to 0-4, reading another two bytes. Accessing 3 has no effect, since it is already cached. Accessing 20 and then 22 causes another seven bytes to be read, and the cache to hold 18-22. Finally, accessing 16 updates the cache to hold 16-20 (the closest range to 18-22 containing 16), for another two bytes.
1)

100
1
{0, 4, 6, 6, 4, 10}
Returns: 4
When the cache only holds one byte, every access causes a read, except where the cache already held the correct byte.
2)

1000
999
{0, 4, 123, 987, 999, 500, 0}
Returns: 2
In this case, all but one byte is cached.



Solution:




public class ContiguousCacheEasy{
public int bytesRead(int n, int k, int[] addresses){
int reads=0;
int base=0;
for (int i=0;i<addresses.length;i++){
System.out.println("base="+base+",reads="+reads);
if (base<=addresses[i] && addresses[i]<base+k){
continue;
}
if (base+k<=addresses[i]){
int newbase=addresses[i]-k+1;
reads+=(newbase-base>k?k:newbase-base);
base=newbase;
} else {
int newbase=addresses[i];
reads+=(base-newbase>k?k:base-newbase);
base=newbase;
}
}
return reads;
}
public static void main(String[] args){
ContiguousCacheEasy cc = new ContiguousCacheEasy();
System.out.println(cc.bytesRead(100,5,new int[]{6, 0, 3, 20, 22, 16}));
System.out.println(cc.bytesRead(100,1,new int[]{0, 4, 6, 6, 4, 10}));
System.out.println(cc.bytesRead(1000,999,new int[]{0, 4, 123, 987, 999, 500, 0}));
}
}

TopCoder Problem: ZigZag

URL
http://www.topcoder.com/stat?c=problem_statement&pm=1259&rd=4493

Problem Statement

A sequence of numbers is called a zig-zag sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a zig-zag sequence.

For example, 1,7,4,9,2,5 is a zig-zag sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, 1,4,7,2,5 and 1,7,4,5,5 are not zig-zag sequences, the first because its first two differences are positive and the second because its last difference is zero.

Given a sequence of integers, sequence, return the length of the longest subsequence of sequence that is a zig-zag sequence. A subsequence is obtained by deleting some number of elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.

Definition

Class:ZigZag
Method:longestZigZag
Parameters:int[]
Returns:int
Method signature:int longestZigZag(int[] sequence)
(be sure your method is public)

Constraints

-sequence contains between 1 and 50 elements, inclusive.
-Each element of sequence is between 1 and 1000, inclusive.

Examples

0)
{ 1, 7, 4, 9, 2, 5 }
Returns: 6
The entire sequence is a zig-zag sequence.
1)
{ 1, 17, 5, 10, 13, 15, 10, 5, 16, 8 }
Returns: 7
There are several subsequences that achieve this length. One is 1,17,10,13,10,16,8.
2)
{ 44 }
Returns: 1

3)
{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }
Returns: 2

4)
{ 70, 55, 13, 2, 99, 2, 80, 80, 80, 80, 100, 19, 7, 5, 5, 5, 1000, 32, 32 }
Returns: 8

5)
{ 374, 40, 854, 203, 203, 156, 362, 279, 812, 955,
600, 947, 978, 46, 100, 953, 670, 862, 568, 188,
67, 669, 810, 704, 52, 861, 49, 640, 370, 908,
477, 245, 413, 109, 659, 401, 483, 308, 609, 120,
249, 22, 176, 279, 23, 22, 617, 462, 459, 244 }
Returns: 36


My Solution

public class ZigZag{
public int longestZigZag(int[] sequence) {
if (sequence.length==1) return 1;
if (sequence.length==2) return 2;
int[] diff = new int[sequence.length-1];

for (int i=1;i<sequence.length;i++){
diff[i-1]=sequence[i]-sequence[i-1];
}
int sign=sign(diff[0]);
int count=0;
if (sign!=0)
count=1;
for (int i=1;i<diff.length;i++){
int nextsign=sign(diff[i]);
if (sign*nextsign==-1){
sign=nextsign;
count++;
}
}
return count+1;
}

public int sign(int a){
if (a==0) return 0;
return a/Math.abs(a);
}
public static void main(String[] args){
ZigZag z = new ZigZag();
System.out.println(z.longestZigZag(new int[] { 1, 7, 4, 9, 2, 5 }));
System.out.println(z.longestZigZag(new int[] { 1, 17, 5, 10, 13, 15, 10, 5, 16, 8 }));
System.out.println(z.longestZigZag(new int[] { 44 }));
System.out.println(z.longestZigZag(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9 }));
System.out.println(z.longestZigZag(new int[] {70, 55, 13, 2, 99, 2, 80, 80, 80,
80, 100, 19, 7, 5, 5, 5, 1000, 32, 32 }));
System.out.println(z.longestZigZag(new int[] {374, 40, 854, 203, 203, 156, 362, 279, 812, 955,
600, 947, 978, 46, 100, 953, 670, 862, 568, 188,
67, 669, 810, 704, 52, 861, 49, 640, 370, 908,
477, 245, 413, 109, 659, 401, 483, 308, 609, 120,
249, 22, 176, 279, 23, 22, 617, 462, 459, 244}));
System.out.println(z.longestZigZag(new int[] {3, 3, 3, 3, 3}));
System.out.println(z.longestZigZag(new int[] {396, 549, 22, 819, 611, 972, 730, 638, 978, 342,
566, 514, 752, 871, 911, 172, 488, 542, 482, 974, 210, 474, 66, 387, 1, 872, 799, 262, 567,
113, 578, 308, 813, 515, 716, 905, 434, 101, 632, 450, 74, 254, 1000, 780, 633, 496, 513,
772, 925, 746}));

}
}

Java Tricks: Converting a number from one base to another

Converting a number int n from base b(<20) to base 10

Integer.parseInt(""+n,b);

Converting a number int n from base 10 to base 2, 8 or 16

Integer.toBinaryString(n);
Integer.toOctalString(n);
Integer.toHexString(n);

Sunday, August 3, 2008

Problem: MatchMaker

Problem Statement

THIS PROBLEM WAS TAKEN FROM THE SEMIFINALS OF THE TOPCODER INVITATIONAL
TOURNAMENT

DEFINITION
Class Name: MatchMaker
Method Name: getBestMatches
Paramaters: String[], String, int
Returns: String[]
Method signature (be sure your method is public): String[]
getBestMatches(String[] members, String currentUser, int sf);

PROBLEM STATEMENT
A new online match making company needs some software to help find the "perfect couples". People who sign up answer a series of multiple-choice questions. Then, when a member makes a "Get Best Mates" request, the software returns a list of users whose gender matches the requested gender and whose answers to the questions were equal to or greater than a similarity factor when compared to the user's answers.

Implement a class MatchMaker, which contains a method getBestMatches. The method takes as parameters a String[] members, String currentUser, and an int sf:
- members contains information about all the members. Elements of members are
of the form "NAME G D X X X X X X X X X X"
* NAME represents the member's name
* G represents the gender of the current user.
* D represents the requested gender of the potential mate.
* Each X indicates the member's answer to one of the multiple-choice
questions. The first X is the answer to the first question, the second is the
answer to the second question, et cetera.
- currentUser is the name of the user who made the "Get Best Mates" request.
- sf is an integer representing the similarity factor.

The method returns a String[] consisting of members' names who have at least sf identical answers to currentUser and are of the requested gender. The names should be returned in order from most identical answers to least. If two members have the same number of identical answers as the currentUser, the names should be returned in the same relative order they were inputted.

TopCoder will ensure the validity of the inputs. Inputs are valid if all of the following criteria are met:
- members will have between 1 and 50 elements, inclusive.
- Each element of members will have a length between 7 and 44, inclusive.
- NAME will have a length between 1 and 20, inclusive, and only contain uppercase letters A-Z.
- G can be either an uppercase M or an uppercase F.
- D can be either an uppercase M or an uppercase F.
- Each X is a capital letter (A-D).
- The number of Xs in each element of the members is equal. The number of Xs will be between 1 and 10, inclusive.
- No two elements will have the same NAME.
- Names are case sensitive.
- currentUser consists of between 1 and 20, inclusive, uppercase letters, A-Z, and must be a member.
- sf is an int between 1 and 10, inclusive.
- sf must be less than or equal to the number of answers (Xs) of the members.

NOTES
The currentUser should not be included in the returned list of potential mates.


EXAMPLES

For the following examples, assume members =
{"BETTY F M A A C C",
"TOM M F A D C A",
"SUE F M D D D D",
"ELLEN F M A A C A",
"JOE M F A A C A",
"ED M F A D D A",
"SALLY F M C D A B",
"MARGE F M A A C C"}

If currentUser="BETTY" and sf=2, BETTY and TOM have two identical answers and BETTY and JOE have three identical answers, so the method should return {"JOE","TOM"}.

If currentUser="JOE" and sf=1, the method should return {"ELLEN","BETTY","MARGE"}.

If currentUser="MARGE" and sf=4, the method should return [].



import java.util.*;

public class MatchMaker {

public String[] getBestMatches(String[] members, String currentUser, int sf){
String[] names = new String[members.length];
String[] gen = new String[members.length];
String[] pre = new String[members.length];
String[][] ans= new String[members.length][];
int index=-1;
for (int i=0;i<members.length;i++){
String[] spls = members[i].split(" ");
names[i]=spls[0];
gen[i]=spls[1];
pre[i]=spls[2];
ans[i]= new String[spls.length-3];
for (int j=3;j<spls.length;j++){
ans[i][j-3]=spls[j];
}
if (spls[0].equals(currentUser)){
index=i;
}
}
List<String> l = new ArrayList<String>();
for (int i=0;i<members.length;i++){
if (!(names[i].equals(currentUser)) && gen[i].equals(pre[index]) && pre[i].equals(gen[index])){
int count=0;
for (int j=0;j<ans[i].length;j++){
if (ans[i][j].equals(ans[index][j])){
count++;
}
}
if (count>=sf) {
l.add(names[i]);
}
}
}
return l.toArray(new String[0]);
}

public static void main(String[] args){
MatchMaker mm = new MatchMaker();
String[] l = new String[] {
"BETTY F M A A C C",
"TOM M F A D C A",
"SUE F M D D D D",
"ELLEN F M A A C A",
"JOE M F A A C A",
"ED M F A D D A",
"SALLY F M C D A B",
"MARGE F M A A C C"};
System.out.println(Arrays.asList(mm.getBestMatches(l,"BETTY",2)));
System.out.println(Arrays.asList(mm.getBestMatches(l,"JOE",1)));
System.out.println(Arrays.asList(mm.getBestMatches(l,"MARGE",4)));

}
}


Problem: BitFlipper

URL:

http://www.topcoder.com/tc?module=Static&d1=help&d2=sampleProblems

Problem Statement:

Binary strings, as most of us know, are composed solely of 0's and 1's. Sometimes it is necessary to turn all the bits either on (1) or off (0). However, sometimes it is not possible to just pick and flip individual bits. In this hypothetical scenario, it is only possible to flip bits in a contiguous segment which is a subset of the contiguous segment which was flipped immediately prior to it. For example, if bits 2-4 are flipped, it is not legal to flip bits 3-5 next, or bits 1-3. However, bits 3-4 or bits 2-3 would be legal. The first segment to be flipped can be located anywhere in the sequence.

Create a class BitFlipper which contains a method minFlip which determines the minimum number of bits that must be flipped under the above restriction in order to get all the bits set to 0. For purposes of this problem, to flip a bit means to change it from 0 to 1 or from 1 to 0.

DEFINITION

Class: BitFlipper
Method: minFlip
Parameters: String
Returns: int

Method signature (be sure it is declared public): int minFlip (String bits);

TopCoder will ensure the validity of the inputs. Inputs are valid if all of the following criteria are met:
* bits will be between 0 and 50 characters in length, inclusive
* bits will contain only 1's and 0's.

EXAMPLES

Example 1:
bits = "00110".
By flipping bits 3-4, we get "00000". Method returns 2.

Example 2:
bits = "10110"
If we flip bits 1-4, we get "01000". Now we flip bit 2 and get "00000".
Method returns 4 + 1 = 5.

Example 3:
bits = "1001110001"
Flipping bits 1-10 yields "0110001110"
Now, flipping bits 2-9 yields "0001110000"
Again, flipping bits 4-6 yields "0000000000"
Method returns 10 + 8 + 3 = 21.

Example 4:
bits = "10001"
Method returns 8.

Example 5:
bits = "101010101"
Method returns 25.

Example 6:
bits = ""
Method returns 0.


Solution:

public class BitFlipper{

public int minFlip (String bits){
int flip=0;
while (!"".equals(bits))
{
bits=bits.replaceAll("^[0]*","");
bits=bits.replaceAll("[0]*$","");
flip+=bits.length();
StringBuffer sb = new StringBuffer();
for (int i=0;i<bits.length();i++){
String cur = bits.substring(i,i+1);
if ("0".equals(cur)) {
sb.append("1");
} else {
sb.append("0");
}
}
bits=sb.toString();
}
return flip;
}

public static void main(String[] args){
BitFlipper bf = new BitFlipper();
System.out.println(bf.minFlip("00110"));
System.out.println(bf.minFlip("10110"));
System.out.println(bf.minFlip("1001110001"));
System.out.println(bf.minFlip("10001"));
System.out.println(bf.minFlip("101010101"));
System.out.println(bf.minFlip(""));
}
}

TopCoder problem: Palindrome

URL: http://www.topcoder.com/tc?module=Static&d1=help&d2=sampleProblems

Problem Statement
A palindrome is a number that is the same whether it is read from left-to-right or right-to-left. For example, 121 and 34543 are both palindromes. It turns out that nearly every integer can be transformed into a palindrome by reversing its digits and adding it to the original number. If that does not create a palindrome, add the reverse of the new number to itself. A palindrome is created by repeating the process of reversing the number and adding it to itself until the number is a palindrome.

Create a class Transform that contains the method palindrome, which takes a number N that is to be transformed and returns a number that is the resultant palindrome from this process. Of course if N is already a palindrome, return it without changing it. Though it is theorized that all numbers can be transformed to palindromes in this way, some numbers do not converge in a reasonable amount of time. For instance, 196 has been carried out to 26,000 digits without finding a palindrome. So if the method finds that the resultant palindrome must be greater than 1,000,000,000, return the special value -1 instead.

DEFINITION
Class: Transform
Method: palindrome
Parameters: int
Returns: int
Method signature (be sure your method is public): int palindrome(int N);

NOTES
- Leading zeroes are never considered part of a number when it is reversed. For instance, 12's reverse will always be 21 regardless of whether it is represented as 12, 012, or 0012. Examples with leading zeroes use the leading zeroes for clarity only.

TopCoder will ensure the validity of the inputs. Inputs are valid if all of the following criteria are met:
- N will be between 1 and 10000 inclusive.

EXAMPLES
Worked examples:
Example 1: N = 28
28 + 82 = 110
110 + 011 = 121, a palindrome. Return 121

Example 2: N = 51
51 + 15 = 66, a palindrome. Return 66

Further examples:
Example 3: N = 11, return 11
Example 4: N = 607, return 4444
Example 5: N = 196, return -1

Solution:




public class Transform{

public int palindrome(int input){
int max= 1000000000;
if (isP(input)){
return input;
}
while (input<max){
input=input+new Integer(new StringBuffer(""+input).reverse().toString());
if (isP(input)){
return input;
}
}
return -1;
}

public boolean isP(int in){
StringBuffer inp = new StringBuffer(""+in);
return inp.reverse().toString().equals(""+in);
}

public static void main(String[] args){
Transform t = new Transform();
System.out.println(t.palindrome(28));
System.out.println(t.palindrome(51));
System.out.println(t.palindrome(11));
System.out.println(t.palindrome(607));
System.out.println(t.palindrome(196));
}
}

Thursday, July 17, 2008

Google Code Jam : Qualification Round : Problem # 2

URL:
http://code.google.com/codejam/contest/dashboard?c=agdjb2RlamFtcg8LEghjb250ZXN0cxjqOQw&selected_problem=2&csrfmiddlewaretoken=

Problem Name: Train Timetable
Problem

A train line has two stations on it, A and B. Trains can take trips from A to B or from B to A multiple times during a day. When a train arrives at B from A (or arrives at A from B), it needs a certain amount of time before it is ready to take the return journey - this is the turnaround time. For example, if a train arrives at 12:00 and the turnaround time is 0 minutes, it can leave immediately, at 12:00.

A train timetable specifies departure and arrival time of all trips between A and B. The train company needs to know how many trains have to start the day at A and B in order to make the timetable work: whenever a train is supposed to leave A or B, there must actually be one there ready to go. There are passing sections on the track, so trains don't necessarily arrive in the same order that they leave. Trains may not travel on trips that do not appear on the schedule.

Input


The first line of input gives the number of cases, N. N test cases follow.

Each case contains a number of lines. The first line is the turnaround time, T, in minutes. The next line has two numbers on it, NA and NB. NA is the number of trips from A to B, and NB is the number of trips from B to A. Then there are NA lines giving the details of the trips from A to B.


Each line contains two fields, giving the HH:MM departure and arrival time for that trip. The departure time for each trip will be earlier than the arrival time. All arrivals and departures occur on the same day. The trips may appear in any order - they are not necessarily sorted by time. The hour and minute values are both two digits, zero-padded, and are on a 24-hour clock (00:00 through 23:59).

After these NA lines, there are NB lines giving the departure and arrival times for the trips from B to A.


Output

For each test case, output one line containing "Case #x: " followed by the number of trains that must start at A and the number of trains that must start at B.

Limits

1 ≤ N ≤ 100

Small dataset

0 ≤ NA, NB ≤ 20

0 ≤ T ≤ 5

Large dataset

0 ≤ NA, NB ≤ 100

0 ≤ T ≤ 60

Sample

Input
2
5
3 2
09:00 12:00
10:00 13:00
11:00 12:30
12:02 15:00
09:00 10:30
2
2 0
09:00 09:01
12:00 12:02

Output
Case #1: 2 2
Case #2: 2 0


My Solution:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;


public class TrainTime {


public Long[] countTrains(Integer turnAround,String[] aScheds, String[] bScheds){
Station a = new Station();
for (String s: aScheds){
a.times.add(new Time(s));
}
Station b = new Station();
for (String s: bScheds){
b.times.add(new Time(s));
}
Collections.sort(a.times);
Collections.sort(b.times);
//System.out.println(a.times);
//System.out.println(b.times);
while (a.times.size()+b.times.size()!=0){
Station cur;
Station oth;
if (a.times.size()==0){
cur=b;
oth=a;
} else if (b.times.size()==0){
cur=a;
oth=b;
} else {
cur=a.times.get(0).startTime<b.times.get(0).startTime? a: b;
oth=a.times.get(0).startTime<b.times.get(0).startTime? b: a;
}
//System.out.println("cur = "+cur.times+" "+cur.trains+",oth = "+oth.times+" "+oth.trains);
if (cur.trains.size()!=0&&cur.trains.get(0).willRunAt<=cur.times.get(0).startTime){
Train t=cur.trains.get(0);
cur.trains.remove(0);
t.willRunAt=cur.times.get(0).endTime+turnAround;
oth.trains.add(t);
Collections.sort(oth.trains);
cur.times.remove(0);
} else {
Train t = new Train(cur.times.get(0).endTime+turnAround);
cur.count++;
oth.trains.add(t);
Collections.sort(oth.trains);
cur.times.remove(0);
}

}

return new Long[]{a.count,b.count};
}

public class Station {

public List<Time> times = new ArrayList<Time>();

public List<Train> trains = new ArrayList<Train>();

public long count =0;


}

public class Train implements Comparable<Train>{
public Long willRunAt;

public Train(Long willRunAt){
this.willRunAt=willRunAt;
}
public int compareTo(Train o) {
return this.willRunAt.compareTo(o.willRunAt);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return willRunAt.toString();
}


}

public class Time implements Comparable<Time>{

public Long startTime;

public Long endTime;

public Time(String time){
String[] spls= time.split(" ");
this.startTime=getTime(spls[0]);
this.endTime= getTime(spls[1]);
}

private Long getTime(String t){
String[] spls=t.split(":");
return (Long.valueOf(spls[0])*60)+Long.valueOf(spls[1]);
}

public int compareTo(Time o) {
if (this.startTime.compareTo(o.startTime)!=0){
return this.startTime.compareTo(o.startTime);
} else {
return this.endTime.compareTo(o.endTime);
}
}

/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
// TODO Auto-generated method stub
return startTime+" "+endTime;
}



}

public static void main(String[] args) throws FileNotFoundException{
TrainTime tt = new TrainTime();

Scanner scan = new Scanner(new File("Input.txt"));
PrintWriter pw = new PrintWriter("Output.txt");
Integer count =new Integer(scan.nextLine());
for (int i=0;i<count;i++){
Integer turnAround = new Integer(scan.nextLine());
String[] cs=(scan.nextLine()).split(" ");
Integer aCount = new Integer(cs[0]);
Integer bCount = new Integer(cs[1]);
String[] aScheds = new String[aCount];
String[] bScheds = new String[bCount];
for (int j=0;j<aCount;j++){
aScheds[j]= scan.nextLine();
}
for (int j=0;j<bCount;j++){
bScheds[j]= scan.nextLine();
}
Long[] res = tt.countTrains(turnAround, aScheds, bScheds);
pw.write("Case #"+(i+1)+": "+res[0]+" "+res[1]+"\n");
}
pw.close();
scan.close();


}
}

Google Code Jam : Qualification Round : Problem #1

URL


Problem

The urban legend goes that if you go to the Google homepage and search for "Google", the universe will implode. We have a secret to share... It is true! Please don't try it, or tell anyone. All right, maybe not. We are just kidding.

The same is not true for a universe far far away. In that universe, if you search on any search engine for that search engine's name, the universe does implode!

To combat this, people came up with an interesting solution. All queries are pooled together. They are passed to a central system that decides which query goes to which search engine. The central system sends a series of queries to one search engine, and can switch to another at any time. Queries must be processed in the order they're received. The central system must never send a query to a search engine whose name matches the query. In order to reduce costs, the number of switches should be minimized.

Your task is to tell us how many times the central system will have to switch between search engines, assuming that we program it optimally.

Input

The first line of the input file contains the number of cases, N. N test cases follow.

Each case starts with the number S -- the number of search engines. The next S lines each contain the name of a search engine. Each search engine name is no more than one hundred characters long and contains only uppercase letters, lowercase letters, spaces, and numbers. There will not be two search engines with the same name.

The following line contains a number Q -- the number of incoming queries. The next Q lines will each contain a query. Each query will be the name of a search engine in the case.

Output

For each input case, you should output:

Case #X: Y
where X is the number of the test case and Y is the number of search engine switches. Do not count the initial choice of a search engine as a switch.

Limits

0 < N ≤ 20

Small dataset

2 ≤ S ≤ 10

0 ≤ Q ≤ 100

Large dataset

2 ≤ S ≤ 100

0 ≤ Q ≤ 1000

Sample

Input

2
5
Yeehaw
NSM
Dont Ask
B9
Googol
10
Yeehaw
Yeehaw
Googol
B9
Googol
NSM
B9
NSM
Dont Ask
Googol
5
Yeehaw
NSM
Dont Ask
B9
Googol
7
Googol
Dont Ask
NSM
NSM
Yeehaw
Yeehaw
Googol

Output
Case #1: 1
Case #2: 0

In the first case, one possible solution is to start by using Dont Ask, and switch to NSM after query number 8.
For the second case, you can use B9, and not need to make any switches.

My Code:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class SearchUniverse {
public int getMin(String[] engines, String[] queries){

List<String> engs = new ArrayList<String>(Arrays.asList(engines));
int index=0;
int switches=0;

while (index<queries.length){
engs.remove(queries[index]);
if (engs.size()==0){
switches++;
engs= new ArrayList<String>(Arrays.asList(engines));
engs.remove(queries[index]);
}
index++;
}


return switches;
}

public static void main(String[] args) throws FileNotFoundException{
SearchUniverse su = new SearchUniverse();
/*System.out.println(su.getMin(new String[]{"Yeehaw",
"NSM",
"Dont Ask",
"B9",
"Googol"}, new String[]{
"Yeehaw",
"Yeehaw",
"Googol",
"B9",
"Googol",
"NSM",
"B9",
"NSM",
"Dont Ask",
"Googol"}));

System.out.println(su.getMin(new String[]{"Yeehaw",
"NSM",
"Dont Ask",
"B9",
"Googol"}, new String[]{
"Googol",
"Dont Ask",
"NSM",
"NSM",
"Yeehaw",
"Yeehaw",
"Googol"}));*/

Scanner scan = new Scanner(new File("Input.txt"));
PrintWriter pw = new PrintWriter("Output.txt");
Integer count =new Integer(scan.nextLine());
for (int i=0;i<count;i++){
Integer sengs = new Integer(scan.nextLine());
String[] engines = new String[sengs];
for (int j=0;j<sengs;j++){
engines[j]=scan.nextLine();
}
Integer ss = new Integer(scan.nextLine());
String[] queries = new String[ss];
for (int j=0;j<ss;j++){
queries[j]=scan.nextLine();
}
pw.write("Case #"+(i+1)+": "+su.getMin(engines, queries)+"\n");
}
pw.close();
scan.close();


}
}

Tuesday, July 15, 2008

Google Code Jam: Triangle Trilemma

Triangle Trilemma

http://code.google.com/codejam/contest/dashboard?c=agdjb2RlamFtcg4LEghjb250ZXN0cxhRDA

Problem

You're interested in writing a program to classify triangles. Triangles can be classified according to their internal angles. If one of the internal angles is exactly 90 degrees, then that triangle is known as a "right" triangle. If one of the internal angles is greater than 90 degrees, that triangle is known as an "obtuse" triangle. Otherwise, all the internal angles are less than 90 degrees and the triangle is known as an "acute" triangle.

Triangles can also be classified according to the relative lengths of their sides. In a "scalene" triangle, all three sides have different lengths. In an "isosceles" triangle, two of the sides are of equal length. (If all three sides have the same length, the triangle is known as an "equilateral" triangle, but you can ignore this case since there will be no equilateral triangles in the input data.)

Your program must determine, for each set of three points, whether or not those points form a triangle. If the three points are not distinct, or the three points are collinear, then those points do not form a valid triangle. (Another way is to calculate the area of the triangle; valid triangles must have non-zero area.) Otherwise, your program will classify the triangle as one of "acute", "obtuse", or "right", and one of "isosceles" or "scalene".

Input

The first line of input gives the number of cases, N. N test cases follow. Each case is a line formatted as

x1 y1 x2 y2 x3 y3

Output

For each test case, output one line containing "Case #x: " followed by one of these strings:

  • isosceles acute triangle
  • isosceles obtuse triangle
  • isosceles right triangle
  • scalene acute triangle
  • scalene obtuse triangle
  • scalene right triangle
  • not a triangle

Limits

1 ≤ N ≤ 100,
x1, y1, x2, y2, x3, y3 will be integers.

Small dataset

0 ≤ x1, y1, x2, y2, x3, y3 ≤ 9

Large dataset

-1000 ≤ x1, y1, x2, y2, x3, y3 ≤ 1000

Sample


Input





Output
8
0 0 0 4 1 2
1 1 1 4 3 2
2 2 2 4 4 3
3 3 3 4 5 3
4 4 4 5 5 6
5 5 5 6 6 5
6 6 6 7 6 8
7 7 7 7 7 7





Case #1: isosceles obtuse triangle
Case #2: scalene acute triangle
Case #3: isosceles acute triangle
Case #4: scalene right triangle
Case #5: scalene obtuse triangle
Case #6: isosceles right triangle
Case #7: not a triangle
Case #8: not a triangle







My Solution:


import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;


public class Triangle {

public String classify(String input){
String[] spl = input.split(" ");
long x1 = new Integer(spl[0]);
long y1 = new Integer(spl[1]);
long x2 = new Integer(spl[2]);
long y2 = new Integer(spl[3]);
long x3 = new Integer(spl[4]);
long y3 = new Integer(spl[5]);

StringBuffer sb = new StringBuffer();

if ((y2-y1)*(x3-x1)==(y3-y1)*(x2-x1)) return "not a triangle";

long s12= (long)(Math.pow(x2-x1, 2)+Math.pow(y2-y1, 2));

long s23= (long)(Math.pow(x3-x2, 2)+Math.pow(y3-y2, 2));

long s13= (long)(Math.pow(x3-x1, 2)+Math.pow(y3-y1, 2));
if (s12==0||s23==0||s12==0) return "not a triangle";


if (s12==s23||s23==s13||s12==s13)
sb.append("isosceles ");
else
sb.append("scalene ");

long min = Math.min(Math.min(s12, s13),s23);

long max = Math.max(Math.max(s12, s13),s23);

long mid = s12+s23+s13-min-max;

if (min+mid==max) sb.append("right ");

if (min+mid<max) sb.append("obtuse ");

if (min+mid>max) sb.append("acute ");

sb.append("triangle");

return sb.toString();
}

public static void main(String[] args) throws FileNotFoundException {

Triangle an = new Triangle();
System.out.println(an.classify("0 0 0 4 1 2"));
System.out.println(an.classify("1 1 1 4 3 2"));
System.out.println(an.classify("2 2 2 4 4 3"));
System.out.println(an.classify("3 3 3 4 5 3"));
System.out.println(an.classify("4 4 4 5 5 6"));
System.out.println(an.classify("5 5 5 6 6 5"));
System.out.println(an.classify("6 6 6 7 6 8"));
System.out.println(an.classify("7 7 7 7 7 7"));
Scanner scan = new Scanner(new File("Input.txt"));
PrintWriter pw = new PrintWriter("Output.txt");
Integer count =new Integer(scan.nextLine());
for (int i=0;i<count;i++){
pw.write("Case #"+(i+1)+": "+an.classify(scan.nextLine())+"\n");
}
pw.close();
scan.close();
}

}

Alien Numbers

Google Code Jam Link
http://code.google.com/codejam/contest/dashboard?c=agdjb2RlamFtcg4LEghjb250ZXN0cxh5DA

Problem

The decimal numeral system is composed of ten digits, which we represent as "0123456789" (the digits in a system are written from lowest to highest). Imagine you have discovered an alien numeral system composed of some number of digits, which may or may not be the same as those used in decimal. For example, if the alien numeral system were represented as "oF8", then the numbers one through ten would be (F, 8, Fo, FF, F8, 8o, 8F, 88, Foo, FoF). We would like to be able to work with numbers in arbitrary alien systems. More generally, we want to be able to convert an arbitrary number that's written in one alien system into a second alien system.

Input

The first line of input gives the number of cases, N. N test cases follow. Each case is a line formatted as

alien_number source_language target_language

Each language will be represented by a list of its digits, ordered from lowest to highest value. No digit will be repeated in any representation, all digits in the alien number will be present in the source language, and the first digit of the alien number will not be the lowest valued digit of the source language (in other words, the alien numbers have no leading zeroes). Each digit will either be a number 0-9, an uppercase or lowercase letter, or one of the following symbols !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

Output

For each test case, output one line containing "Case #x: " followed by the alien number translated from the source language to the target language.

Limits

1 ≤ N ≤ 100.

Small dataset

1 ≤ num digits in alien_number ≤ 4,
2 ≤ num digits in source_language ≤ 16,
2 ≤ num digits in target_language ≤ 16.

Large dataset

1 ≤ alien_number (in decimal) ≤ 1000000000,
2 ≤ num digits in source_language ≤ 94,
2 ≤ num digits in target_language ≤ 94.

Sample


Input

Output
4
9 0123456789 oF8
Foo oF8 0123456789
13 0123456789abcdef 01
CODE O!CDE? A?JM!.

Case #1: Foo
Case #2: 9
Case #3: 10011
Case #4: JAM



import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Scanner;


public class AlienNumbers {

public String convert(String input){
String[] sp = input.split(" ");
String sourceLang = sp[1];
String destLang = sp[2];
String number =sp[0];
long exactVal =0;
for (int i=0;i<number.length();i++){
exactVal+=sourceLang.indexOf(number.substring(i, i+1))*Math.pow(sourceLang.length(), number.length()-i-1);
}
StringBuffer sb = new StringBuffer();
for (int i=0;exactVal!=0;i++){
sb.append(destLang.substring((int)(exactVal%destLang.length()),(int)((exactVal%destLang.length())+1)));
exactVal = (long)(exactVal/destLang.length());
}
return sb.reverse().toString();
}

public static void main(String[] args) throws FileNotFoundException {

AlienNumbers an = new AlienNumbers();
System.out.println(an.convert("9 0123456789 oF8"));
System.out.println(an.convert("Foo oF8 0123456789"));
System.out.println(an.convert("13 0123456789abcdef 01"));
System.out.println(an.convert("CODE O!CDE? A?JM!."));
InputStream is = new BufferedInputStream(new FileInputStream("Input.txt"));
Scanner scan = new Scanner(new File("Input.txt"));
PrintWriter pw = new PrintWriter("Output.txt");
Integer count =new Integer(scan.nextLine());
for (int i=0;i<count;i++){
pw.write("Case #"+(i+1)+": "+an.convert(scan.nextLine())+"\n");
}
pw.close();
scan.close();
}
}

Sunday, July 13, 2008

TopCoder Problem

http://www.topcoder.com/stat?c=problem_statement&pm=2922&rd=5855

Problem Statement


The Olympic Games in Athens end tomorrow. Given the results of the olympic disciplines, generate and return the medal table.



The results of the disciplines are given as a String[] results, where each element is in the format "GGG SSS BBB". GGG, SSS and BBB are the 3-letter country codes (three capital letters from 'A' to 'Z') of the countries winning the gold, silver and bronze medal, respectively.



The medal table is a String[] with an element for each country appearing in results. Each element has to be in the format "CCO G S B" (quotes for clarity), where G, S and B are the number of gold, silver and bronze medals won by country CCO, e.g. "AUT 1 4 1". The numbers should not have any extra leading zeros.

Sort the elements by the number of gold medals won in decreasing order. If several countries are tied, sort the tied countries by the number of silver medals won in decreasing order. If some countries are still tied, sort the tied countries by the number of bronze medals won in decreasing order. If a tie still remains, sort the tied countries by their 3-letter code in ascending alphabetical order.

Definition


Class:MedalTable
Method:generate
Parameters:String[]
Returns:String[]
Method signature:String[] generate(String[] results)
(be sure your method is public)



Constraints

-results contains between 1 and 50 elements, inclusive.
-Each element of results is formatted as described in the problem statement.
-No more than 50 different countries appear in results.

Examples

0)

{"ITA JPN AUS", "KOR TPE UKR", "KOR KOR GBR", "KOR CHN TPE"}
Returns:
{ "KOR 3 1 0",
"ITA 1 0 0",
"TPE 0 1 1",
"CHN 0 1 0",
"JPN 0 1 0",
"AUS 0 0 1",
"GBR 0 0 1",
"UKR 0 0 1" }
These are the results of the archery competitions.
1)

{"USA AUT ROM"}
Returns: { "USA 1 0 0",  "AUT 0 1 0",  "ROM 0 0 1" }

2)

{"GER AUT SUI", "AUT SUI GER", "SUI GER AUT"}
Returns: { "AUT 1 1 1",  "GER 1 1 1",  "SUI 1 1 1" }




My Solution:

import java.util.*;

public class MedalTable{
public String[] generate(String[] results){
Map<String,Country> map = new HashMap<String,Country>();
for (int i=0; i<results.length; i++){
String[] cont = results[i].split(" ");
Country cy = map.get(cont[0])!=null? map.get(cont[0]):new Country(cont[0]);
cy.g=cy.g+1;
map.put(cont[0],cy);
Country cy1 = map.get(cont[1])!=null? map.get(cont[1]):new Country(cont[1]);
cy1.s=cy1.s+1;
map.put(cont[1],cy1);
Country cy2 = map.get(cont[2])!=null? map.get(cont[2]):new Country(cont[2]);
cy2.b=cy2.b+1;
map.put(cont[2],cy2);
}

List<Country> list = new ArrayList<Country>();
list.addAll(map.values());
Collections.sort(list);
Collections.reverse(list);
System.out.println(list);
String[] r = new String[list.size()];
for (int i=0;i<list.size();i++){
r[i]=list.get(0).toString();
}
return r;
}

public class Country implements Comparable<Country> {
public int g=0;
public int s=0;
public int b=0;

public String name;

public Country(String name) {
this.name = name;
}
public String toString(){
return name+" "+g+" "+s+" "+b;
}

public int compareTo(Country con){
if (this.g!=con.g) return this.g-con.g;
if (this.s!=con.s) return this.s-con.s;
if (this.b!=con.b) return this.b-con.b;
return con.name.compareTo(this.name);
}
}

public static void main(String[] args){

MedalTable mt = new MedalTable();
mt.generate(new String[]{"ITA JPN AUS", "KOR TPE UKR", "KOR KOR GBR", "KOR CHN TPE"});
mt.generate(new String[]{"USA AUT ROM"});
mt.generate(new String[]{"GER AUT SUI", "AUT SUI GER", "SUI GER AUT"});

}
}

Problem Statement for TallPeople


Problem URL:

http://www.topcoder.com/stat?c=problem_statement&pm=2923&rd=5854

Problem Statement


A group of people stand before you arranged in rows and columns. Looking from above, they form an R by C rectangle of people. You will be given a String[] people containing the height of each person. Elements of people correspond to rows in the rectangle. Each element contains a space-delimited list of integers representing the heights of the people in that row. Your job is to return 2 specific heights in a int[]. The first is computed by finding the shortest person in each row, and then finding the tallest person among them (the "tallest-of-the-shortest"). The second is computed by finding the tallest person in each column, and then finding the shortest person among them (the "shortest-of-the-tallest").

Definition


Class:TallPeople
Method:getPeople
Parameters:String[]
Returns:int[]
Method signature:int[] getPeople(String[] people)
(be sure your method is public)



Constraints

-people will contain between 2 and 50 elements inclusive.
-Each element of people will contain between 3 and 50 characters inclusive.
-Each element of people will be a single space-delimited list of positive integers such that:

1) Each positive integer is between 1 and 1000 inclusive with no extra leading zeros.

2) Each element contains the same number of integers.

3) Each element contains at least 2 positive integers.

4) Each element does not contain leading or trailing whitespace.

Examples

0)

{"9 2 3",
"4 8 7"}
Returns: { 4,  7 }
The heights 2 and 4 are the shortest from the rows, so 4 is the taller of the two. The heights 9, 8, and 7 are the tallest from the columns, so 7 is the shortest of the 3.
1)

{"1 2",
"4 5",
"3 6"}
Returns: { 4,  4 }

2)

{"1 1",
"1 1"}
Returns: { 1,  1 }

My Solution:


public class TallPeople{
public int[] getPeople(String[] people){
int[][] a = new int[people.length][people[0].split(" ").length];
int row=people.length,col=people[0].split(" ").length;
for (int i=0;i< spl =" people[i].split(" j="0;" tallofshort="-1,shortOfTall="Integer.MAX_VALUE;" i="0;i<" s="a[i][0];" j="0;j<" s=" s<" tallofshort="s;" i="0;i<" s="a[0][i];" j="0;j<" s=" s"> a[j][i]?s:a[j][i];
}
if (shortOfTall > s) shortOfTall=s;
}
System.out.println(tallOfShort+" "+shortOfTall);
return new int[]{tallOfShort,shortOfTall};
}

public static void main(String[] args){
TallPeople tp = new TallPeople();
tp.getPeople(new String[]{"9 2 3","4 8 7"});
tp.getPeople(new String[]{"1 2","4 5","3 6"});
tp.getPeople(new String[]{"1 1","1 1"});
}
}

Saturday, July 12, 2008

Problem Statement for BusinessTasks

TopCoder Problem:
http://www.topcoder.com/stat?c=problem_statement&pm=1585&rd=6535

Problem Statement


A busy businessman has a number of equally important tasks which he must accomplish. To decide which of the tasks to perform first, he performs the following operation.

He writes down all his tasks in the form of a circular list, so the first task is adjacent to the last task. He then thinks of a positive number. This number is the random seed, which he calls n. Starting with the first task, he moves clockwise (from element 1 in the list to element 2 in the list and so on), counting from 1 to n. When his count reaches n, he removes that task from the list and starts counting from the next available task. He repeats this procedure until one task remains. It is this last task that he chooses to execute.

Given a String[] list representing the tasks and an int n, return the task which the businessman chooses to execute.


Definition


Class:BusinessTasks
Method:getTask
Parameters:String[], int
Returns:String
Method signature:String getTask(String[] list, int n)
(be sure your method is public)



Constraints

-list will contain between 2 and 50 elements inclusive.
-Each element in list will contain between 1 and 50 characters inclusive.
-Each element in list will contain only characters 'a'-'z'.
-n will be between 1 and 10000000 inclusive.

Examples

0)

{"a","b","c","d"}
2
Returns: "a"
We start counting from a. So a is 1, b is 2. We remove b, so list is now {a,c,d}. We continue from c. So c is 1, d is 2. We remove d, so list is now {a,c}. We continue from a. So a is 1, c is 2. We remove c, and now we are left with the last task a.
1)

{"a","b","c","d","e"}
3
Returns: "d"
We start counting from a. So a is 1, b is 2, c is 3. We remove c, now list = {a,b,d,e}. We continue from d. So d is 1, e is 2, a is 3. We remove a, now list = {b,d,e}. We continue from b. So b is 1, d is 2, e is 3. We remove e, now list = {b,d}. We continue from b. So b is 1, d is 2 and finally b is 3. We remove b, and now we are left with just one task d.
2)

{"alpha","beta","gamma","delta","epsilon"}
1
Returns: "epsilon"

3)

{"a","b"}
1000
Returns: "a"

4)

{"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t",
"u","v","w","x","y","z"}
17
Returns: "n"

5)

{"zlqamum","yjsrpybmq","tjllfea","fxjqzznvg","nvhekxr","am","skmazcey","piklp",
"olcqvhg","dnpo","bhcfc","y","h","fj","bjeoaxglt","oafduixsz","kmtbaxu",
"qgcxjbfx","my","mlhy","bt","bo","q"}
9000000
Returns: "fxjqzznvg"


My Solution:


import java.util.*;
public class BusinessTasks{

public String getTask(String[] list, int n){
List l = new ArrayList();
for (String a: list){
l.add(a);
}
int start =0;
while (l.size()!=1){
int index = start + n;
index = index % l.size();
if (index==0) {
index=l.size();
start=0;
} else {
start=index-1;
}
l.remove(index-1);
//System.out.println(l);
}
return l.get(0);
}

public static void main(String[] args){
BusinessTasks bt = new BusinessTasks();
System.out.println(bt.getTask(new String[]{"a","b","c","d"},2));
System.out.println(bt.getTask(new String[]{"a","b","c","d","e"},3));
System.out.println(bt.getTask(new String[]{"alpha","beta","gamma","delta","epsilon"},1));
System.out.println(bt.getTask(new String[]{"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t",
"u","v","w","x","y","z"},17));
System.out.println(bt.getTask(new String[]{"zlqamum","yjsrpybmq","tjllfea","fxjqzznvg","nvhekxr","am","skmazcey","piklp",
"olcqvhg","dnpo","bhcfc","y","h","fj","bjeoaxglt","oafduixsz","kmtbaxu",
"qgcxjbfx","my","mlhy","bt","bo","q"},9000000));
}
}