Last active
August 29, 2015 14:13
-
-
Save vnprc/39ef7bab5b085e0a4f3b to your computer and use it in GitHub Desktop.
Generate a list of random doubles. For each double, take the first digit after the decimal and count how many times that digit appears in the double. Sum the counts and print the results.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Random; | |
import java.util.TreeSet; | |
/** | |
* This is a programming exercise to generate a series of random doubles between | |
* 0.0 and 1.0 and return an ordered list of the count of the first digit after | |
* the decimal point for each double. | |
*/ | |
public class DigitCount { | |
public static final String USAGE = "usage: java DigitCount [numDigits]"; | |
public static void main(String args[]) { | |
if (args.length != 1) { | |
printUsageAndExit(); | |
} | |
int numDoubles = 0; | |
try { | |
numDoubles = Integer.parseInt(args[0]); | |
} catch (NumberFormatException e) { | |
printUsageAndExit(); | |
} | |
if (numDoubles <= 0) { | |
printUsageAndExit(); | |
} | |
List<Double> doubles = generateDoubles(numDoubles); | |
Map<String, Integer> counts = generateCounts(doubles); | |
printResults(counts); | |
} | |
/* | |
* Print all the counts in ascending order | |
*/ | |
private static void printResults(Map<String, Integer> digitMap) { | |
TreeSet<DigitCountTuple> treeSet = new TreeSet<DigitCountTuple>(); | |
// run the tuples through a TreeSet to sort them | |
for (String digit : digitMap.keySet()) { | |
treeSet.add(new DigitCountTuple(digit.charAt(0), digitMap.get(digit))); | |
} | |
// print the sorted collection of tuples | |
for (DigitCountTuple tuple : treeSet) { | |
System.out.println(tuple.toString()); | |
} | |
} | |
/* | |
* Generate a hashmap where the key is the digit in question and the | |
* value is the count of that digit across all Doubles. | |
*/ | |
private static Map<String, Integer> generateCounts(List<Double> doubles) { | |
Map<String, Integer> digitMap = new HashMap<String, Integer>(10); | |
for (Double dubble : doubles) { | |
String dubbleString = String.valueOf(dubble); | |
char firstDigit = dubbleString.charAt(2); | |
int count = countDigits(dubbleString, firstDigit); | |
if (digitMap.containsKey(String.valueOf(firstDigit))) { | |
// if we have already encountered this digit, increment it | |
digitMap.put(String.valueOf(firstDigit), | |
digitMap.get(String.valueOf(firstDigit)) + count); | |
} else { | |
// we haven't seen this digit yet, insert it | |
digitMap.put(String.valueOf(firstDigit), count); | |
} | |
} | |
return digitMap; | |
} | |
/* | |
* Count how many times a char appears in a string | |
*/ | |
private static int countDigits(String doubleString, char digit) { | |
int count = 0; | |
for (char c : doubleString.toCharArray()) { | |
if (c == digit) { | |
count++; | |
} | |
} | |
return count; | |
} | |
/* | |
* Generate a list of random doubles between 0.0 and 1.0 | |
*/ | |
private static List<Double> generateDoubles(int numDoubles) { | |
List<Double> doubles = new ArrayList<Double>(numDoubles); | |
Random r = new Random(); | |
for (int i = 0; i < numDoubles; i++) { | |
doubles.add(r.nextDouble()); | |
} | |
return doubles; | |
} | |
public static void printUsageAndExit() { | |
System.out.println(USAGE); | |
System.exit(0); | |
} | |
/** | |
* A simple class representing how many times a specific digit has | |
* appeared inside the doubles where it is the most significant | |
* digit after the decimal. | |
* | |
* Note: this class has a natural ordering that is inconsistent with | |
* equals (because it's probably not worth implementing equals() | |
* (and therefore hashcode()) for a coding exercise). | |
*/ | |
static class DigitCountTuple implements Comparable<DigitCountTuple> { | |
final char digit; | |
final int count; | |
public DigitCountTuple(char digit, int count) { | |
this.digit = digit; | |
this.count = count; | |
} | |
@Override | |
public int compareTo(DigitCountTuple other) { | |
int difference = this.count - other.count; | |
// if the count is the same we need some other ordering | |
// so they won't overwrite each other in the treeset | |
if (difference == 0) { | |
if (digit > other.digit) { | |
return 1; | |
} else { | |
return -1; | |
} | |
} | |
return difference; | |
} | |
@Override | |
public String toString() { | |
return "The digit " + digit + " appears " + count + " times (in the " | |
+ "doubles where it is the most significant digit after the " | |
+ "decimal point)."; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment