Skip to content

Instantly share code, notes, and snippets.

@vnprc
Last active August 29, 2015 14:13
Show Gist options
  • Save vnprc/39ef7bab5b085e0a4f3b to your computer and use it in GitHub Desktop.
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.
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