Compare commits

..

1 Commits

Author SHA1 Message Date
Selebrator 74ad4e9f4c try to generify the observer pattern 7 years ago

@ -11,7 +11,7 @@ project.ext.junitVersion = '5.3.1'
mainClassName = '_9._2.Lights'
sourceCompatibility = 12
sourceCompatibility = 1.8
repositories {
mavenCentral()

@ -1,59 +0,0 @@
package _10._1;
public class SearchThread extends Thread {
private int[] array;
private int value;
private int from;
private int to;
private boolean found = false;
public SearchThread(int[] array, int value, int from, int to) {
this.array = array;
this.value = value;
this.from = from;
this.to = to;
}
public void run() {
for (int i = this.from; i < this.to; i++) {
if (this.array[i] == this.value) {
this.found = true;
System.out.println(this.getName() + ": found");
return;
}
}
System.out.println(this.getName() + ": not found");
}
public boolean getFound() {
return found;
}
public static void main(String[] args) {
int[] array = { 2, 7, 3, 9, 23 };
arraySearch(array,7);
}
private static void arraySearch(int[] array, int value) {
SearchThread thread1 = new SearchThread(array, value, 0, array.length/2);
SearchThread thread2 = new SearchThread(array, value, array.length/2, array.length);
thread1.setName("Thread 1");
thread2.setName("Thread 2");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
if (thread1.getFound() || thread2.getFound()) {
System.out.println("Found: true");
} else {
System.out.println("Found: false");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

@ -1,53 +0,0 @@
package _10._2;
import provided._10._2.*;
public class QuickSortThreaded extends QuickSort implements Runnable {
private int[] numbers;
private int leftIndex;
private int rightIndex;
public QuickSortThreaded() {
}
public QuickSortThreaded(int[] numbers, int leftIndex, int rightIndex) {
this.numbers = numbers;
this.leftIndex = leftIndex;
this.rightIndex = rightIndex;
}
@Override
public void run() {
quickSort(numbers, leftIndex, rightIndex);
}
/**
* sortiert das uebergebene Array in aufsteigender Reihenfolge
* gemaess dem QuickSort-Algorithmus (parallel!)
*/
public static void sort(int[] numbers) {
new QuickSortThreaded().quickSort(numbers, 0, numbers.length - 1);
}
/**
* der Quicksort-Algorithmus wird auf dem Array zwischen den
* angegebenen Indizes ausgefuehrt
*/
protected void quickSort(int[] numbers, int leftIndex, int rightIndex) {
if (leftIndex < rightIndex) {
int pivotIndex = divide(numbers, leftIndex, rightIndex);
Thread threadLeft = new Thread(new QuickSortThreaded(numbers, leftIndex, pivotIndex - 1));
Thread threadRight = new Thread(new QuickSortThreaded(numbers, pivotIndex + 1, rightIndex));
threadLeft.start();
threadRight.start();
try {
threadLeft.join(); // Wait for first thread.
threadRight.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

@ -1,59 +0,0 @@
package _10._3;
import java.awt.*;
import provided._10._3.ImageFilter;
public class ImageFilterThreaded extends ImageFilter {
class FilterThread implements Runnable {
private int x1;
private int x2;
private int y1;
private int y2;
private Color[][] result;
private float[][] filter;
private FilterThread(int x1, int x2, int y1, int y2, Color[][] result, float[][] filter) {
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
this.result = result;
this.filter = filter;
}
@Override
public void run() {
for (int x = x1; x < x2; x++) {
for (int y = y1; y < y2; y++) {
filterPixel(result, x, y, filter);
}
}
}
}
@Override
protected Color[][] filterMatrix(float[][] filter) {
Color[][] result = new Color[matrix.length][matrix[0].length];
Thread threadLB = new Thread(new FilterThread(0, matrix.length/2, matrix[0].length/2, matrix[0].length,result,filter));
Thread threadRB = new Thread(new FilterThread(matrix.length/2, matrix.length, matrix[0].length/2, matrix[0].length,result,filter));
Thread threadLT = new Thread(new FilterThread(0, matrix.length/2, 0, matrix[0].length/2,result,filter));
Thread threadRT = new Thread(new FilterThread(matrix.length/2, matrix.length, 0, matrix[0].length/2,result,filter));
threadLB.start();
threadRB.start();
threadLT.start();
threadRT.start();
try {
threadLB.join();
threadRB.join();
threadLT.join();
threadRT.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
}
}

@ -1,55 +0,0 @@
package _10._4;
public class NameOutput extends Thread {
private NumberData currentNumber;
private int threadNumber;
public NameOutput(int threadNumber, NumberData currentNumber) {
this.threadNumber = threadNumber;
this.currentNumber = currentNumber;
}
@Override
public void run() {
while (true) {
synchronized (currentNumber) {
while (currentNumber.getNumber() != threadNumber) {
try {
currentNumber.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.getName());
currentNumber.increaseNumber();
}
}
}
public static void main(String[] args) {
int numberOfThreads = 3;
NumberData currentNumber = new NumberData(numberOfThreads);
for (int i = 0; i < numberOfThreads; i++) {
Thread thread = new NameOutput(i, currentNumber);
thread.start();
}
}
}
class NumberData {
private int number = 0;
private int modulo;
public NumberData(int modulo) {
this.modulo = modulo;
}
public int getNumber() {
return number;
}
public void increaseNumber() {
this.number = (this.number + 1) % this.modulo;
notifyAll();
}
}

@ -1,14 +0,0 @@
package _10._4.alternative;
public abstract class NameOutput {
private NameOutput() {
}
public static void main(String[] args) {
final int n = 3;
for(int i = 0; i < n; i++) {
new NameOutputFairLock().start();
}
}
}

@ -1,31 +0,0 @@
package _10._4.alternative;
// ordered by creation time, deadlocks if any thread in the chain is interrupted.
public class NameOutputBusyWaiting extends Thread {
private static final Object LOCK = new Object();
private static int counter = 0;
private static int total = 0;
private final int number;
public NameOutputBusyWaiting() {
synchronized(LOCK) {
this.number = total;
total++;
}
}
@Override
public void run() {
while(!this.isInterrupted()) {
synchronized(LOCK) {
if(this.number == counter) {
System.out.println(this.getName());
counter = (counter + 1) % total;
}
}
}
}
}

@ -1,22 +0,0 @@
package _10._4.alternative;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
// ordered by least recent access since creation
public class NameOutputFairLock extends Thread {
private static final Lock LOCK = new ReentrantLock(true);
@Override
public void run() {
while(!this.isInterrupted()) {
LOCK.lock();
try {
System.out.println(this.getName());
} finally {
LOCK.unlock();
}
}
}
}

@ -1,37 +0,0 @@
package _10._4.alternative;
// ordered by creation time, deadlocks if any thread in the chain is interrupted.
public class NameOutputWaitNotify extends Thread {
private static final Object LOCK = new Object();
private static int counter = 0;
private static int total = 0;
private final int number;
public NameOutputWaitNotify() {
synchronized(LOCK) {
this.number = total;
total++;
}
}
@Override
public void run() {
while(!this.isInterrupted()) {
synchronized(LOCK) {
while(this.number != counter) {
try {
LOCK.wait();
} catch(InterruptedException e) {
System.out.println(this.getName() + " was interrupted");
}
}
System.out.println(this.getName());
counter = (counter + 1) % total;
LOCK.notifyAll();
}
}
}
}

@ -1,46 +0,0 @@
package _11._1;
import provided.IO;
import java.util.concurrent.Semaphore;
class Output extends Thread {
public void run() {
try {
InOut.getSemaphore().acquire();
System.out.println(InOut.getValue() * InOut.getValue());
} catch (InterruptedException e) {
}
}
}
class Input extends Thread {
public void run() {
InOut.setValue(IO.readInt("Value: "));
InOut.getSemaphore().release();
}
}
public class InOut {
private static Semaphore semaphore = new Semaphore(0);
private static int value = 0;
public static Semaphore getSemaphore() { return semaphore; }
public static int getValue() {
return value;
}
public static void setValue(int value) {
InOut.value = value;
}
public static void main(String[] args) {
new Output().start();
new Input().start();
}
}

@ -1,101 +0,0 @@
package _11._2;
public class Barriers {
private final static int NUMBER = 3;
public static void main(String[] args) {
Counter obj = new Counter(NUMBER);
NumberRunner[] runner = new NumberRunner[NUMBER];
for (int i = 0; i < NUMBER; i++) {
runner[i] = new NumberRunner(i, obj);
}
for (int i = 0; i < NUMBER; i++) {
runner[i].start();
}
}
}
class Counter {
private final int numb; // Anzahl Threads
private int numberIn = 0; // Anzahl der Threads an Sperre
private int numberOut; // Anzahl der laufenden Threads
public Counter(int number) {
this.numb = number;
this.numberOut = number;
}
public int getMax() { return this.numb; }
public int getIn() {
return this.numberIn;
}
public int getOut() { return this.numberOut; }
public void resetIn() { this.numberIn = 0; }
public void resetOut() { this.numberOut = 0; }
public void incrementIn() { this.numberIn++; }
public void incrementOut() { this.numberOut++; }
}
class NumberRunner extends Thread {
private int number;
private final Counter obj;
public NumberRunner(int n, Counter obj) {
this.number = n;
this.obj = obj;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("Thread " + number + ": " + i);
if (i%10 == 0 && i != 0) {
synchronized (obj) {
try {
// warte, falls andere Threads von vorheriger Sperre noch nicht wieder gestartet sind
while (obj.getOut() < obj.getMax()) {
obj.wait();
}
// Thread kommt an aktueller Sperre an
obj.incrementIn();
// letzter Thread, der ankommt, benachrichtigt alle, dass es weiter gehen kann
if (obj.getIn() >= obj.getMax()) {
obj.resetOut();
obj.notifyAll();
}
// Threads warten, bis alle angekommen sind
while (obj.getIn() < obj.getMax()) {
obj.wait();
}
// Thread startet wieder
obj.incrementOut();
// der letzte Thread, der startet, benachrichtigt alle, dass die naechste Sperre freigegeben ist
if (obj.getOut() == obj.getMax()) {
obj.resetIn();
obj.notifyAll();
}
} catch (InterruptedException e) {
}
}
}
}
}
}

@ -1,16 +0,0 @@
package _11._2.alternative;
public class Barriers {
public static final int NUMBER_OF_RUNNERS = 3;
public static void main(String[] args) {
NumberRunner[] runners = new NumberRunner[NUMBER_OF_RUNNERS];
for(int i = 0; i < NUMBER_OF_RUNNERS; i++) {
runners[i] = new NumberRunner(i);
}
for(int i = 0; i < NUMBER_OF_RUNNERS; i++) {
runners[i].start();
}
}
}

@ -1,28 +0,0 @@
package _11._2.alternative;
public class Checkpoint {
private final Object lock = new Object();
private int groupSize;
private int gathered = 0;
public Checkpoint(int groupSize) {
this.groupSize = groupSize;
}
/**
* Blocks until called by {@link #groupSize} different Threads,
* then wakes all of them up again.
*/
public void gather() throws InterruptedException {
synchronized(this.lock) {
if(++this.gathered != this.groupSize) {
this.lock.wait();
} else {
this.gathered = 0;
System.out.println("Group gathered");
this.lock.notifyAll();
}
}
}
}

@ -1,27 +0,0 @@
package _11._2.alternative;
public class NumberRunner extends Thread {
private static final Checkpoint CHECKPOINT = new Checkpoint(Barriers.NUMBER_OF_RUNNERS);
private final int id;
public NumberRunner(int id) {
this.id = id;
}
@Override
public void run() {
for(int i = 0; i < 1000; i++) {
if(i % 10 == 0) {
try {
CHECKPOINT.gather();
} catch(InterruptedException e) {
throw new IllegalStateException("Group can never be complete again, because one of the members got lost", e);
}
}
System.out.println("Thread " + this.id + ": " + i);
}
}
}

@ -1,35 +0,0 @@
package _11._3;
import provided._11._3.Item;
import provided._11._3.Knapsack;
import provided._11._3.Selection;
import java.util.*;
public class KnapsackDynamic extends Knapsack {
public KnapsackDynamic(int capacity, Collection<Item> candidates) {
super(capacity, candidates);
}
@Override
public Selection pack() {
return this.pack(new Selection(), new HashMap<>());
}
private Selection pack(Selection parent, Map<Integer, Selection> memory) {
return memory.computeIfAbsent(parent.getWeight(), weight -> {
final Collection<Selection> children = new ArrayList<>();
for(Item candidate : this.candidates) {
if(parent.getWeight() + candidate.getWeight() <= this.capacity) {
children.add(pack(new Selection(parent, candidate), memory));
}
}
return children.stream()
.max(Comparator.comparingDouble(Selection::getValue))
.orElse(parent);
});
}
}

@ -1,43 +0,0 @@
package _11._3;
import provided._11._3.Item;
import provided._11._3.Knapsack;
import provided._11._3.Selection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
public class KnapsackGreedy extends Knapsack {
private static final Comparator<Item> DESCENDING_ITEM_VALUE_COMPARATOR
= Comparator.comparing(Item::getValue).reversed();
public KnapsackGreedy(int capacity, Collection<Item> candidates) {
super(capacity, candidates);
}
@Override
public Selection pack() {
final List<Item> orderedCandidates = new ArrayList<>(this.candidates);
orderedCandidates.sort(DESCENDING_ITEM_VALUE_COMPARATOR);
/*
* Fügt das wertvollste Item hinzu, solange es noch passt, geht
* dann zum nächst wertvolleren Item über und wiederholt den Vorgang
* so lange bis kein Item mehr passt.
*/
Selection selection = new Selection();
for(Item candidate : orderedCandidates) {
while(selection.getWeight() + candidate.getWeight() <= this.capacity) {
selection = new Selection(selection, candidate);
/*
* Der Speicher leidet hier sehr,
* weil Selection#add(Item) private ist.
*/
}
}
return selection;
}
}

@ -1,35 +0,0 @@
package _11._3;
import provided._11._3.Item;
import provided._11._3.Knapsack;
import provided._11._3.Selection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
public class KnapsackRecursive extends Knapsack {
public KnapsackRecursive(int capacity, Collection<Item> candidates) {
super(capacity, candidates);
}
@Override
public Selection pack() {
return this.pack(new Selection());
}
private Selection pack(Selection parent) {
final Collection<Selection> children = new ArrayList<>();
for(Item candidate : this.candidates) {
if(parent.getWeight() + candidate.getWeight() <= this.capacity) {
children.add(pack(new Selection(parent, candidate)));
}
}
return children.stream()
.max(Comparator.comparingDouble(Selection::getValue))
.orElse(parent);
}
}

@ -1,26 +0,0 @@
package _12._1;
import provided._12._1.Fibonacci;
import java.util.HashMap;
import java.util.Map;
public class FibonacciDynamic extends Fibonacci {
protected Map<Integer, Long> map = new HashMap<>();
public FibonacciDynamic() {
this.map.put(0, (long) 0);
this.map.put(1, (long) 1);
}
@Override
public long calculate(int n) {
if (this.map.containsKey(n)) {
return this.map.get(n);
} else {
long result = calculate(n-1) + calculate(n-2);
this.map.put(n, result);
return result;
}
}
}

@ -1,47 +0,0 @@
package _12._1;
public class FibonacciDynamicParallel extends FibonacciDynamic {
@Override
public long calculate(int n) {
if (this.map.containsKey(n)) {
return this.map.get(n);
} else {
FibonacciThread thread1 = new FibonacciThread(n-1);
FibonacciThread thread2 = new FibonacciThread(n-2);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
long result = thread1.getResult() + thread2.getResult();
this.map.put(n, result);
return result;
}
}
class FibonacciThread extends Thread {
private int n;
private long result;
public FibonacciThread(int n) {
this.n = n;
}
@Override
public void run() {
result = calculate(n);
}
public long getResult() {
return result;
}
}
}

@ -1,50 +0,0 @@
package _12._1;
import provided._12._1.Fibonacci;
public class FibonacciParallel extends Fibonacci {
@Override
public long calculate(int n) {
if (n == 0) {
return 0;
} else if (n == 1) {
return 1;
} else {
FibonacciThread thread1 = new FibonacciThread(n-1);
FibonacciThread thread2 = new FibonacciThread(n-2);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return thread1.getResult() + thread2.getResult();
}
}
class FibonacciThread extends Thread {
private int n;
private long result;
public FibonacciThread(int n) {
this.n = n;
}
@Override
public void run() {
result = calculate(n);
}
public long getResult() {
return result;
}
}
}

@ -1,17 +0,0 @@
package _12._1;
import provided._12._1.Fibonacci;
public class FibonacciRecursive extends Fibonacci {
@Override
public long calculate(int n) {
if (n == 0) {
return 0;
} else if (n == 1) {
return 1;
} else {
return calculate(n-1) + calculate(n-2);
}
}
}

@ -1,33 +0,0 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
/*
* F(2n) = F(n) * (2*F(n+1) - F(n)).
* F(2n+1) = F(n+1)^2 + F(n)^2.
*
* O(log(n))
*/
public class FibonacciDoubling extends Fibonacci {
@Override
public long calculate(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must not be negative. Negafibonacci numbers are not supported.");
}
long a = 0L;
long b = 1L;
for(int bit = Integer.highestOneBit(n); bit != 0; bit >>>= 1) {
long aTemp = a * ((2 * b) - a);
long bTemp = a * a + b * b;
a = aTemp;
b = bTemp;
if((n & bit) != 0) {
long c = a + b;
a = b;
b = c;
}
}
return a;
}
}

@ -1,20 +0,0 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
// iterative, dynamic programing with minimal memory usage
public class FibonacciDynamicIterative extends Fibonacci {
@Override
public long calculate(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must not be negative. Negafibonacci numbers are not supported.");
}
long a = 0L, b = 1L, c;
for(int i = 0; i < n; i++) {
c = a + b;
a = b;
b = c;
}
return a;
}
}

@ -1,31 +0,0 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
import java.util.HashMap;
import java.util.Map;
// uses recursion and dynamic programing with persistent memory
public class FibonacciDynamicRecursivePersistent extends Fibonacci {
private final Map<Integer, Long> memory = new HashMap<>();
{
this.memory.put(0, 0L);
this.memory.put(1, 1L);
}
@Override
public long calculate(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must not be negative. Negafibonacci numbers are not supported.");
}
if(this.memory.containsKey(n)) {
return this.memory.get(n);
}
long result = calculate(n - 1) + calculate(n - 2);
this.memory.put(n, result);
return result;
}
}

@ -1,46 +0,0 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
import java.util.HashMap;
import java.util.Map;
// eats up the heap
public class FibonacciDynamicRecursivePersistentParallel extends Fibonacci {
private final Map<Integer, Long> memory = new HashMap<>();
{
this.memory.put(0, 0L);
this.memory.put(1, 1L);
}
@Override
public long calculate(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must not be negative. Negafibonacci numbers are not supported.");
}
if(this.memory.containsKey(n)) {
return this.memory.get(n);
}
final long result;
{
final long[] parts = new long[2];
Thread big = new Thread(() -> parts[0] = calculate(n - 1));
Thread small = new Thread(() -> parts[1] = calculate(n - 2));
big.start();
small.start();
try {
big.join();
small.join();
result = parts[0] + parts[1];
} catch(InterruptedException e) {
throw new IllegalStateException(e);
}
}
this.memory.put(n, result);
return result;
}
}

@ -1,16 +0,0 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
public class FibonacciRecursive extends Fibonacci {
@Override
public long calculate(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must not be negative. Negafibonacci numbers are not supported.");
}
if(n == 0 || n == 1) {
return n;
}
return calculate(n - 1) + calculate(n - 2);
}
}

@ -1,30 +0,0 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
// rest in peace ram
public class FibonacciRecursiveParallel extends Fibonacci {
@Override
public long calculate(int n) {
if(n < 0) {
throw new IllegalArgumentException("n must not be negative. Negafibonacci numbers are not supported.");
}
if(n == 0 || n == 1) {
return n;
}
final long[] parts = new long[2];
Thread big = new Thread(() -> parts[0] = calculate(n - 1));
Thread small = new Thread(() -> parts[1] = calculate(n - 2));
big.start();
small.start();
try {
big.join();
small.join();
return parts[0] + parts[1];
} catch(InterruptedException e) {
throw new IllegalStateException(e);
}
}
}

@ -1,70 +0,0 @@
package _12._1.lukas;
import provided._12._1.Fibonacci;
public class FibonacciTiming {
private static final int[] NUMBERS = new int[]{ 3, 5, 8, 12, 9, 18, 15, 10, 7, 11, 20 };
private static final Fibonacci RECURSIVE = new FibonacciRecursive();
private static final Fibonacci PARALLEL_RECURSIVE = new FibonacciRecursiveParallel();
private static final Fibonacci DYNAMIC = new FibonacciDynamicRecursivePersistent();
private static final Fibonacci PARALLEL_DYNAMIC = new FibonacciDynamicRecursivePersistentParallel();
private static final Fibonacci ITERATIVE = new FibonacciDynamicIterative();
// can take a few minutes
public static void main(String[] args) {
System.out.println("# Sequential");
System.out.println("FibonacciRecursive (first): " + formatTime(
Timing.measureNanos(() -> generateHeat(RECURSIVE))
));
System.out.println("FibonacciDynamicRecursivePersistent (first): " + formatTime(
Timing.measureNanos(() -> generateHeat(DYNAMIC))
));
System.out.println("FibonacciDynamicIterative (first): " + formatTime(
Timing.measureNanos(() -> generateHeat(ITERATIVE))
));
System.out.println("FibonacciRecursive (1M iteration average): " + formatTime(
Timing.measureAverageNanos(1_000_000, () -> generateHeat(RECURSIVE))
));
System.out.println("FibonacciDynamicRecursivePersistent (1M iteration average): " + formatTime(
Timing.measureAverageNanos(1_000_000, () -> generateHeat(DYNAMIC))
));
System.out.println("FibonacciDynamicIterative (1M iteration average): " + formatTime(
Timing.measureAverageNanos(1_000_000, () -> generateHeat(ITERATIVE))
));
System.out.println("# Parallel");
System.out.println("FibonacciRecursiveParallel (first): " + formatTime(
Timing.measureNanos(() -> generateHeat(PARALLEL_RECURSIVE))
));
System.out.println("FibonacciDynamicRecursivePersistentParallel (first): " + formatTime(
Timing.measureNanos(() -> generateHeat(PARALLEL_DYNAMIC))
));
System.out.println("FibonacciRecursiveParallel (10 iteration average): " + formatTime(
Timing.measureAverageNanos(10, () -> generateHeat(PARALLEL_RECURSIVE))
));
System.out.println("FibonacciDynamicRecursivePersistentParallel (1M iteration average): " + formatTime(
Timing.measureAverageNanos(1_000_000, () -> generateHeat(PARALLEL_DYNAMIC))
));
}
private static void generateHeat(Fibonacci calculator) {
for(int n : NUMBERS) {
calculator.calculate(n);
}
}
private static String formatTime(double nanos) {
double digits = Math.log10(nanos);
if(digits > 9) {
return Math.round(nanos / 1e7) / 1e2 + " seconds";
} else if(digits > 6) {
return Math.round(nanos / 1e4) / 1e2 + " milliseconds";
} else if(digits > 3) {
return Math.round(nanos / 1e1) / 1e2 + " microseconds";
} else {
return Math.round(nanos) + " nanoseconds";
}
}
}

@ -1,18 +0,0 @@
package _12._1.lukas;
public class Timing {
public static long measureNanos(Runnable runnable) {
long start = System.nanoTime();
runnable.run();
return System.nanoTime() - start;
}
public static double measureAverageNanos(int iterations, Runnable runnable) {
long start = System.nanoTime();
for(int i = 0; i < iterations; i++) {
runnable.run();
}
return (System.nanoTime() - start) / (double) iterations;
}
}

@ -184,18 +184,6 @@ public class Lecture {
Files.write(file, lines);
}
/*
* Bitte um Feedback, untere lösung (loadText2)
* macht weniger Annahmen.
*
* Zeilenumbrüche zwischen name-value Paaren.
* Whitespace weglassen macht probleme. Ist kompatibel mit
* dem outout von saveText.
* Nur eine Lecture pro Datei.
*
*
*
*/
public static Lecture loadText(String filename) throws IOException {
Path file = Paths.get(filename);
List<String> data = Files.readAllLines(file);

@ -56,7 +56,6 @@ public class SonReader implements Closeable {
}
}
/* true untill the current inner most array or object is out of elements */
public boolean hasNext() throws IOException {
int c = this.nextNonWhitespace();
this.rememberChar(c);
@ -94,7 +93,6 @@ public class SonReader implements Closeable {
return name.toString().trim();
}
/* put the reder in a state where it can accept a name */
private void prepareName() throws IOException {
SonState state = this.peekState();
if(state == NONEMPTY_OBJECT) { // not first in an object
@ -106,8 +104,6 @@ public class SonReader implements Closeable {
this.replaceTopState(DANGLING_NAME);
}
/* put the reder in a state where it can accept a value
*/
private void prepareValue() throws IOException {
SonState state = this.peekState();
switch(state) {
@ -140,8 +136,6 @@ public class SonReader implements Closeable {
return value.toString().trim();
}
/* should recursively skip a value */
//TODO funktioniert nicht so wie es soll
public void skipValue() throws IOException {
this.prepareValue();
int count = 0;

@ -1,6 +1,8 @@
package _9._3;
public class Ship extends Observable {
import _9._3.observer.Observable;
public class Ship extends Observable<Ship, ShipEvent> {
private boolean sailsSet = false;
private boolean cannonsLoaded = false;
private int heading = 0;
@ -13,6 +15,10 @@ public class Ship extends Observable {
}
}
public boolean isSailsSet() {
return this.sailsSet;
}
public void strikeSails() {
if (sailsSet) {
sailsSet = false;
@ -37,12 +43,12 @@ public class Ship extends Observable {
}
}
public boolean isCannonsLoaded() {
return this.cannonsLoaded;
}
public void turnLeft() {
if (heading - 90 < 0) {
heading = 360 + ((heading - 90) % 360);
} else {
heading = (heading - 90) % 360;
}
heading = (heading - 90) % 180;
this.setChanged();
notifyObservers(ShipEvent.TURN_LEFT);
}
@ -52,4 +58,8 @@ public class Ship extends Observable {
this.setChanged();
notifyObservers(ShipEvent.TURN_RIGHT);
}
public int getHeading() {
return this.heading;
}
}

@ -1,6 +1,6 @@
package _9._3;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
public enum ShipEvent {
@ -13,7 +13,6 @@ public enum ShipEvent {
TURN_RIGHT;
public static ShipEvent getRandomShipEvent() {
Random random = new Random();
return values()[random.nextInt(values().length)];
return values()[ThreadLocalRandom.current().nextInt(values().length)];
}
}

@ -1,11 +1,10 @@
package _9._3;
import provided._9.Observer;
import _9._3.observer.Observer;
public class ShipLog implements Observer {
private int heading = 0;
public class ShipLog implements Observer<Ship, ShipEvent> {
@Override
public void update(Observable who, ShipEvent what) {
public void update(Ship who, ShipEvent what) {
switch (what) {
case SET_SAILS:
System.out.println("Sails set.");
@ -20,16 +19,10 @@ public class ShipLog implements Observer {
System.out.println("Cannons fired.");
break;
case TURN_LEFT:
if (heading - 90 < 0) {
heading = 360 + ((heading - 90) % 360);
} else {
heading = (heading - 90) % 360;
}
System.out.println("Turned left. New heading " + heading + " degrees.");
System.out.println("Turned left. New heading " + who.getHeading() + " degrees.");
break;
case TURN_RIGHT:
heading = (heading + 90) % 360;
System.out.println("Turned right. New heading " + heading + " degrees.");
System.out.println("Turned right. New heading " + who.getHeading() + " degrees.");
break;
}
}

@ -1,19 +1,17 @@
package _9._3;
import provided._9.Observer;
package _9._3.observer;
import java.util.ArrayList;
import java.util.List;
public abstract class Observable {
private List<Observer> observers = new ArrayList<>();
public abstract class Observable<Who extends Observable<Who, What>, What> {
private List<Observer<Who, What>> observers = new ArrayList<>();
private boolean changed = false;
public void addObserver(Observer o) {
public void addObserver(Observer<Who, What> o) {
this.observers.add(o);
}
public void removeObserver(Observer o) {
public void removeObserver(Observer<Who, What> o) {
this.observers.remove(o);
}
@ -29,10 +27,10 @@ public abstract class Observable {
return changed;
}
public void notifyObservers(ShipEvent what) {
public void notifyObservers(What what) {
if (this.isChanged()) {
for (Observer observer : observers) {
observer.update(this, what);
for (Observer<Who, What> observer : observers) {
observer.update((Who) this, what);
}
this.clearChanged();
}

@ -0,0 +1,5 @@
package _9._3.observer;
public interface Observer<Who extends Observable<Who, What>, What> {
void update(Who who, What what);
}

@ -1,80 +0,0 @@
package provided._10._2;
public class QuickSort {
/**
* sortiert das uebergebene Array in aufsteigender Reihenfolge
* gemaess dem QuickSort-Algorithmus
*/
public static void sort(int[] numbers) {
new QuickSort().quickSort(numbers, 0, numbers.length - 1);
}
/**
* der Quicksort-Algorithmus wird auf dem Array zwischen den
* angegebenen Indizes ausgefuehrt
*/
protected void quickSort(int[] numbers, int leftIndex, int rightIndex) {
if (leftIndex < rightIndex) {
int pivotIndex = divide(numbers, leftIndex, rightIndex);
quickSort(numbers, leftIndex, pivotIndex - 1);
quickSort(numbers, pivotIndex + 1, rightIndex);
}
}
/**
* liefert den Index des Pivot-Elementes und ordnet das Array innerhalb
* der angegebenen Indizes so um, dass alle Zahlen links vom Index
* kleiner oder gleich und alle Zahlen rechts vom Index groesser
* oder gleich dem Pivot-Element sind
*/
protected int divide(int[] numbers, int leftIndex, int rightIndex) {
int pivotIndex = choosePivotIndex(numbers, leftIndex, rightIndex);
int pivotValue = numbers[pivotIndex];
// das Pivot-Element kommt nach ganz rechts im Array
swap(numbers, pivotIndex, rightIndex);
int left = leftIndex - 1;
int right = rightIndex;
// ordne das Array so um, dass jeweils alle Elemente links vom
// Zeiger left kleiner und alle Elemente rechts vom Zeiger right
// groesser als das Pivot-Element sind
do {
left++;
while (left <= rightIndex && numbers[left] <= pivotValue)
left++;
right--;
while (right >= leftIndex && numbers[right] >= pivotValue)
right--;
if (left < right) {
swap(numbers, left, right);
}
} while (left < right);
// platziere das Pivot-Element an seine korrekte Position
if (left < rightIndex) {
swap(numbers, left, rightIndex);
return left;
} else {
return rightIndex;
}
}
/**
* waehlt einen beliebigen Index zwischen den angegebenen Indizes
*/
protected int choosePivotIndex(int[] numbers, int leftIndex, int rightIndex) {
// in diesem Fall einfach der mittleren Index
return (leftIndex + rightIndex) / 2;
}
/**
* tauscht die Elemente des Arrays an den angegebenen Indizes
*/
protected void swap(int[] numbers, int index1, int index2) {
if (index1 != index2) {
int tmp = numbers[index1];
numbers[index1] = numbers[index2];
numbers[index2] = tmp;
}
}
}

@ -1,26 +0,0 @@
package provided._10._2;
import _10._2.QuickSortThreaded;
public class QuickSortTest {
public static void main(String[] args) {
int[] numbers = {2, 3, 9, 33, -2, 4, 55, 66, -234};
print(numbers);
QuickSort.sort(numbers);
print(numbers);
int[] numbers2 = {2, 3, 9, 33, -2, 4, 55, 66, -234};
print(numbers2);
QuickSortThreaded.sort(numbers2);
print(numbers2);
}
private static void print(int[] numbers) {
for (int number : numbers) {
System.out.print(number + " ");
}
System.out.println();
}
}

@ -1,113 +0,0 @@
package provided._10._3;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImageFilter {
private static final int FILTER_SIZE = 3;
private static final int OFFSET = FILTER_SIZE / 2;
public static final float[][] FILTER_BLUR = new float[][] {
{ 0.111f, 0.111f, 0.111f },
{ 0.111f, 0.111f, 0.111f },
{ 0.111f, 0.111f, 0.111f }
};
public static final float[][] FILTER_SHARPEN = new float[][] {
{ 0.f, -1f, 0.f },
{ -1f, 5f, -1f },
{ 0.f, -1f, 0.f }
};
public static final float[][] FILTER_LINES = new float[][] {
{ -1f, -1f, -1f },
{ -1f, 8f, -1f },
{ -1f, -1f, -1f }
};
protected Color[][] matrix = new Color[0][0];
public void setImage(File input) throws IOException {
BufferedImage img = ImageIO.read(input);
getMatrix(img);
}
public void applyFilter(float[][] filter, File output) throws IOException, InvalidFilterException {
if (filter == null || filter.length != FILTER_SIZE || filter[0].length != FILTER_SIZE) {
throw new InvalidFilterException();
}
Color[][] result = filterMatrix(filter);
BufferedImage img = new BufferedImage(result.length, result[0].length, BufferedImage.TYPE_INT_ARGB);
setMatrix(img, result);
ImageIO.write(img, "jpg", output);
}
protected Color[][] filterMatrix(float[][] filter) {
Color[][] result = new Color[matrix.length][matrix[0].length];
for (int x = 0; x < matrix.length; x++) {
for (int y = 0; y < matrix[x].length; y++) {
filterPixel(result, x, y, filter);
}
}
return result;
}
protected void filterPixel(Color[][] result, int x, int y, float[][] filter) {
Color[][] colors = getColorMatrix(x, y);
float red = 0;
float green = 0;
float blue = 0;
for (int i = 0; i < FILTER_SIZE; i++) {
for (int j = 0; j < FILTER_SIZE; j++) {
red += (float) colors[i][j].getRed() * filter[i][j];
green += (float) colors[i][j].getGreen() * filter[i][j];
blue += (float) colors[i][j].getBlue() * filter[i][j];
}
}
red = Math.min(red, 255);
red = Math.max(red, 0);
green = Math.min(green, 255);
green = Math.max(green, 0);
blue = Math.min(blue, 255);
blue = Math.max(blue, 0);
result[x][y] = new Color(Math.round(red), Math.round(green), Math.round(blue));
}
protected Color[][] getColorMatrix(int x, int y) {
Color[][] result = new Color[FILTER_SIZE][FILTER_SIZE];
for (int i = 0; i < FILTER_SIZE; i++) {
for (int j = 0; j < FILTER_SIZE; j++) {
result[i][j] = getColor(x + (i - OFFSET), y + (j - OFFSET));
}
}
return result;
}
protected Color getColor(int x, int y) {
x = Math.min(x, matrix.length - 1);
x = Math.max(x, 0);
y = Math.min(y, matrix[0].length - 1);
y = Math.max(y, 0);
return matrix[x][y];
}
private void setMatrix(BufferedImage img, Color[][] matrix) {
for (int x=0;x<matrix.length;x++) {
for (int y=0;y<matrix[x].length;y++) {
img.setRGB(x, y, matrix[x][y].getRGB());
}
}
}
private void getMatrix(BufferedImage img) {
matrix = new Color[img.getWidth()][img.getHeight()];
for (int x=0;x<img.getWidth();x++) {
for (int y=0;y<img.getHeight();y++) {
matrix[x][y] = new Color(img.getRGB(x, y));
}
}
}
}

@ -1,51 +0,0 @@
package provided._10._3;
import _10._3.ImageFilterThreaded;
import java.io.File;
import java.io.IOException;
public class ImageFilterTest {
private static final int REPETITIONS = 5;
public static void main(String[] args) {
ImageFilter filterSequential = new ImageFilter();
ImageFilter filterThreaded = new ImageFilterThreaded();
try {
filterSequential.setImage(new File("./university_of_oldenburg.jpg"));
filterThreaded.setImage(new File("./university_of_oldenburg.jpg"));
} catch (IOException e) {
e.printStackTrace();
return;
}
long start;
long stop;
long time;
start = System.nanoTime();
for (int i = 0; i < REPETITIONS; i++) {
runFilters(filterSequential);
}
stop = System.nanoTime();
time = (stop - start) / 1000000L;
System.out.println("Sequential runtime: " + time + " ms");
start = System.nanoTime();
for (int i = 0; i < REPETITIONS; i++) {
runFilters(filterThreaded);
}
stop = System.nanoTime();
time = (stop - start) / 1000000L;
System.out.println("Threaded runtime: " + time + " ms");
}
private static void runFilters(ImageFilter filter) {
try {
filter.applyFilter(ImageFilter.FILTER_BLUR, new File("./university_of_oldenburg_blur.jpg"));
filter.applyFilter(ImageFilter.FILTER_SHARPEN, new File("./university_of_oldenburg_sharpen.jpg"));
filter.applyFilter(ImageFilter.FILTER_LINES, new File("./university_of_oldenburg_lines.jpg"));
} catch (IOException | InvalidFilterException e) {
e.printStackTrace();
}
}
}

@ -1,7 +0,0 @@
package provided._10._3;
public class InvalidFilterException extends Exception {
private static final long serialVersionUID = 1L;
}

@ -1,76 +0,0 @@
package provided._11._3;
public class Item {
private String name;
private int value;
private int weight;
public Item(String name, int value, int weight) {
super();
this.name = name;
this.value = value;
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
@Override
public String toString() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + value;
result = prime * result + weight;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Item other = (Item) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (value != other.value)
return false;
if (weight != other.weight)
return false;
return true;
}
}

@ -1,67 +0,0 @@
package provided._11._3;
import _11._3.KnapsackDynamic;
import _11._3.KnapsackGreedy;
import _11._3.KnapsackRecursive;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public abstract class Knapsack {
protected List<Item> candidates = new ArrayList<>();
protected int capacity;
public Knapsack(int capacity, Collection<Item> candidates) {
super();
this.capacity = capacity;
this.candidates.addAll(candidates);
}
public int getCapacity() {
return capacity;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
public List<Item> getCandidates() {
return candidates;
}
public abstract Selection pack();
private static final int REPETITIONS = 5;
private static final int CAPACITY = 49;
public static void main(String[] args) {
List<Item> items = new ArrayList<>();
items.add(new Item("Banknote", 100, 1));
items.add(new Item("Goldbar", 1000, 30));
items.add(new Item("Diamond", 750, 5));
test("Recursive", new KnapsackRecursive(CAPACITY, items));
test("Greedy", new KnapsackGreedy(CAPACITY, items));
test("Dynamic Programming", new KnapsackDynamic(CAPACITY, items));
}
private static void test(String title, Knapsack knapsack) {
System.out.print(title);
Selection result = null;
long totalNs = 0;
for (int i = 0; i < REPETITIONS; i++) {
long start = System.nanoTime();
result = knapsack.pack();
long stop = System.nanoTime();
totalNs += stop - start;
System.out.print(".");
}
System.out.println("\n\t" + result);
totalNs /= REPETITIONS;
long totalMs = totalNs / 1000000L;
System.out.println("\tTime required: " + totalNs + " ns (~ " + totalMs + " ms)");
System.out.println();
}
}

@ -1,114 +0,0 @@
package provided._11._3;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Selection {
private Map<Item, Integer> items = new HashMap<>();
private int value;
private int weight;
public Selection() {
super();
}
public Selection(Selection previous) {
super();
items.putAll(previous.items);
value = previous.value;
weight = previous.weight;
}
public Selection(Selection previous, Item item) {
super();
items.putAll(previous.items);
value = previous.value;
weight = previous.weight;
add(item);
}
private void add(Item item) {
items.put(item, getCount(item) + 1);
value += item.getValue();
weight += item.getWeight();
}
public int getCount(Item item) {
Integer result = items.get(item);
if (result == null) {
result = 0;
}
return result;
}
public Collection<Item> getItems() {
return items.keySet();
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
@Override
public String toString() {
StringBuilder b = new StringBuilder();
b.append("Value: ");
b.append(value);
b.append(", weight: ");
b.append(weight);
b.append(", items: ");
List<Item> list = new ArrayList<>(items.keySet());
list.sort((i1, i2) -> i1.getName().compareTo(i2.getName()));
for (int i = 0; i < list.size(); i++) {
b.append(items.get(list.get(i)));
b.append("x ");
b.append(list.get(i).getName());
if (i < list.size() - 1) {
b.append(", ");
}
}
return b.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((items == null) ? 0 : items.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Selection other = (Selection) obj;
if (items == null) {
if (other.items != null)
return false;
} else if (!items.equals(other.items))
return false;
return true;
}
}

@ -1,7 +0,0 @@
package provided._12._1;
public abstract class Fibonacci {
public abstract long calculate(int n);
}

@ -1,10 +0,0 @@
package provided._9;
import _9._3.Observable;
import _9._3.ShipEvent;
public interface Observer {
void update(Observable who, ShipEvent what);
}

@ -1,81 +0,0 @@
package _12._1;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class FibonacciTest {
private static final int[] NUMBERS = new int[] { 3, 5, 8, 12, 9, 18, 15, 10, 7, 11, 20 };
@Test
void test() {
int count = 0;
long start;
long stop;
long time;
start = System.nanoTime();
FibonacciRecursive r = new FibonacciRecursive();
long[] rResult = new long[NUMBERS.length];
for (int i : NUMBERS) {
rResult[count] = r.calculate(i);
count++;
}
stop = System.nanoTime();
time = (stop - start) / 1000000L;
System.out.println("Rekursiv runtime: " + time + " ms");
count = 0;
start = System.nanoTime();
FibonacciParallel p = new FibonacciParallel();
long[] pResult = new long[NUMBERS.length];
for (int i : NUMBERS) {
pResult[count] = p.calculate(i);
count++;
}
stop = System.nanoTime();
time = (stop - start) / 1000000L;
System.out.println("Parallel runtime: " + time + " ms");
count = 0;
start = System.nanoTime();
FibonacciDynamic d = new FibonacciDynamic();
long[] dResult = new long[NUMBERS.length];
for (int i : NUMBERS) {
dResult[count] = d.calculate(i);
count++;
}
stop = System.nanoTime();
time = (stop - start) / 1000000L;
System.out.println("Dynamic runtime: " + time + " ms");
count = 0;
start = System.nanoTime();
FibonacciDynamicParallel dp = new FibonacciDynamicParallel();
long[] dpResult = new long[NUMBERS.length];
for (int i : NUMBERS) {
dpResult[count] = dp.calculate(i);
count++;
}
stop = System.nanoTime();
time = (stop - start) / 1000000L;
System.out.println("Dynamic Parallel runtime: " + time + " ms");
for (int i = 0; i < NUMBERS.length; i++) {
assertEquals(rResult[i], pResult[i]);
assertEquals(rResult[i], dResult[i]);
assertEquals(rResult[i], dpResult[i]);
assertEquals(pResult[i], dResult[i]);
assertEquals(pResult[i], dpResult[i]);
assertEquals(dResult[i], dpResult[i]);
}
}
}

@ -1,59 +0,0 @@
package _12._1.lukas;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import provided._12._1.Fibonacci;
import java.util.Map;
public class FibonacciTest {
private static final Map<Integer, Long> NUMBERS = Map.ofEntries(
Map.entry(3, 2L),
Map.entry(5, 5L),
Map.entry(8, 21L),
Map.entry(12, 144L),
Map.entry(9, 34L),
Map.entry(18, 2584L),
Map.entry(15, 610L),
Map.entry(10, 55L),
Map.entry(7, 13L),
Map.entry(11, 89L),
Map.entry(20, 6765L)
);
@Test
void recursive() {
Fibonacci calculator = new FibonacciRecursive();
NUMBERS.forEach((n, fn) -> Assertions.assertEquals(fn.longValue(), calculator.calculate(n)));
}
@Test
void recursiveParallel() {
Fibonacci calculator = new FibonacciRecursiveParallel();
NUMBERS.forEach((n, fn) -> Assertions.assertEquals(fn.longValue(), calculator.calculate(n)));
}
@Test
void dynamicRecursivePersistent() {
Fibonacci calculator = new FibonacciDynamicRecursivePersistent();
NUMBERS.forEach((n, fn) -> Assertions.assertEquals(fn.longValue(), calculator.calculate(n)));
}
@Test
void dynamicRecursivePersistentParallel() {
Fibonacci calculator = new FibonacciDynamicRecursivePersistentParallel();
NUMBERS.forEach((n, fn) -> Assertions.assertEquals(fn.longValue(), calculator.calculate(n)));
}
@Test
void dynamicIterative() {
Fibonacci calculator = new FibonacciDynamicIterative();
NUMBERS.forEach((n, fn) -> Assertions.assertEquals(fn.longValue(), calculator.calculate(n)));
}
@Test
void doubling() {
Fibonacci calculator = new FibonacciDoubling();
NUMBERS.forEach((n, fn) -> Assertions.assertEquals(fn.longValue(), calculator.calculate(n)));
}
}
Loading…
Cancel
Save