Created
February 9, 2016 23:28
-
-
Save Hadyn/01c74b4c7fe2c0effdf5 to your computer and use it in GitHub Desktop.
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
package io.hadyn.politics; | |
import java.io.BufferedReader; | |
import java.io.BufferedWriter; | |
import java.io.IOException; | |
import java.nio.file.Files; | |
import java.nio.file.Paths; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Set; | |
import java.util.TreeSet; | |
import java.util.function.Supplier; | |
import java.util.stream.Collectors; | |
/** | |
* @author Hadyn Fitzgerald | |
*/ | |
public class Runner { | |
public static void main(String... args) { | |
try(BufferedReader reader = Files.newBufferedReader(Paths.get("data.txt"))) { | |
// Chomp the header. | |
chomp(reader, 6); | |
List<DataEntry> entries = new ArrayList<>(); | |
while(reader.ready()) { | |
entries.add(readEntry(reader)); | |
} | |
// Remove any entries that are not for clinton or sanders since we will not be analyzing | |
// their data. | |
entries.removeIf(entry -> !entry.getCandidateName().equals("Clinton") && | |
!entry.getCandidateName().equals("Sanders")); | |
assert(entries.size() / 2 == 1683); | |
Set<String> countiesAndPrecincts = entries.stream() | |
.map(entry -> entry.getCountyName() + "+" + entry.getPrecinctName()) | |
.collect(Collectors.toSet()); | |
List<Result> results = new ArrayList<>(); | |
for(String countyAndPrecinct : countiesAndPrecincts) { | |
String county = countyAndPrecinct.substring(0, countyAndPrecinct.indexOf('+')); | |
String precinct = countyAndPrecinct.substring(countyAndPrecinct.indexOf('+') + 1); | |
List<DataEntry> precinctEntries = entries.stream() | |
.filter(entry -> entry.getCountyName().equals(county) && | |
entry.getPrecinctName().equals(precinct)) | |
.collect(Collectors.toList()); | |
if(precinctEntries.size() > 2) { | |
throw new IllegalStateException("Expected only two results."); | |
} | |
Result precinctResult = new Result(county, precinct); | |
for(DataEntry entry : precinctEntries) { | |
if(entry.getCandidateName().equals("Clinton")) { | |
precinctResult.setClintonEntry(entry); | |
} else { | |
precinctResult.setSandersEntry(entry); | |
} | |
} | |
results.add(precinctResult); | |
} | |
Supplier<TreeSet<Result>> supplier = () -> | |
new TreeSet<>((first, second) -> Double.compare(first.getEquivalent(), | |
second.getEquivalent())); | |
// Create a new heap of the results we can then iterate over to find the best results. This | |
// set will be in ascending order. | |
TreeSet<Result> sortedResults = results.stream() | |
.collect(Collectors.toCollection(supplier)); | |
Result bestSandersResult = null; | |
Result bestClintonResult = null; | |
// Search for the best precinct result for each canidate. | |
Result result; | |
while(bestSandersResult == null || bestClintonResult == null) { | |
result = sortedResults.pollLast(); | |
if(result.isSandersPrecinct()) { | |
if(bestSandersResult == null) { | |
bestSandersResult = result; | |
} | |
} else { | |
if(bestClintonResult == null) { | |
bestClintonResult = result; | |
} | |
} | |
} | |
try(BufferedWriter writer = Files.newBufferedWriter(Paths.get("bestprecincts.txt"))) { | |
writer.write(bestSandersResult.toString()); | |
writer.newLine(); | |
writer.write(bestClintonResult.toString()); | |
writer.newLine(); | |
writer.flush(); | |
} catch (IOException ex) { | |
System.out.println("Failed to write to output file."); | |
} | |
} catch (IOException e) { | |
System.out.println("Failed to open the data file."); | |
} | |
} | |
private static void chomp(BufferedReader reader, int lineCount) throws IOException { | |
if(lineCount < 1) { | |
throw new IllegalArgumentException("Line count cannot be less than one."); | |
} | |
while(lineCount-- > 0) { | |
reader.readLine(); | |
} | |
} | |
private static DataEntry readEntry(BufferedReader reader) throws IOException { | |
String countyName = reader.readLine(); | |
String precictName = reader.readLine(); | |
String canidateName = reader.readLine(); | |
int delegatesWon = Integer.parseInt(reader.readLine()); | |
int delegatesToElect = Integer.parseInt(reader.readLine()); | |
double equivalent = Double.parseDouble(reader.readLine()); | |
return new DataEntry(countyName, precictName, canidateName, | |
delegatesWon, delegatesToElect, equivalent); | |
} | |
private static class DataEntry { | |
private String countyName; | |
private String precinctName; | |
private String candidateName; | |
private int delegatesWon; | |
private int delegatesToElect; | |
private double equivalent; | |
DataEntry(String countyName, String precinctName, String candidateName, | |
int delegatesWon, int delegatesToElect, double equivalent) { | |
this.countyName = countyName; | |
this.precinctName = precinctName; | |
this.candidateName = candidateName; | |
this.delegatesWon = delegatesWon; | |
this.delegatesToElect = delegatesToElect; | |
this.equivalent = equivalent; | |
} | |
public String getCountyName() { | |
return countyName; | |
} | |
public String getPrecinctName() { | |
return precinctName; | |
} | |
public String getCandidateName() { | |
return candidateName; | |
} | |
public int getDelegatesWon() { | |
return delegatesWon; | |
} | |
public int getDelegatesToElect() { | |
return delegatesToElect; | |
} | |
public double getEquivalent() { | |
return equivalent; | |
} | |
} | |
private static class Result { | |
String precinct; | |
String county; | |
DataEntry sandersEntry; | |
DataEntry clintonEntry; | |
Result(String county, String precinct) { | |
this.precinct = precinct; | |
this.county = county; | |
} | |
void setSandersEntry(DataEntry entry) { | |
sandersEntry = entry; | |
} | |
void setClintonEntry(DataEntry entry) { | |
clintonEntry = entry; | |
} | |
double getSandersEquivalent() { | |
return sandersEntry.getEquivalent(); | |
} | |
double getClintonEquivalent() { | |
return clintonEntry.getEquivalent(); | |
} | |
double getEquivalent() { | |
return Math.max(getSandersEquivalent() - getClintonEquivalent(), | |
getClintonEquivalent() - getSandersEquivalent()); | |
} | |
boolean isSandersPrecinct() { | |
return getSandersEquivalent() > getClintonEquivalent(); | |
} | |
@Override | |
public String toString() { | |
StringBuilder builder = new StringBuilder(); | |
builder.append(isSandersPrecinct() ? "Sanders" : "Clinton") | |
.append(" Biggest Win: ").append(getEquivalent()) | |
.append(" state delegates from " + precinct) | |
.append(" in ") | |
.append(county); | |
return builder.toString(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment