Java Rätsel

Hab noch einen. PI nach dem Zufallsprinzip "ausrechnen". Haben vermutlich viele von euch schon mal in der Schule gemacht, aber ich fand die Übung ziemlich cool =)

Vorgabe
Code:
		Random random = new Random();
		// kleiner tipp... was wird wohl "gehittet"
		int hits = 0;

		int runs = 999999;

		for (int i = 0; i < runs; i++) {
		// hier Code einfügen 
		}

		double myPI = // und hier Code einfügen

		System.out.println(Math.PI);
		System.out.println(myPI);
		System.out.println("difference = " + (Math.PI - myPI));

Ausgabe soll ungefähr gleich wie PI sein, je mehr runs, desto genauer.

Beispielausgabe:
Code:
3.141592653589793
3.1416427141642713
difference = -5.0060574478205666E-5
Gruss,
slowy
 
Kleine Alternative zum KnackMich "Rätsel":
Java:
package de.tutorials.training;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicLong;

class KnackMich{
    private String geheim = "Ich bin privat";
    private String privat = "Ich bin geheim";
}

public class PrivateInformationStealingExample {

    static Unsafe getUnsafe() throws Exception{
        Field field = AtomicLong.class.getDeclaredField("unsafe");
        field.setAccessible(true);
        return (Unsafe)field.get(null);
    }

    public static void main(String[] args) throws Exception{
        KnackMich k = new KnackMich();
        Unsafe u = getUnsafe();

        for(Field f : k.getClass().getDeclaredFields()){
            System.out.printf("%s=%s%n", f.getName(), u.getObject(k, u.objectFieldOffset(f)));
        }
    }
}

Gruß Tom
 
Zum RandomPI
package de.tutorials.training;

import static java.lang.Math.*;

public class RandomPI {

public static void main(String[] args) {
int inQuarterCircle = 0;
int iterations = 999999;

for (int i = 0; i < iterations; i++) {
inQuarterCircle += sqrt(pow(random(),2)+pow(random(),2)) <= 1 ? 1 : 0;
}

double myPI = inQuarterCircle*4.0/iterations;

System.out.println(Math.PI);
System.out.println(myPI);
System.out.println("difference = " + (Math.PI - myPI));
}
}

Sample output:
Code:
3.141592653589793
3.142155142155142
difference = -5.624885653490175E-4
 
Hier meine Lösung zu der Pi-Berechnung:

Java:
package de.tutorials.bratkartoffel;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.concurrent.ThreadLocalRandom;

public class MonteCarloPi {
	public static final int THREADS = 6;

	static class MonteCarloPiWorker extends Thread {
		private int hits = 0;
		private final int rounds;

		public MonteCarloPiWorker(ThreadGroup group, int rounds) {
			super(group, "MonteCarloPiWorker");
			this.rounds = rounds;
		}

		@Override
		public void run() {
			int hits = 0, rounds = this.rounds;
			double x, y;
			ThreadLocalRandom rnd = ThreadLocalRandom.current();

			for (long i = 0; i < rounds; i++) {
				x = rnd.nextDouble();
				y = rnd.nextDouble();

				if (Math.sqrt((x * x) + (y * y)) < 1.0) {
					hits++;
				}
			}

			this.hits = hits;
		}

		public int getHits() {
			return hits;
		}
	}

	private final int iRounds;

	public MonteCarloPi(int rounds) {
		iRounds = rounds - (rounds % THREADS);
	}

	public void doWork() throws InterruptedException {
		int hits = 0;
		if (Integer.valueOf(1).equals(THREADS)) {
			System.out.println("Not threading.");
			MonteCarloPiWorker worker = new MonteCarloPiWorker(null, iRounds);
			worker.run();
			hits = worker.getHits();
		} else {
			System.out.println("Using " + THREADS + " threads.");
			ThreadGroup group = new ThreadGroup("MonteCarloPi");
			for (int i = 0; i < THREADS; i++) {
				new MonteCarloPiWorker(group, iRounds / THREADS).start();
			}

			MonteCarloPiWorker[] threadArray = new MonteCarloPiWorker[THREADS];
			group.enumerate(threadArray);

			synchronized (group) {
				group.wait();
			}

			for (MonteCarloPiWorker thread : threadArray) {
				hits += thread.getHits();
			}
		}

		BigDecimal result = null;
		{
			BigDecimal dQuarter = new BigDecimal(4.0);
			BigDecimal dHits = new BigDecimal(hits);
			BigDecimal dRounds = new BigDecimal(iRounds);

			BigDecimal dParts = dHits.divide(dRounds, MathContext.DECIMAL64);
			result = dQuarter.multiply(dParts);
		}

		System.out.println("Rounds:  " + iRounds);
		System.out.println("Math.PI: " + Math.PI);
		System.out.println("Calc.PI: " + result);
		System.out.println("difference = " + (Math.PI - result.doubleValue()));
		System.out.println();
	}

	public static void main(String[] args) throws InterruptedException {
		long start = System.currentTimeMillis();
		new MonteCarloPi(100000000).doWork();
		long end = System.currentTimeMillis();

		System.out.println("Dauer: " + (end - start) + " ms.");
	}
}

Ausgabe:
Code:
Using 6 threads.
Rounds:  100000002
Math.PI: 3.141592653589793
Calc.PI: 3.1416844971663100
difference = -9.184357651692565E-5

Dauer: 340 ms.

Using 6 threads.
Rounds:  100000002
Math.PI: 3.141592653589793
Calc.PI: 3.1416984171660316
difference = -1.0576357623870436E-4

Dauer: 339 ms.

Using 6 threads.
Rounds:  100000002
Math.PI: 3.141592653589793
Calc.PI: 3.1415952571680948
difference = -2.60357830184077E-6

Dauer: 277 ms.

Ich weiß, etwas overkill und übers Ziel hinausgeschossen, aber was solls ;)

Grüße,
BK
 
Zuletzt bearbeitet:
Hallo,

schick :)
... zum Thema Einzeiler ;-)
Java:
package de.tutorials.training.java8.lambda;
 
import java.util.stream.IntStream;
 
import static java.lang.Math.*;
import static java.util.concurrent.ThreadLocalRandom.*;
 
/**
 * Author: Thomas Darimont
 */
public class LambdaPi {
 
    public static void main(String[] args) {
        int n = 9999999;
        double pi = IntStream.range(0, n)
                             .mapToDouble((a) -> 4.0 * 1.0 / n * (sqrt(pow(current().nextDouble(),2)+pow(current().nextDouble(),2)) <= 1 ? 1 : 0))
                             .sum();
        System.out.printf("%s delta-abs: %s",pi, PI-pi);
    }
}
:)

Gruß Tom
 
So, ich hab auch noch ein kleines Rätsel:

Gegeben sind folgende Interfaces:
Java:
interface A {
  int getA();
}

interface B {
  int getB();
}

Wie würde eine generische Methode aussehen, bei denen der Parameter sowohl A, als auch B implementieren muss?

Und noch gleich eins:
Was ist die Ausgabe von folgendem Programm?
Java:
class Test {
    public static void main(String[] args) {
        int big = 1234567890;
        float approx = big;
        System.out.println(big - (int)approx);
    }
}

Grüße,
BK
 
Zuletzt bearbeitet:
Zurück