Skip to content

Instantly share code, notes, and snippets.

@GeorgiKarapetrov
Last active April 9, 2019 20:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GeorgiKarapetrov/81e4d8847d1858bcc5e8ab79b9ca4fd9 to your computer and use it in GitHub Desktop.
Save GeorgiKarapetrov/81e4d8847d1858bcc5e8ab79b9ca4fd9 to your computer and use it in GitHub Desktop.

Keys

You are presented with a bunch of lines that look like this:

8239b961379a4f9f854fd19d82b56dc9 24
8239b961379a4f9f854fd19d82b56dc9 39
8239b961379a4f9f854fd19d82b56dc9 39
8239b961379a4f9f854fd19d82b56dc9 18
8239b961379a4f9f854fd19d82b56dc9 25
533cc20dc02647cb98c9cc534112e092 66
533cc20dc02647cb98c9cc534112e092 12

The general format is {key} {value}, where {key} is some string (a hex representation of uuid4, to be preciese) and {value} is a positive integer.

{key} and {value} are separated by exactly one interval.

The task

In a language of your choice, implement a program, that reads those lines from the standard input (stdin) and outputs the top 3 keys, regarding the sum of their values.

For example, if we have the following input:

f 1
g 2
f 3
h 10
f 5
h 2

The output should be:

h: 12
f: 9
g: 2

Where the sum of the values of all lines, containing h is 12, containing f is 9 and containing g is 2.

If there are keys with equal summed values in top3, output all the keys with the same summed value, ordered alphabetically and separated by , .

For example, if we have the following input:

c 1
b 1
a 1

The output should be:

a, b, c: 1

The output should end with a newline.

The tests

Alongside the task, add tests, that proove your solution is correct. This is entirely up to you.

/*
* This program lists the top three UUIDv4s with regards to the sum of their values. It outputs the value of the said sums.
* The list is user generated.
*
* N.B. No mechanisms have been implemented to safeguard the user from missusing the program.
* This can be done with some conditional statements in the prompt method and reprompting the user to correct the input, as well as try/catch clauses.
*
* N.B. It is not clear what to do when we have more than three competing values for the top three places.
* For instance, if three keys compete for the first two positions, what do we do with the next in line?
* Do we consider it to be a winner?
*
* I solved this uncertainty by choosing to prioritise the sums of the values of each key.
* This is, fisrt place is for all keys tied for first place, etc, second place - for all tiers for second place, etc.
*/
package keys;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import java.util.UUID;
/**
*
* @author Georgi Karapetrov
*/
public class Keys
{
private static Hashtable<String, Integer> keys; // a map to store the input
private static ArrayList<Map.Entry<String, Integer>> sorted; // a list that can be sorted by the values of the map rather than the keys
//constructor
public Keys()
{
keys = new Hashtable<String, Integer>();
sorted = new ArrayList<Map.Entry<String, Integer>>();
}
//returns hash table
private Hashtable<String, Integer> getTable() {
return keys;
}
//promt, and storing the keys and summing over the values
public static void prompt()
{
Scanner input = new Scanner( System.in ); // scanner for standart input
//prompt
System.out.print( "This program outputs the first three UUIDv4 keys from a list regarding the sum of their values. Let us create this list.\n"
+ "Enter the first keys separated from their values by only a single space like this:\n"
+ "8239b961379a4f9f854fd19d82b56dc9 24 \n"
+ "8239b961379a4f9f854fd19d82b56dc9 39 \n"
+ "533cc20dc02647cb98c9cc534112e092 166 \n"
+ "Enter EXIT if you are finished.\n" );
//store UUID's and add theirvalues while the list is being generated
while (input.hasNext())
{
//check if user terminates
String key = input.next();
if (key.toLowerCase().contains("exit"))
{
break;
}
//add key and value if the user hasn't terminated
//probram would break in most cases where the input format changes from (String + " " + int + "\n")
int value = input.nextInt();
addData(key, value);
}
}
//add input line to hashtable
public static void addData(String key, int value)
{
//add value to the existing value of an existing key
if(keys.containsKey(key))
{
keys.put(key, value+keys.get(key));
}
//create new key and its value
else
keys.put(key,value);
}
public static ArrayList sortTable( Hashtable<String, Integer> table )
{
//Transfer as List and sort
ArrayList unsorted = new ArrayList(table.entrySet());
Collections.sort(unsorted, new ComparatorImpl());
return unsorted;
}
public static void printResults(ArrayList list)
{
int j = 0; // counts the tier (winner, second, third)
for(int i=0; i < list.size(); ++i)
{
//break when we've printed the top three
if ( j == 3 )
{
break;
}
//word wrap results
else if ( i < list.size() - 1 )
{
int currentValue = Integer.parseInt( list.get(i).toString().split("=")[1] );
int nextValue = Integer.parseInt( list.get(i+1).toString().split("=")[1] );
if( currentValue == nextValue )
System.out.print( list.get(i).toString().split("=")[0] + ", " );
else
{
System.out.println( list.get(i).toString().split("=")[0] + ": " + list.get(i).toString().split("=")[1] );
++j;
}
}
// To handle small lists as well as lists with less than three tier possition
// we need to avoid attempting to check whether the key in the current itteration
// has the same value as the next key
// when we have reached the end of the list
else if ( i == list.size() - 1 )
{
System.out.println( list.get(i).toString().split("=")[0] + ": " + list.get(i).toString().split("=")[1] );
}
}
}
//populate table automatically for test
/*
* This test is no proof that the program always halts or always works as intended.
* Neither is this test able to test the prompt() method from the main file as we cannot simulate stdin.
* However as many times as I have run this test, the tested methods run as intended.
* Also as many times as I ran the main program, it works as long as you keep the input format (String + " " + int + "\n")
*/
public static void generateTable()
{
//store each UUID and integer, in order to be able to print them
Random integerGenerator = new Random();
String uUID;
int integer;
System.out.println("Input:" );
//add 19 values and probably 19 UUIDs, any number should work in place of "19"
for(int i=1; i <= 19; ++i)
{
uUID = UUID.randomUUID().toString();
integer = integerGenerator.nextInt();
//test adding method
addData( uUID, integer );
System.out.println(uUID + " " + integer );
}
System.out.println("Output:" );
}
public static void main(String[] args)
{
Keys keys1 = new Keys();
//call prompt (comment out the following line if you want to test automatically)
keys1.prompt();
//or generate table automatically (uncomment the following line if you want to test automatically)
//keys1.generateTable();
//compute and print result
keys1.printResults( sortTable( keys1.getTable( ) ) );
} // end method main
private static class ComparatorImpl implements Comparator<Map.Entry<String, Integer>> {
public ComparatorImpl() {
}
@Override
public int compare(Map.Entry<String, Integer> keyOne, Map.Entry<String, Integer> keyTwo) {
//compare keys by value, sort in descending order
return keyTwo.getValue().compareTo(keyOne.getValue());
}
}
} // end class Keys
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment