Skip to content

Instantly share code, notes, and snippets.

@coderodde
Last active February 18, 2026 13:12
Show Gist options
  • Select an option

  • Save coderodde/bc718d5d2b7c421177d25a5cae26ce6f to your computer and use it in GitHub Desktop.

Select an option

Save coderodde/bc718d5d2b7c421177d25a5cae26ce6f to your computer and use it in GitHub Desktop.
Ohejlma Todennököisyyslaskenta I 2026 kurssia varten: viikko 5 tehtävä 5.
package viikko5;
import java.util.Objects;
public final class Fraction implements Comparable<Fraction> {
public static final Fraction ZERO = new Fraction(0);
private final long numerator;
private final long denominator;
public Fraction(long numerator, long denominator) {
if (denominator == 0) {
throw new ArithmeticException("Denominator cannot be zero.");
}
// Normalize sign (denominator always positive)
if (denominator < 0) {
numerator = -numerator;
denominator = -denominator;
}
long gcd = gcd(Math.abs(numerator), denominator);
this.numerator = numerator / gcd;
this.denominator = denominator / gcd;
}
public Fraction(long number) {
this(number, 1L);
}
public static Fraction of(long numerator, long denominator) {
return new Fraction(numerator, denominator);
}
public static Fraction of(long number) {
return of(number, 1L);
}
public long getNumerator() {
return numerator;
}
public long getDenominator() {
return denominator;
}
/* ================= Arithmetic ================= */
public Fraction add(Fraction other) {
long num = this.numerator * other.denominator
+ other.numerator * this.denominator;
long den = this.denominator * other.denominator;
return new Fraction(num, den);
}
public Fraction subtract(Fraction other) {
long num = this.numerator * other.denominator
- other.numerator * this.denominator;
long den = this.denominator * other.denominator;
return new Fraction(num, den);
}
public Fraction multiply(Fraction other) {
return new Fraction(
this.numerator * other.numerator,
this.denominator * other.denominator
);
}
public Fraction divide(Fraction other) {
if (other.numerator == 0) {
throw new ArithmeticException("Division by zero fraction.");
}
return new Fraction(
this.numerator * other.denominator,
this.denominator * other.numerator
);
}
public Fraction negate() {
return new Fraction(-numerator, denominator);
}
public Fraction reciprocal() {
if (numerator == 0) {
throw new ArithmeticException("Zero has no reciprocal.");
}
return new Fraction(denominator, numerator);
}
public double asDouble() {
return (double) numerator / (double) denominator;
}
/* ================= Comparison ================= */
@Override
public int compareTo(Fraction other) {
// Avoid floating-point comparison
return Long.compare(
this.numerator * other.denominator,
other.numerator * this.denominator
);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Fraction)) return false;
Fraction other = (Fraction) obj;
return numerator == other.numerator &&
denominator == other.denominator;
}
@Override
public int hashCode() {
return Objects.hash(numerator, denominator);
}
@Override
public String toString() {
if (denominator == 1) {
return Long.toString(numerator);
}
return numerator + "/" + denominator;
}
public String toTexDollar() {
return "$\\frac{" + numerator + "}{" + denominator + "}$";
}
public String toTex() {
return "\\frac{" + numerator + "}{" + denominator + "}";
}
/* ================= Utilities ================= */
private static long gcd(long a, long b) {
while (b != 0) {
long tmp = b;
b = a % b;
a = tmp;
}
return a;
}
}
package viikko5;
import java.util.HashMap;
import java.util.Map;
public class Tehtavat5 {
public static void tehtava5() {
Map<Integer, Map<Integer, Fraction>> m = new HashMap<>();
for (int s = 2; s <= 12; ++s) {
m.put(s, new HashMap<>());
for (int x = 1; x <= 6; ++x) {
m.get(s).put(x, Fraction.ZERO);
}
}
// Table initialized!
for (int s = 2; s <= 12; ++s) {
for (int b = 1; b <= 6; ++b) {
int a = s - b;
Fraction p =
(1 <= a && a <= 6
? Fraction.of(1, 36)
: Fraction.ZERO);
m.get(s).put(b, p);
}
}
for (int j = 2; j <= 12; ++j) {
System.out.printf("%2d & ", j);
for (int i = 1; i <= 6; ++i) {
if (i > 1) {
System.out.print("& ");
}
Fraction p = m.get(j).get(i);
System.out.print(p);
}
Fraction rs = rowSum(m, j);
System.out.printf(" & %s \\\\%n", rs);
}
printColumnSums(m);
printRowWiseTotal(m);
System.out.println("Poikkeavat todennäköisyydet:");
printDifferentEtnries(m);
printSubtaskCProbability(m);
}
private static void printRowWiseTotal(
Map<Integer, Map<Integer, Fraction>> m) {
System.out.println();
Fraction total = Fraction.ZERO;
for (int s = 2; s <= 12; ++s) {
total = total.add(rowSum(m, s));
}
System.out.println(total);
}
private static void printColumnSums(
Map<Integer, Map<Integer, Fraction>> m) {
System.out.print(" ");
Fraction total = Fraction.ZERO;
for (int b = 1; b <= 6; ++b) {
Fraction s = columnSum(m, b);
total = total.add(s);
System.out.printf(" & %s", s);
}
System.out.printf(" & %s \\\\", total);
}
private static Fraction columnSum(Map<Integer, Map<Integer, Fraction>> m,
int b) {
Fraction sum = Fraction.ZERO;
for (int y = 2; y <= 12; ++y) {
Map<Integer, Fraction> mm = m.get(y);
sum = sum.add(mm.get(b));
}
return sum;
}
private static Fraction rowSum(Map<Integer, Map<Integer, Fraction>> m,
int row) {
Fraction sum = Fraction.ZERO;
for (Fraction f : m.get(row).values()) {
sum = sum.add(f);
}
return sum;
}
private static Fraction fx(int x, Map<Integer, Map<Integer, Fraction>> m) {
Fraction s = Fraction.ZERO;
for (Map<Integer, Fraction> row : m.values()) {
s = s.add(row.get(x));
}
return s;
}
private static Fraction fy(int y, Map<Integer, Map<Integer, Fraction>> m) {
Fraction s = Fraction.ZERO;
Map<Integer, Fraction> mm = m.get(y);
for (Fraction d : mm.values()) {
s = s.add(d);
}
return s;
}
private static void printDifferentEtnries(
Map<Integer, Map<Integer, Fraction>> m) {
int rowNumber = 1;
for (int y = 2; y <= 12; ++y) {
for (int x = 1; x <= 6; ++x) {
Fraction fxy = m.get(y).get(x);
Fraction fx = fx(x, m);
Fraction fy = fy(y, m);
Fraction fxfy = fx.multiply(fy);
if (!fxfy.equals(fxy)) {
System.out.printf(
"Rivi %2d: x = %d, y = %d: %s vs %s\n",
rowNumber++,
x,
y,
fxfy,
fxy);
}
}
}
}
private static void
printSubtaskCProbability(Map<Integer, Map<Integer, Fraction>> m) {
Fraction ex = ex(m);
Fraction ey = ey(m);
Fraction varx = varx(m, ex);
Fraction vary = vary(m, ey);
Fraction cov = cov(m, ex, ey);
double corr = cov.asDouble() /
(Math.sqrt(varx.asDouble() * vary.asDouble()));
System.out.println("Corr(X, Y) = " + corr);
}
private static Fraction ex(Map<Integer, Map<Integer, Fraction>> m) {
Fraction fp = Fraction.ZERO;
for (int x = 1; x <= 6; ++x) {
fp = fp.add(Fraction.of(x).multiply(fx(x, m)));
}
System.out.println();
return fp;
}
private static Fraction ey(Map<Integer, Map<Integer, Fraction>> m) {
Fraction fp = Fraction.ZERO;
for (int y = 2; y <= 12; ++y) {
fp = fp.add(Fraction.of(y).multiply(fy(y, m)));
}
System.out.println();
return fp;
}
private static Fraction varx(Map<Integer, Map<Integer, Fraction>> m,
Fraction ex) {
Fraction fp = Fraction.ZERO;
for (int x = 1; x <= 6; ++x) {
Fraction t = Fraction.of(x).subtract(ex);
Fraction pow = t.multiply(t);
fp = fp.add(pow.multiply(fx(x, m)));
}
return fp;
}
private static Fraction vary(Map<Integer, Map<Integer, Fraction>> m,
Fraction ey) {
Fraction fp = Fraction.ZERO;
for (int y = 2; y <= 12; ++y) {
Fraction t = Fraction.of(y).subtract(ey);
Fraction pow = t.multiply(t);
fp = fp.add(pow.multiply(fy(y, m)));
}
return fp;
}
private static Fraction cov(Map<Integer, Map<Integer, Fraction>> m,
Fraction ex,
Fraction ey) {
Fraction fp = Fraction.ZERO;
for (int x = 1; x <= 6; ++x) {
for (int y = 2; y <= 12; ++y) {
Fraction term1 = Fraction.of(x).subtract(ex);
Fraction term2 = Fraction.of(y).subtract(ey);
fp = fp.add(term1.multiply(term2).multiply(m.get(y).get(x)));
}
}
return fp;
}
public static void main(String[] args) {
tehtava5();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment