import java.util.Random;
public class DiceProbs {

	protected int m_numDice = 1;
	protected int m_numSides = 6;

	public DiceProbs (int numDice, int numSides) {
		if (numDice > 0 && numSides > 0) {
			m_numDice = numDice;
			m_numSides = numSides;
		} else {
			out ("num dice '"+numDice+"' invalid.");
			out ("or num sides '"+numSides+"' invalid.");
		}
	}

	// brute force approach for now...
	public void computeAndDisplayProbs() {
		int[] rollCounts = new int[1+(m_numDice*m_numSides)];
		for (int i=0; i<rollCounts.length; i++) {
			rollCounts[i] = 0;
		}
		computeRollCounts(rollCounts, m_numDice, 0);
		displayRollCounts(rollCounts);
	}

	public void computeLizardmanColdBloodedRoll(int val) {
		int succ=0, fail=0;
		int d1, d2, d3;
		Random rand = new Random(System.currentTimeMillis());
		for (int i=0; i<100000; i++) {
			d1 = rand.nextInt(6) + 1;
			d2 = rand.nextInt(6) + 1;
			d3 = rand.nextInt(6) + 1;
			if (d1 + d2 <= val) {
				succ++;
			} else if ( d1 + d3 <= val) {
				succ++;
			} else if ( d2 + d3 <= val) {
				succ++;
			} else {
				fail++;
			}
		}
		int total = succ+fail;
		out(""+succ+"/"+total+" succeeded.");
	}

	public void computeRollCounts(
		int[] rollCounts, 
		int numDice, 
		int restCurRoll
	) {
		if (numDice == 1) {
			for (int i=1; i<=m_numSides; i++) {
				rollCounts[restCurRoll+i]++;
			}
		} else {
			for (int i=1; i<=m_numSides; i++) {
				computeRollCounts(
					rollCounts, 
					numDice-1,
					restCurRoll+i
				);
			}
		}
	}

	public void displayRollCounts(int[] rollCounts) {
		double expectedSum = Math.pow ((double) m_numSides, (double) m_numDice);
		int sum=0;
		double totalProb=0.0;
		double moreThan=1.0;
		double lessThan=0.0;
		out ("roll\tcount\tprob\tmore\tless");
		for (int i=m_numDice; i<rollCounts.length; i++) {
			double prob = ((double) rollCounts[i]) / expectedSum;
			double finalProb = round(prob);
			moreThan -= prob;
			out (""+i+"\t"
				+rollCounts[i]+"\t"
				+finalProb+"\t"
				+round(moreThan)+"\t"
				+round(lessThan)+"\t"
			);
			lessThan += prob;

			sum+=rollCounts[i];
			totalProb += finalProb;
		}
		out ("total = "+sum);
        out ("");
		out ("(debug) expected total = "+expectedSum);
		out ("(debug) totalProb = "+totalProb);

	}

	public double round(double num) {
		long prob = Math.round(
			num * 10000
		);
		return ((double) prob) / 100;
	}

	public static void main (String args[]) {
		if (args.length > 1) {
			DiceProbs dice = new DiceProbs(
				Integer.parseInt(args[0]),
				Integer.parseInt(args[1])
			);
			dice.computeAndDisplayProbs();
		} else {
			DiceProbs dice = new DiceProbs(
				Integer.parseInt(args[0]),
				1
			);
			dice.computeLizardmanColdBloodedRoll(Integer.parseInt(args[0]));
		}
	}

	public static void out (String s) {
		System.out.println(s);
	}
}

