Skip to content

Instantly share code, notes, and snippets.

@Xirema
Created October 4, 2018 21:28
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 Xirema/744ba7a0c00ddf87320405942af5d651 to your computer and use it in GitHub Desktop.
Save Xirema/744ba7a0c00ddf87320405942af5d651 to your computer and use it in GitHub Desktop.
package org.scratch.test;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import org.scratch.main.util.Pair;
//Pair is a basic utility class that simply stores two fields. Can be implemented in about 50 lines of code if needed, based on Apache Commons Pair.
public class ClassPopularity {
public static class Results {
final List<Pair<Integer, Integer>> sample;
final List<Pair<Integer, Boolean>> thresholds;
public Results(List<Pair<Integer, Integer>> b, List<Pair<Integer, Boolean>> c) {
sample = b;
thresholds = c;
}
}
public static Results sample(Random engine, int numOfBuckets, int numOfParticipants, int threshold) {
List<Pair<Integer, Integer>> results = new ArrayList<>();
for(int i = 0; i < numOfBuckets; i++) {
results.add(Pair.of(i, 0));
}
for(int i = 0; i < numOfParticipants; i++) {
int bucket = engine.nextInt(numOfBuckets);
results.set(bucket, Pair.of(bucket, results.get(bucket).second + 1));
}
Collections.sort(results, new Comparator<Pair<Integer, Integer>>() {
@Override
public int compare(Pair<Integer, Integer> arg0,
Pair<Integer, Integer> arg1) {
return arg1.second - arg0.second;
}
});
List<Pair<Integer, Boolean>> thresholds = new ArrayList<>();
for(int i = 0; i < numOfBuckets; i++) {
threshold -= results.get(i).second;
thresholds.add(Pair.of(i, threshold <= 0));
}
// Collections.sort(results, new Comparator<Pair<Integer, Integer>>() {
// @Override
// public int compare(Pair<Integer, Integer> arg0,
// Pair<Integer, Integer> arg1) {
// return arg0.first - arg1.first;
// }
// });
return new Results(results, thresholds);
}
public static void main(String[] args) {
final int NUM_OF_BUCKETS = 12;
final int NUM_OF_PARTICIPANTS = 30;
final int THRESHOLD = (int)(NUM_OF_PARTICIPANTS * 0.50);
JFrame frame = new JFrame("Popularity Graph");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JTextArea resultsPanel = new JTextArea(NUM_OF_BUCKETS * 2 + 3, 50);
resultsPanel.setEditable(false);
resultsPanel.setFont(new Font("Courier New", Font.PLAIN, 18));
frame.getContentPane().add(resultsPanel);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
final AtomicBoolean running = new AtomicBoolean(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0) {
running.set(false);
}
});
final AtomicBoolean shouldPrintResults = new AtomicBoolean(true);
Timer updateTimer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
shouldPrintResults.set(true);
}
});
updateTimer.start();
long numOfTrials = 0;
long[] numOfSuccesses = new long[NUM_OF_BUCKETS];
Arrays.fill(numOfSuccesses, 0L);
Random engine = new Random();
while(running.get()) {
Results results = sample(engine, NUM_OF_BUCKETS, NUM_OF_PARTICIPANTS, THRESHOLD);
numOfTrials++;
for(Pair<Integer, Boolean> threshold : results.thresholds){
if(threshold.second)
numOfSuccesses[threshold.first]++;
}
if(shouldPrintResults.get()) {
shouldPrintResults.set(false);
setTextArea(resultsPanel, numOfTrials, numOfSuccesses, results, THRESHOLD, NUM_OF_PARTICIPANTS);
}
}
System.out.println("Done.");
updateTimer.stop();
}
private static void setTextArea(final JTextArea resultsPanel, final long numOfTrials, long[] numOfSuccesses, final Results currentResults, final int threshold, final int numOfParticipants) {
final long[] currentSuccesses = Arrays.copyOf(numOfSuccesses, numOfSuccesses.length);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
String text = "";
text += "Num of Trials:" + String.format("%10d", numOfTrials) + " (PARTICIPANTS=" + numOfParticipants + ")\n";
text += "Num of Successes (THRESHOLD=" + threshold + "): \n";
for(int i = 0; i < currentSuccesses.length; i++) {
text += String.format(" %2d: %10d (%5.2f%%)\n", i + 1, currentSuccesses[i], (double)currentSuccesses[i] / numOfTrials * 100.0);
}
text += "Current Results:\n";
for(Pair<Integer, Integer> ret : currentResults.sample) {
text += " " + String.format("%-10s", classNames.get(ret.first)) + ": " + ret.second + "\n";
}
text = text.substring(0, text.length() - 1);
resultsPanel.setText(text);
}
});
}
static Map<Integer, String> classNames = new HashMap<>();
static {
classNames.put(0, "Barbarian");
classNames.put(1, "Bard");
classNames.put(2, "Cleric");
classNames.put(3, "Druid");
classNames.put(4, "Fighter");
classNames.put(5, "Paladin");
classNames.put(6, "Rogue");
classNames.put(7, "Monk");
classNames.put(8, "Ranger");
classNames.put(9, "Wizard");
classNames.put(10, "Warlock");
classNames.put(11, "Sorcerer");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment