diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..919ce1f --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/sbt.xml similarity index 100% rename from .idea/misc.xml rename to .idea/sbt.xml diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 3d5b769..242fd62 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -3,11 +3,70 @@ - { - "keyToString": { - "project.structure.last.edited": "Project", - "project.structure.proportion": "0.0", - "project.structure.side.proportion": "0.0" + + + + + + + + + + + + +}]]> + + + + + + + + + + + + + + + + + + + + + 1742140697920 + + + \ No newline at end of file diff --git a/H06/src/main/java/h06/Main.java b/H06/src/main/java/h06/Main.java index 19d82ec..c3d2745 100644 --- a/H06/src/main/java/h06/Main.java +++ b/H06/src/main/java/h06/Main.java @@ -1,5 +1,9 @@ package h06; +import h06.problems.Fractals; +import h06.ui.FractalDrawer; +import h06.ui.FractalVisualizer; + /** * Main entry point in executing the program. */ @@ -10,6 +14,7 @@ public class Main { * @param args program arguments, currently ignored */ public static void main(String[] args) { - + var inst = Fractals.kochSnowflake(3); + new FractalVisualizer(inst, 60).setVisible(true); } } diff --git a/H06/src/main/java/h06/problems/Fibonacci.java b/H06/src/main/java/h06/problems/Fibonacci.java index 744382f..6fac538 100644 --- a/H06/src/main/java/h06/problems/Fibonacci.java +++ b/H06/src/main/java/h06/problems/Fibonacci.java @@ -41,12 +41,12 @@ public class Fibonacci { */ @StudentImplementationRequired public static int fibonacciRecursiveDifferent(int n) { - return crash(); // TODO: H1.1 - remove if implemented + return doTheRecursion(0, 1, n); } @StudentImplementationRequired private static int doTheRecursion(int a, int b, int n) { - return crash(); // TODO: H1.1 - remove if implemented + return n <= 0 ? a : doTheRecursion(b, a+b, n-1); } /** @@ -57,6 +57,15 @@ public class Fibonacci { */ @StudentImplementationRequired public static int fibonacciIterative(int n) { - return crash(); // TODO: H1.2 - remove if implemented + var a = 0; + var b = 1; + + for (int i = 0; i < n; i++) { + var t = a+b; + a = b; + b = t; + } + + return a; } } diff --git a/H06/src/main/java/h06/problems/Fractals.java b/H06/src/main/java/h06/problems/Fractals.java index 3c401bd..76b696f 100644 --- a/H06/src/main/java/h06/problems/Fractals.java +++ b/H06/src/main/java/h06/problems/Fractals.java @@ -4,6 +4,14 @@ import h06.ui.DrawInstruction; import org.tudalgo.algoutils.student.annotation.DoNotTouch; import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + import static org.tudalgo.algoutils.student.Student.crash; /** @@ -29,7 +37,7 @@ public class Fractals { */ @StudentImplementationRequired public static int pow(int a, int b) { - return crash(); // TODO: H3.1 - remove if implemented + return (int) Math.pow(a, b); } /** @@ -42,7 +50,9 @@ public class Fractals { */ @StudentImplementationRequired public static DrawInstruction[] concatenate(DrawInstruction[] arr1, DrawInstruction[] arr2) { - return crash(); // TODO: H3.2 - remove if implemented + do { + return Stream.of(arr1, arr2).flatMap(Stream::of).toArray(DrawInstruction[]::new); // TODO: H3.2 - remove if implemented + } while(false); } /** @@ -56,7 +66,29 @@ public class Fractals { */ @StudentImplementationRequired public static DrawInstruction[] replaceAtIndex(DrawInstruction[] arr, int idx, DrawInstruction elem) { - return crash(); // TODO: H3.3 - remove if implemented + do { + List x = new ArrayList<>(List.of(arr)); + x.set(idx, elem); + return x.toArray(DrawInstruction[]::new); + } while (true); + } + + static String fracToString(DrawInstruction[] frac) { + return Stream.of(frac).map(String::valueOf).collect(Collectors.joining()); + } + + static DrawInstruction[] stringToFrac(String string) { + return string.chars() + .mapToObj(c -> (char) c) + .map(String::valueOf) + .map(x -> switch (x) { + case "D": yield DrawInstruction.DRAW_LINE; + case "R": yield DrawInstruction.TURN_RIGHT; + case "L": yield DrawInstruction.TURN_LEFT; + default: + throw new IllegalStateException("Unexpected value: " + x); + }) + .toArray(DrawInstruction[]::new); } /** @@ -67,7 +99,25 @@ public class Fractals { */ @StudentImplementationRequired public static DrawInstruction[] dragonCurve(int n) { - return crash(); // TODO: H3.4 - remove if implemented + return stringToFrac(dragonCurveString(n)); + } + public static String dragonCurveString(int n) { + if (n < 0) return "D"; + + return switch (n) { + case 0: yield "D"; + case 1: yield "DRD"; + default: yield ((dragonCurveString(n-1) + "R") + stringReplace(dragonCurveString(n-1), pow(2, n-1)-1, "L")); + }; + } + + static String stringReplace(String a, int n, String b) { + return a.substring(0, n) + b + a.substring(n+1); + } + + + public static List replaceAll(List list, A a, List newThings) { + return list.stream().flatMap(x -> a.equals(x) ? newThings.stream() : Stream.of(x)).toList(); } /** @@ -78,6 +128,17 @@ public class Fractals { */ @StudentImplementationRequired public static DrawInstruction[] kochSnowflake(int n) { - return crash(); // TODO: H3.5 - remove if implemented + return stringToFrac(kockSnowflakeString(n)); } + + public static String kockSnowflakeString(int n) { + if (n < 0) return "DRRDRRD"; + + return switch (n) { + case 0: yield "DRRDRRD"; + default: yield kockSnowflakeString(n-1).replaceAll("D", "DLDRRDLD"); + }; + } + + } diff --git a/H06/src/main/java/h06/problems/LinearSearch.java b/H06/src/main/java/h06/problems/LinearSearch.java index 90c3a64..d63a454 100644 --- a/H06/src/main/java/h06/problems/LinearSearch.java +++ b/H06/src/main/java/h06/problems/LinearSearch.java @@ -2,6 +2,8 @@ package h06.problems; import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; +import java.util.stream.IntStream; + import static org.tudalgo.algoutils.student.Student.crash; public class LinearSearch { @@ -15,7 +17,11 @@ public class LinearSearch { */ @StudentImplementationRequired public static int linearSearchRecursive(int[] arr, int target) { - return crash(); // TODO: H2.1 - remove if implemented + linearSearchRecursiveHelper(arr, target, 0); + return IntStream.range(0, arr.length) + .filter(i -> arr[i] == target) + .findFirst() + .orElse(-1); } /** @@ -28,7 +34,7 @@ public class LinearSearch { */ @StudentImplementationRequired public static int linearSearchRecursiveHelper(int[] arr, int target, int index) { - return crash(); // TODO: H2.1 - remove if implemented + return index >= arr.length ? -1 : (arr[index] == target ? index : linearSearchRecursiveHelper(arr, target, index+1)); // TODO: H2.1 - remove if implemented } /** @@ -40,6 +46,16 @@ public class LinearSearch { */ @StudentImplementationRequired public static int linearSearchIterative(int[] arr, int target) { - return crash(); // TODO: H2.2 - remove if implemented + for (int i = 0; i < arr.length; i++) { + scope : { + if (arr[i] == target) { + break scope; + } + continue; + } + return i; + } + + return -1; } } diff --git a/H07/src/main/java/h07/ArithmeticExpression.java b/H07/src/main/java/h07/ArithmeticExpression.java new file mode 100644 index 0000000..9af4d68 --- /dev/null +++ b/H07/src/main/java/h07/ArithmeticExpression.java @@ -0,0 +1,6 @@ +package h07; + +public interface ArithmeticExpression { + + NumberExpression evaluate(NumberExpression lhs, NumberExpression rhs); +} diff --git a/H07/src/main/java/h07/ConvertNumberToPeanoExpression.java b/H07/src/main/java/h07/ConvertNumberToPeanoExpression.java new file mode 100644 index 0000000..9f1dd24 --- /dev/null +++ b/H07/src/main/java/h07/ConvertNumberToPeanoExpression.java @@ -0,0 +1,8 @@ +package h07; + +import h07.peano.PeanoNumberExpression; + +public interface ConvertNumberToPeanoExpression { + + PeanoNumberExpression convert(NumberExpression e); +} diff --git a/H07/src/main/java/h07/ConvertNumberToPeanoExpressionImpl.java b/H07/src/main/java/h07/ConvertNumberToPeanoExpressionImpl.java new file mode 100644 index 0000000..76e95cc --- /dev/null +++ b/H07/src/main/java/h07/ConvertNumberToPeanoExpressionImpl.java @@ -0,0 +1,22 @@ +package h07; + +import h07.peano.PeanoNumberExpression; +import h07.peano.Successor; +import h07.peano.Zero; + +public class ConvertNumberToPeanoExpressionImpl implements ConvertNumberToPeanoExpression { + + + @Override + public PeanoNumberExpression convert(NumberExpression e) { + var x = e.evaluate(); + if (x == 0) { + return () -> { + return new Zero(); + }; + } + return () -> { + return new Successor(convert(() -> x-1).evaluate()); + }; + } +} diff --git a/H07/src/main/java/h07/ConvertPeanoToNumberExpression.java b/H07/src/main/java/h07/ConvertPeanoToNumberExpression.java new file mode 100644 index 0000000..ed779df --- /dev/null +++ b/H07/src/main/java/h07/ConvertPeanoToNumberExpression.java @@ -0,0 +1,8 @@ +package h07; + +import h07.peano.PeanoNumberExpression; + +public interface ConvertPeanoToNumberExpression { + + NumberExpression convert(PeanoNumberExpression e); +} diff --git a/H07/src/main/java/h07/ConvertPeanoToNumberExpressionImpl.java b/H07/src/main/java/h07/ConvertPeanoToNumberExpressionImpl.java new file mode 100644 index 0000000..6289882 --- /dev/null +++ b/H07/src/main/java/h07/ConvertPeanoToNumberExpressionImpl.java @@ -0,0 +1,22 @@ +package h07; + +import h07.peano.PeanoNumberExpression; +import h07.peano.Successor; + +public class ConvertPeanoToNumberExpressionImpl implements ConvertPeanoToNumberExpression { + + @Override + public NumberExpression convert(PeanoNumberExpression e) { + var x = e.evaluate(); + + if (x instanceof Successor s) { + return () -> { + return 1 + convert(() -> s.predecessor).evaluate(); + }; + } + + return () -> { + return 0; + }; + } +} diff --git a/H07/src/main/java/h07/Main.java b/H07/src/main/java/h07/Main.java index 4a57760..c50acc3 100644 --- a/H07/src/main/java/h07/Main.java +++ b/H07/src/main/java/h07/Main.java @@ -1,14 +1,9 @@ package h07; +import h07.peano.*; import org.tudalgo.algoutils.student.annotation.DoNotTouch; import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; -import h07.peano.NaturalNumber; -import h07.peano.Successor; -import h07.peano.Zero; - -import static org.tudalgo.algoutils.student.Student.crash; - /** * Main entry point in executing the program. */ @@ -39,16 +34,16 @@ public class Main { @DoNotTouch private static void numberExpressionMultiplicationTableTests() { // TODO: H2.2 - uncomment to test -// int lowerBound = 1; -// int upperBound = 10; -// NumberExpression[] multiplicationTable = NumberExpressionFactory.multiplicationTable(lowerBound, upperBound); -// -// for (int i = lowerBound; i <= upperBound; i++) { -// for (int j = lowerBound; j <= upperBound; j++) { -// System.out.printf("| %4s ", multiplicationTable[(i - lowerBound) * (upperBound - lowerBound + 1) + (j - lowerBound)].evaluate()); -// } -// System.out.println("|"); -// } + int lowerBound = 1; + int upperBound = 10; + NumberExpression[] multiplicationTable = NumberExpressionFactory.multiplicationTable(lowerBound, upperBound); + + for (int i = lowerBound; i <= upperBound; i++) { + for (int j = lowerBound; j <= upperBound; j++) { + System.out.printf("| %4s ", multiplicationTable[(i - lowerBound) * (upperBound - lowerBound + 1) + (j - lowerBound)].evaluate()); + } + System.out.println("|"); + } } private static final NaturalNumber THREE = new Successor(new Successor(new Successor(new Zero()))); @@ -56,11 +51,36 @@ public class Main { @StudentImplementationRequired private static void peanoNumberExpressionTests() { - crash(); // TODO: H3.3 - remove if implemented + var ten = new PeanoAddExpression().evaluate(() -> { + return THREE; + }, () -> { + return SEVEN; + }).evaluate(); + System.out.println(ten); + + var _21 = new PeanoMultiplyExpression().evaluate(() -> { + return THREE; + }, () -> { + return SEVEN; + }).evaluate(); + System.out.println(_21); } @StudentImplementationRequired private static void filterFoldMapTests() { - crash(); // TODO: H4.6 - remove if implemented + int lowerBound = 1; + int upperBound = 10; + var timesTable = NumberExpressionFactory.multiplicationTable(lowerBound, upperBound); + + var filtered = NumberExpressionFactory.filter(timesTable, x -> { + return x % 3 == 0; + }); + var peano = PeanoNumberExpressionFactory.fromNumberExpressions(filtered); + var sum = PeanoNumberExpressionFactory.fold(peano, () -> { + return new Zero(); + }, (e1, e2) -> { + return new PeanoAddExpression().evaluate(e1, e2); + }); + System.out.println(new ConvertPeanoToNumberExpressionImpl().convert(sum).evaluate()); } } diff --git a/H07/src/main/java/h07/NumberExpression.java b/H07/src/main/java/h07/NumberExpression.java new file mode 100644 index 0000000..e9aed60 --- /dev/null +++ b/H07/src/main/java/h07/NumberExpression.java @@ -0,0 +1,6 @@ +package h07; + +public interface NumberExpression { + + int evaluate(); +} diff --git a/H07/src/main/java/h07/NumberExpressionFactory.java b/H07/src/main/java/h07/NumberExpressionFactory.java index f2bb270..a729ae4 100644 --- a/H07/src/main/java/h07/NumberExpressionFactory.java +++ b/H07/src/main/java/h07/NumberExpressionFactory.java @@ -1,12 +1,11 @@ package h07; +import java.util.Arrays; import java.util.function.IntPredicate; import org.tudalgo.algoutils.student.annotation.DoNotTouch; import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; -import static org.tudalgo.algoutils.student.Student.crash; - /** * A factory class for creating number expressions. */ @@ -18,10 +17,14 @@ public class NumberExpressionFactory { * @return An array of number expressions representing the result of the * multiplication table of the given numbers. */ -// @StudentImplementationRequired -// public static NumberExpression[] multiplicationTable(NumberExpression[] numbers) { -// return crash(); // TODO: H2.1 - remove if implemented -// } + @StudentImplementationRequired + public static NumberExpression[] multiplicationTable(NumberExpression[] numbers) { + return Arrays.stream(numbers) + .flatMap(e1 -> Arrays.stream(numbers).map(e2 -> { + return () -> e1.evaluate() * e2.evaluate(); + })) + .toArray(NumberExpression[]::new); + } // TODO: H2.2 - uncomment for testing @@ -33,20 +36,20 @@ public class NumberExpressionFactory { * @return An array of number expressions representing the result of the * multiplication table of the numbers from lowerBound to upperBound. */ -// @DoNotTouch -// public static NumberExpression[] multiplicationTable(int lowerBound, int upperBound) { -// int numberOfNumbers = upperBound - lowerBound + 1; -// NumberExpression[] baseNumbers = new NumberExpression[numberOfNumbers]; -// -// for (int i = lowerBound; i <= upperBound; i++) { -// // Copy to local variable to make it effectively final, so it can be used in -// // lambda -// int finalI = i; -// baseNumbers[i - lowerBound] = () -> finalI; -// } -// -// return multiplicationTable(baseNumbers); -// } + @DoNotTouch + public static NumberExpression[] multiplicationTable(int lowerBound, int upperBound) { + int numberOfNumbers = upperBound - lowerBound + 1; + NumberExpression[] baseNumbers = new NumberExpression[numberOfNumbers]; + + for (int i = lowerBound; i <= upperBound; i++) { + // Copy to local variable to make it effectively final, so it can be used in + // lambda + int finalI = i; + baseNumbers[i - lowerBound] = () -> finalI; + } + + return multiplicationTable(baseNumbers); + } /** * Filters the given array of number expressions based on the given predicate. @@ -58,8 +61,10 @@ public class NumberExpressionFactory { * @param predicate the predicate to filter the number expressions * @return An array of number expressions that satisfy the predicate. */ -// @StudentImplementationRequired -// public static NumberExpression[] filter(NumberExpression[] numbers, IntPredicate predicate) { -// return crash(); // TODO: H4.4 - remove if implemented -// } + @StudentImplementationRequired + public static NumberExpression[] filter(NumberExpression[] numbers, IntPredicate predicate) { + return Arrays.stream(numbers) + .filter(e -> predicate.test(e.evaluate())) + .toArray(NumberExpression[]::new); + } } diff --git a/H07/src/main/java/h07/peano/PeanoAddExpression.java b/H07/src/main/java/h07/peano/PeanoAddExpression.java new file mode 100644 index 0000000..9826229 --- /dev/null +++ b/H07/src/main/java/h07/peano/PeanoAddExpression.java @@ -0,0 +1,20 @@ +package h07.peano; + +public class PeanoAddExpression implements PeanoArithmeticExpression { + + @Override + public PeanoNumberExpression evaluate(PeanoNumberExpression a, PeanoNumberExpression b) { + if (b.evaluate() instanceof Successor s) { + return () -> { + return new Successor(evaluate(() -> { + return a.evaluate(); + }, () -> { + return s.predecessor; + }).evaluate()); + }; + } + return () -> { + return a.evaluate(); + }; + } +} diff --git a/H07/src/main/java/h07/peano/PeanoArithmeticExpression.java b/H07/src/main/java/h07/peano/PeanoArithmeticExpression.java new file mode 100644 index 0000000..25db485 --- /dev/null +++ b/H07/src/main/java/h07/peano/PeanoArithmeticExpression.java @@ -0,0 +1,6 @@ +package h07.peano; + +public interface PeanoArithmeticExpression { + + PeanoNumberExpression evaluate(PeanoNumberExpression a, PeanoNumberExpression b); +} diff --git a/H07/src/main/java/h07/peano/PeanoMultiplyExpression.java b/H07/src/main/java/h07/peano/PeanoMultiplyExpression.java new file mode 100644 index 0000000..83c6504 --- /dev/null +++ b/H07/src/main/java/h07/peano/PeanoMultiplyExpression.java @@ -0,0 +1,12 @@ +package h07.peano; + +public class PeanoMultiplyExpression implements PeanoArithmeticExpression { + + @Override + public PeanoNumberExpression evaluate(PeanoNumberExpression a, PeanoNumberExpression b) { + if (b.evaluate() instanceof Successor s) { + return () -> new PeanoAddExpression().evaluate(a, evaluate(a, () -> s.predecessor)).evaluate(); + } + return Zero::new; + } +} diff --git a/H07/src/main/java/h07/peano/PeanoNumberExpression.java b/H07/src/main/java/h07/peano/PeanoNumberExpression.java new file mode 100644 index 0000000..1bba396 --- /dev/null +++ b/H07/src/main/java/h07/peano/PeanoNumberExpression.java @@ -0,0 +1,6 @@ +package h07.peano; + +public interface PeanoNumberExpression { + + NaturalNumber evaluate(); +} diff --git a/H07/src/main/java/h07/peano/PeanoNumberExpressionFactory.java b/H07/src/main/java/h07/peano/PeanoNumberExpressionFactory.java index 753da6f..05b46ba 100644 --- a/H07/src/main/java/h07/peano/PeanoNumberExpressionFactory.java +++ b/H07/src/main/java/h07/peano/PeanoNumberExpressionFactory.java @@ -1,9 +1,11 @@ package h07.peano; +import h07.ConvertNumberToPeanoExpressionImpl; +import h07.NumberExpression; import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; -import static org.tudalgo.algoutils.student.Student.crash; +import java.util.Arrays; /** * Represents a factory for Peano number expressions. @@ -15,10 +17,14 @@ public class PeanoNumberExpressionFactory { * @param numberExpressions the number expressions to convert * @return the converted Peano number expressions */ -// @StudentImplementationRequired -// public static PeanoNumberExpression[] fromNumberExpressions(NumberExpression[] numberExpressions) { -// return crash(); // TODO: H4.3 - remove if implemented -// } + @StudentImplementationRequired + public static PeanoNumberExpression[] fromNumberExpressions(NumberExpression[] numberExpressions) { + return Arrays.stream(numberExpressions) + .map(e -> { + return new ConvertNumberToPeanoExpressionImpl().convert(e); + }) + .toArray(PeanoNumberExpression[]::new); + } /** * Folds an array of Peano number expressions into a single Peano number expression. @@ -28,8 +34,11 @@ public class PeanoNumberExpressionFactory { * @param operation the operation to apply * @return the folded Peano number expression */ -// @StudentImplementationRequired -// public static PeanoNumberExpression fold(PeanoNumberExpression[] peanoNumberExpressions, PeanoNumberExpression initial, PeanoArithmeticExpression operation) { -// return crash(); // TODO: H4.5 - remove if implemented -// } + @StudentImplementationRequired + public static PeanoNumberExpression fold(PeanoNumberExpression[] peanoNumberExpressions, PeanoNumberExpression initial, PeanoArithmeticExpression operation) { + return Arrays.stream(peanoNumberExpressions) + .reduce(initial, (e1, e2) -> { + return operation.evaluate(e1, e2); + }); + } } diff --git a/H08/src/main/java/h08/Airport.java b/H08/src/main/java/h08/Airport.java index e182039..27068e8 100644 --- a/H08/src/main/java/h08/Airport.java +++ b/H08/src/main/java/h08/Airport.java @@ -1,6 +1,8 @@ package h08; +import h08.Exceptions.FlightNotFoundException; + import java.util.Arrays; /** @@ -56,7 +58,35 @@ public class Airport { */ public void addFlight(Flight flight, boolean isDeparting) { //TODO H8.4.1 - org.tudalgo.algoutils.student.Student.crash("H8.4.1 - Remove if implemented"); + if (isDeparting) { + addDeparture(flight); + } else { + addArrival(flight); + } + } + + public void addDeparture(Flight flight) { + if (!flight.getDeparture().equals(airportCode)) { + throw new IllegalArgumentException("Flight's departure airport code does not match this airport's code"); + } + + if (departingFlights.length >= departingSize) { + departingFlights = Arrays.copyOf(departingFlights, departingSize*2); + } + + departingFlights[departingSize++] = flight; + } + + public void addArrival(Flight flight) { + if (!flight.getDestination().equals(airportCode)) { + throw new IllegalArgumentException("Flight's arrival airport code does not match this airport's code"); + } + + if (arrivingFlights.length >= arrivingSize) { + arrivingFlights = Arrays.copyOf(arrivingFlights, arrivingSize*2); + } + + arrivingFlights[arrivingSize++] = flight; } /** @@ -66,9 +96,54 @@ public class Airport { * @param isDeparting if true, removes from departing flights, otherwise from arriving flights * @throws FlightNotFoundException if the flight is not found */ - public void removeFlight(String flightNumber, boolean isDeparting) { + public void removeFlight(String flightNumber, boolean isDeparting) throws FlightNotFoundException { //TODO H8.4.2 - org.tudalgo.algoutils.student.Student.crash("H8.4.2 - Remove if implemented"); + if (isDeparting) { + removeDeparture(flightNumber); + } else { + removeArrival(flightNumber); + } + } + + public void removeArrival(String flightNumber) throws FlightNotFoundException { + if (removeFlight(arrivingSize, arrivingFlights, flightNumber)) { + arrivingSize--; + return; + }; + + throw new FlightNotFoundException("Arriving flight not found: " + flightNumber); + } + + public void removeDeparture(String flightNumber) throws FlightNotFoundException { + if (removeFlight(departingSize, departingFlights, flightNumber)) { + departingSize--; + return; + } + + throw new FlightNotFoundException("Departing flight not found: " + flightNumber); + } + + private boolean removeFlight(int size, Flight[] flights, String flightNumber) { + int index = 0; + boolean found = false; + + for (; index < size; index++) { + if (flights[index].getFlightNumber().equals(flightNumber)) { + found = true; + break; + } + } + + System.out.println(index); + + if (found) { + for (int i = index; i < size - 1; i++) { + flights[i] = flights[i + 1]; + } + + flights[size-1] = null; + } + return found; } /** @@ -79,11 +154,34 @@ public class Airport { * @return the flight with the specified flight number * @throws FlightNotFoundException if the flight is not found */ - public Flight getFlight(String flightNumber, boolean isDeparting) { + public Flight getFlight(String flightNumber, boolean isDeparting) throws FlightNotFoundException { //TODO H8.4.3 - return org.tudalgo.algoutils.student.Student.crash("H8.4.3 - Remove if implemented"); + if (isDeparting) { + return getDeparture(flightNumber); + } else { + return getArrival(flightNumber); + } } + private Flight getArrival(String flightNumber) throws FlightNotFoundException { + for (int i = 0; i < arrivingSize; i++) { + if (arrivingFlights[i].getFlightNumber().equals(flightNumber)) { + return arrivingFlights[i]; + } + } + + throw new FlightNotFoundException("Arriving flight not found: " + flightNumber); + } + + private Flight getDeparture(String flightNumber) throws FlightNotFoundException { + for (int i = 0; i < departingSize; i++) { + if (departingFlights[i].getFlightNumber().equals(flightNumber)) { + return departingFlights[i]; + } + } + + throw new FlightNotFoundException("Departing flight not found: " + flightNumber); + } /** * Returns the departing flights of the airport. diff --git a/H08/src/main/java/h08/Booking.java b/H08/src/main/java/h08/Booking.java index 8838392..4a7e0e9 100644 --- a/H08/src/main/java/h08/Booking.java +++ b/H08/src/main/java/h08/Booking.java @@ -1,5 +1,7 @@ package h08; +import h08.Exceptions.BookingAlreadyCancelledException; + /** * Represents a flight booking. A booking allows the reservation of a flight as long as managing its identification and its relevant information. */ @@ -80,9 +82,13 @@ public class Booking { * * @throws BookingAlreadyCancelledException if the booking is already cancelled */ - public void cancelBooking() { + public void cancelBooking() throws BookingAlreadyCancelledException { //TODO H8.4.4 - org.tudalgo.algoutils.student.Student.crash("H8.4.4 - Remove if implemented"); + if (isCancelled) { + throw new BookingAlreadyCancelledException("Booking is already cancelled: " + bookingId); + } + + isCancelled = true; } /** diff --git a/H08/src/main/java/h08/BookingManagement.java b/H08/src/main/java/h08/BookingManagement.java index fed0b6e..0d6224d 100644 --- a/H08/src/main/java/h08/BookingManagement.java +++ b/H08/src/main/java/h08/BookingManagement.java @@ -1,5 +1,9 @@ package h08; +import h08.Exceptions.*; + +import java.util.Arrays; + /** * Represents a booking management. A booking management oversees booking operations, ensuring validity and handling duplicates. */ @@ -39,9 +43,26 @@ public class BookingManagement { * @param flightNumber the flight number of the booking * @param passengerId the passenger ID of the booking */ - public void createBooking(String bookingId, String flightNumber, String passengerId) { + public void createBooking(String bookingId, String flightNumber, String passengerId) throws InvalidBookingException { //TODO H8.5.5 - org.tudalgo.algoutils.student.Student.crash("H8.5.5 - Remove if implemented"); + try { + validateAndCheckBooking(bookingId, flightNumber, passengerId); + + var flight = flightManagement.getFlight(flightNumber); + flight.bookSeat(); + + if (bookings.length <= size) { + bookings = Arrays.copyOf(bookings, size*2); + } + + bookings[size++] = new Booking(bookingId, flightNumber, passengerId); + + } catch (NoSeatsAvailableException ignored) { + } catch (DuplicateBookingException e) { + System.out.println("Booking already exists: " + bookingId); + } catch (InvalidBookingException e) { + System.out.println("Invalid booking details: " + e.getMessage()); + } } /** @@ -53,9 +74,17 @@ public class BookingManagement { * @throws InvalidBookingException if the booking details are invalid * @throws DuplicateBookingException if the booking ID is already in use */ - private void validateAndCheckBooking(String bookingId, String flightNumber, String passengerId){ + private void validateAndCheckBooking(String bookingId, String flightNumber, String passengerId) throws InvalidBookingException { //TODO H8.5.2 - org.tudalgo.algoutils.student.Student.crash("H8.5.2 - Remove if implemented"); + if (bookingId == null || flightNumber == null || passengerId == null || bookingId.isEmpty() || flightNumber.isEmpty() || passengerId.isEmpty()) { + throw new InvalidBookingException("Invalid booking details provided."); + } + + try { + searchBooking(bookingId); + throw new DuplicateBookingException("A booking with this ID already exists."); + } catch (BookingNotFoundException ignored) { + } } /** @@ -65,9 +94,15 @@ public class BookingManagement { * @return the booking with the specified booking ID * @throws BookingNotFoundException if the booking ist not found */ - private Booking searchBooking(String bookingId){ + private Booking searchBooking(String bookingId) throws BookingNotFoundException { //TODO H8.5.3 - return org.tudalgo.algoutils.student.Student.crash("H8.5.3 - Remove if implemented"); + for (int i = 0; i < size; i++) { + if (bookings[i].getBookingId().equals(bookingId)) { + return bookings[i]; + } + } + + throw new BookingNotFoundException("Booking not found: " + bookingId); } /** @@ -78,7 +113,12 @@ public class BookingManagement { */ public Booking getBooking(String bookingId) { //TODO H8.5.3 - return org.tudalgo.algoutils.student.Student.crash("H8.5.3 - Remove if implemented"); + try { + return searchBooking(bookingId); + } catch (BookingNotFoundException e) { + System.out.println("Error retrieving booking: " + e.getMessage()); + return null; + } } /** @@ -88,6 +128,13 @@ public class BookingManagement { */ public void cancelBooking(String bookingId) { //TODO H8.5.4 - org.tudalgo.algoutils.student.Student.crash("H8.5.4 - Remove if implemented"); + try { + searchBooking(bookingId).cancelBooking(); + System.out.println("Booking cancelled successfully: " + bookingId); + } catch (BookingAlreadyCancelledException e) { + System.out.println("Already cancelled booking: " + bookingId); + } catch (BookingNotFoundException e) { + System.out.println("Error cancelling booking: " + e.getMessage()); + } } } diff --git a/H08/src/main/java/h08/Exceptions/BookingAlreadyCancelledException.java b/H08/src/main/java/h08/Exceptions/BookingAlreadyCancelledException.java new file mode 100644 index 0000000..5bd15af --- /dev/null +++ b/H08/src/main/java/h08/Exceptions/BookingAlreadyCancelledException.java @@ -0,0 +1,8 @@ +package h08.Exceptions; + +public class BookingAlreadyCancelledException extends FlightNotFoundException { + + public BookingAlreadyCancelledException(String message) { + super(message); + } +} diff --git a/H08/src/main/java/h08/Exceptions/BookingManagementException.java b/H08/src/main/java/h08/Exceptions/BookingManagementException.java new file mode 100644 index 0000000..93a4f74 --- /dev/null +++ b/H08/src/main/java/h08/Exceptions/BookingManagementException.java @@ -0,0 +1,8 @@ +package h08.Exceptions; + +public class BookingManagementException extends Exception { + + public BookingManagementException(String message) { + super(message); + } +} diff --git a/H08/src/main/java/h08/Exceptions/BookingNotFoundException.java b/H08/src/main/java/h08/Exceptions/BookingNotFoundException.java new file mode 100644 index 0000000..7f4cb1e --- /dev/null +++ b/H08/src/main/java/h08/Exceptions/BookingNotFoundException.java @@ -0,0 +1,9 @@ +package h08.Exceptions; + +public class BookingNotFoundException extends BookingManagementException { + + + public BookingNotFoundException(String message) { + super(message); + } +} diff --git a/H08/src/main/java/h08/Exceptions/DuplicateBookingException.java b/H08/src/main/java/h08/Exceptions/DuplicateBookingException.java new file mode 100644 index 0000000..be676bb --- /dev/null +++ b/H08/src/main/java/h08/Exceptions/DuplicateBookingException.java @@ -0,0 +1,9 @@ +package h08.Exceptions; + +public class DuplicateBookingException extends InvalidBookingException { + + + public DuplicateBookingException(String message) { + super(message); + } +} diff --git a/H08/src/main/java/h08/Exceptions/FlightManagementException.java b/H08/src/main/java/h08/Exceptions/FlightManagementException.java new file mode 100644 index 0000000..d70156c --- /dev/null +++ b/H08/src/main/java/h08/Exceptions/FlightManagementException.java @@ -0,0 +1,8 @@ +package h08.Exceptions; + +public class FlightManagementException extends Exception { + + public FlightManagementException(String message) { + super(message); + } +} diff --git a/H08/src/main/java/h08/Exceptions/FlightNotFoundException.java b/H08/src/main/java/h08/Exceptions/FlightNotFoundException.java new file mode 100644 index 0000000..d8b2565 --- /dev/null +++ b/H08/src/main/java/h08/Exceptions/FlightNotFoundException.java @@ -0,0 +1,9 @@ +package h08.Exceptions; + +public class FlightNotFoundException extends FlightManagementException { + + + public FlightNotFoundException(String message) { + super(message); + } +} diff --git a/H08/src/main/java/h08/Exceptions/InvalidBookingException.java b/H08/src/main/java/h08/Exceptions/InvalidBookingException.java new file mode 100644 index 0000000..9aea9b0 --- /dev/null +++ b/H08/src/main/java/h08/Exceptions/InvalidBookingException.java @@ -0,0 +1,9 @@ +package h08.Exceptions; + +public class InvalidBookingException extends BookingManagementException { + + + public InvalidBookingException(String message) { + super(message); + } +} diff --git a/H08/src/main/java/h08/Exceptions/NoSeatsAvailableException.java b/H08/src/main/java/h08/Exceptions/NoSeatsAvailableException.java new file mode 100644 index 0000000..85ae0c6 --- /dev/null +++ b/H08/src/main/java/h08/Exceptions/NoSeatsAvailableException.java @@ -0,0 +1,8 @@ +package h08.Exceptions; + +public class NoSeatsAvailableException extends Exception { + + public NoSeatsAvailableException(String flightNumber) { + super("No seats available for flight: " + flightNumber); + } +} diff --git a/H08/src/main/java/h08/Flight.java b/H08/src/main/java/h08/Flight.java index 18e033e..21419d5 100644 --- a/H08/src/main/java/h08/Flight.java +++ b/H08/src/main/java/h08/Flight.java @@ -1,8 +1,11 @@ package h08; +import h08.Exceptions.NoSeatsAvailableException; import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; import java.time.LocalDateTime; +import java.util.Objects; +import java.util.regex.Pattern; /** * Represents a flight. A flight offers information such as the flight details and seat management. @@ -50,10 +53,17 @@ public class Flight { */ public Flight(String flightNumber, String departure, String destination, LocalDateTime departureTime, int initialSeats) { //TODO H8.2.1 + assert null != flightNumber; + assert null != departure; + assert null != destination; + assert null != departureTime; + assert initialSeats >= 0; + validateFlightNumber(flightNumber); + this.flightNumber = flightNumber; - this.departure = departure; - this.destination = destination; - this.departureTime = departureTime; + this.departure = Objects.requireNonNull(departure); + this.destination = Objects.requireNonNull(destination); + this.departureTime = Objects.requireNonNull(departureTime); this.initialSeats = initialSeats; this.availableSeats = initialSeats; @@ -67,7 +77,7 @@ public class Flight { @StudentImplementationRequired("H8.2.1") public void validateFlightNumber(String flightNumber) { //TODO H8.2.1 - org.tudalgo.algoutils.student.Student.crash("H8.2.1 - Remove if implemented"); + assert flightNumber.matches("^[A-Z]{2}\\d{3,4}$"); } /** @@ -116,9 +126,13 @@ public class Flight { } @StudentImplementationRequired("H8.2.2") - public void bookSeat() { + public void bookSeat() throws NoSeatsAvailableException { //TODO H8.2.2 - org.tudalgo.algoutils.student.Student.crash("H8.2.2 - Remove if implemented"); + if (availableSeats == 0) { + throw new NoSeatsAvailableException(flightNumber); + } + + availableSeats--; } public void cancelSeat() { diff --git a/H08/src/main/java/h08/FlightManagement.java b/H08/src/main/java/h08/FlightManagement.java index e3f6e3e..53ac21d 100644 --- a/H08/src/main/java/h08/FlightManagement.java +++ b/H08/src/main/java/h08/FlightManagement.java @@ -1,5 +1,7 @@ package h08; +import h08.Exceptions.FlightNotFoundException; + import java.util.Arrays; /** @@ -46,9 +48,28 @@ public class FlightManagement { * @param flight the flight to be added or removed * @param isAddOperation if true, the flight will be added; if false, the flight will be removed */ - public void manageFlight(String airportCode, Flight flight, boolean isAddOperation) { + public void manageFlight(String airportCode, Flight flight, boolean isAddOperation) throws Exception { //TODO H8.5.2 - org.tudalgo.algoutils.student.Student.crash("H8.5.2 - Remove if implemented"); + var airport = searchAirport(airportCode); + airport.getAirportCode(); + + if (isAddOperation) { + try { + airport.addFlight(flight, true); + } catch (Exception e) { + airport.addFlight(flight, false); + } + } else { + try { + airport.removeDeparture(flight.getFlightNumber()); + } catch (Exception e) { + try { + airport.removeArrival(flight.getFlightNumber()); + } catch (FlightNotFoundException ficken) { + System.out.println("Error removing flight: " + ficken.getMessage()); + } + } + } } /** @@ -87,9 +108,15 @@ public class FlightManagement { * @return an airport by airport code * @throws Exception if the airport ist not found */ - private Airport searchAirport(String airportCode) { + private Airport searchAirport(String airportCode) throws Exception { //TODO H8.5.1 - return org.tudalgo.algoutils.student.Student.crash("H8.5.1 - Remove if implemented"); + for (int i = 0; i < size; i++) { + if (airports[i].getAirportCode().equals(airportCode)) { + return airports[i]; + } + } + + throw new Exception("Airport not found: " + airportCode); } /** @@ -101,6 +128,15 @@ public class FlightManagement { */ private Flight searchFlight(Airport airport, String flightNumber) { //TODO H8.5.1 - return org.tudalgo.algoutils.student.Student.crash("H8.5.1 - Remove if implemented"); + try { + return airport.getFlight(flightNumber, true); + } catch (FlightNotFoundException e) { + try { + return airport.getFlight(flightNumber, false); + } + catch (FlightNotFoundException euerScheißErnstEinElf) { + return null; + } + } } } diff --git a/H08/src/main/java/h08/Passenger.java b/H08/src/main/java/h08/Passenger.java index fb91ece..741447c 100644 --- a/H08/src/main/java/h08/Passenger.java +++ b/H08/src/main/java/h08/Passenger.java @@ -55,7 +55,7 @@ public class Passenger { @StudentImplementationRequired("H8.1") private String generatePassengerID(String firstName, String lastName, LocalDate dateOfBirth) { //TODO H8.1 - return org.tudalgo.algoutils.student.Student.crash("H8.1 - Remove if implemented"); + return "" + firstName.charAt(0) + lastName.charAt(0) + dateOfBirth.hashCode(); } /** diff --git a/H09/build.gradle.kts b/H09/build.gradle.kts index 7ed2fe4..d13235d 100644 --- a/H09/build.gradle.kts +++ b/H09/build.gradle.kts @@ -13,12 +13,9 @@ submission { // Setzen Sie im folgenden Bereich Ihre TU-ID (NICHT Ihre Matrikelnummer!), Ihren Nachnamen und Ihren Vornamen // in Anführungszeichen (z.B. "ab12cdef" für Ihre TU-ID) ein! // BEISPIEL: - // studentId = "ab12cdef" - // firstName = "sol_first" - // lastName = "sol_last" - studentId = "" - firstName = "" - lastName = "" + studentId = "ab12cdef" + firstName = "sol_first" + lastName = "sol_last" // Optionally require own tests for mainBuildSubmission task. Default is false requireTests = false diff --git a/H09/src/main/java/h09/Enclosure.java b/H09/src/main/java/h09/Enclosure.java index 561255d..6ab0366 100644 --- a/H09/src/main/java/h09/Enclosure.java +++ b/H09/src/main/java/h09/Enclosure.java @@ -1,9 +1,11 @@ package h09; +import h09.abilities.Swims; import h09.animals.Animal; import org.tudalgo.algoutils.student.annotation.DoNotTouch; import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; +import javax.security.auth.login.AccountNotFoundException; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.Supplier; @@ -12,13 +14,13 @@ import java.util.function.Supplier; * An object of a class implementing {@link Enclosure} has the ability to contain and manage a stack of {@link Animal}s. */ // TODO: H9.2.1 -public interface Enclosure { +public interface Enclosure { /** * @return the stack of animals which is used manage the contained {@link Animal}s */ @StudentImplementationRequired("H9.2.1") // TODO: H9.2.1 - StackOfObjects getStack(); + StackOfObjects getStack(); /** * Feeds all contained animals. @@ -47,7 +49,7 @@ public interface Enclosure { * @param func operation to be applied to each {@link Animal} in the enclosure */ @StudentImplementationRequired("H9.3.1") // TODO: H9.3.1 - default void forEach(Consumer func) { + default void forEach(Consumer func) { for (int i = 0; i < this.getStack().size(); i++) func.accept(this.getStack().get(i)); } @@ -60,9 +62,9 @@ public interface Enclosure { * @param filter operation to test to each {@link Animal} in the enclosure */ @StudentImplementationRequired("H9.3.2") // TODO: H9.3.2 - default void filterObj(Predicate filter) { + default void filterObj(Predicate filter) { for (int i = 0; i < this.getStack().size(); i++) { - Object a = this.getStack().get(i); + A a = this.getStack().get(i); if (!filter.test(a)) { this.getStack().remove(a); i--; @@ -82,9 +84,15 @@ public interface Enclosure { * satisfied the predicate */ @StudentImplementationRequired("H9.3.3") - default Enclosure filterFunc(Supplier supp, Predicate filter) { + default > E filterFunc(Supplier supp, Predicate filter) { // TODO: H9.3.3 - return org.tudalgo.algoutils.student.Student.crash("H9.3.3 - Remove if implemented"); + E enclosure = supp.get(); + forEach(a -> { + if (filter.test(a)) { + enclosure.getStack().push(a); + } + }); + return enclosure; } /** @@ -97,13 +105,17 @@ public interface Enclosure { * {@link Predicate} which returns true if a swimming {@link Animal} swims at a low elevation. */ @StudentImplementationRequired("H9.4.1") // TODO: H9.4.1 - Predicate SWIMS_AT_LOW_ELEVATION = null; + Predicate SWIMS_AT_LOW_ELEVATION = a -> + a.getElevation() < Swims.HIGH_ELEVATION; /** * {@link Consumer} which lets the consumed {@link Animal} eat and sleep. */ @StudentImplementationRequired("H9.4.2") // TODO: H9.4.2 - Consumer FEED_AND_SLEEP = null; + Consumer FEED_AND_SLEEP = a -> { + a.eat(); + a.sleep(); + }; /** * Returns a {@link Consumer} which lets the consumed swimming {@link Animal} eat and swim down. @@ -112,8 +124,11 @@ public interface Enclosure { * @return a {@link Consumer} which lets the consumed swimming {@link Animal} eat and swim down */ @StudentImplementationRequired("H9.4.3") - static Consumer EAT_AND_SINK() { + static Consumer EAT_AND_SINK() { // TODO: H9.4.3 - return org.tudalgo.algoutils.student.Student.crash("H9.4.3 - Remove if implemented"); + return a -> { + a.eat(); + a.swimDown(); + }; } } diff --git a/H09/src/main/java/h09/StackOfObjects.java b/H09/src/main/java/h09/StackOfObjects.java index 9094f82..4531686 100644 --- a/H09/src/main/java/h09/StackOfObjects.java +++ b/H09/src/main/java/h09/StackOfObjects.java @@ -6,10 +6,10 @@ import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; /** * An object of class {@link StackOfObjects} represents a data structure of type stack. */ -@SuppressWarnings({"ManualArrayCopy"}) -public class StackOfObjects { +@SuppressWarnings({"ManualArrayCopy", "unchecked"}) +public class StackOfObjects { @StudentImplementationRequired("H9.1.1") // TODO: H9.1.1 - private Object[] objs = new Object[0]; + private O[] objs = (O[]) new Object[0]; /** * Pushes the given object on this stack. @@ -17,8 +17,8 @@ public class StackOfObjects { * @param obj the object */ @StudentImplementationRequired("H9.1.2") // TODO: H9.1.2 - public void push(Object obj) { - Object[] newArray = new Object[objs.length + 1]; + public void push(O obj) { + O[] newArray = (O[]) new Object[objs.length + 1]; for (int i = 0; i < objs.length; i++) newArray[i] = objs[i]; newArray[objs.length] = obj; objs = newArray; @@ -30,10 +30,10 @@ public class StackOfObjects { * @param obj the object */ @StudentImplementationRequired("H9.1.3") // TODO: H9.1.3 - public void remove(Object obj) { - Object[] newArray = new Object[objs.length - 1]; + public void remove(O obj) { + O[] newArray = (O[]) new Object[objs.length - 1]; int n = 0; - for (Object currObj : objs) { + for (O currObj : objs) { if (currObj == obj) continue; newArray[n++] = currObj; } @@ -57,7 +57,7 @@ public class StackOfObjects { * @return the object */ @StudentImplementationRequired("H9.1.4") // TODO: H9.1.4 - public Object get(int index) { + public O get(int index) { return objs[index]; } @@ -67,8 +67,8 @@ public class StackOfObjects { * @return the top object */ @StudentImplementationRequired("H9.1.4") // TODO: H9.1.4 - public Object pop() { - Object o = get(objs.length - 1); + public O pop() { + O o = get(objs.length - 1); remove(o); return o; } @@ -82,8 +82,8 @@ public class StackOfObjects { */ @SafeVarargs @StudentImplementationRequired("H9.1.5") // TODO: H9.1.5 - public static StackOfObjects of(Object... objs) { - StackOfObjects stack = new StackOfObjects(); + public static StackOfObjects of(O... objs) { + var stack = new StackOfObjects(); stack.objs = objs; return stack; } diff --git a/H09/src/main/java/h09/WaterEnclosure.java b/H09/src/main/java/h09/WaterEnclosure.java index 9d4a468..aefb18e 100644 --- a/H09/src/main/java/h09/WaterEnclosure.java +++ b/H09/src/main/java/h09/WaterEnclosure.java @@ -9,25 +9,36 @@ import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; * {@link Animal}s which have the ability to {@link Swims}. */ // TODO: H9.2.2 -public class WaterEnclosure { +public class WaterEnclosure implements Enclosure { /** * The stack of animals which is used manage the contained Animals. */ @StudentImplementationRequired("H9.2.2") // TODO: H9.2.2 - final StackOfObjects animals = null; + final StackOfObjects animals = new StackOfObjects<>(); @StudentImplementationRequired("H9.2.2") - // @Override - public StackOfObjects getStack() { + @Override + public StackOfObjects getStack() { // TODO: H9.2.2 - return org.tudalgo.algoutils.student.Student.crash("H9.2.2 - Remove if implemented"); + return animals; } @StudentImplementationRequired("H9.2.2") - // @Override + @Override public void feed() { // TODO: H9.2.2 - org.tudalgo.algoutils.student.Student.crash("H9.2.2 - Remove if implemented"); + forEach(a -> { + if (!a.isHungry()) { + return; + } + + if (a.getElevation() < Swims.HIGH_ELEVATION) { + a.swimUp(); + } + + a.eat(); + a.swimDown(); + }); } /** @@ -38,6 +49,10 @@ public class WaterEnclosure { @StudentImplementationRequired("H9.2.2") public float getMeanElevation() { // TODO: H9.2.2 - return org.tudalgo.algoutils.student.Student.crash("H9.2.2 - Remove if implemented"); + float sum = 0; + for (int i = 0; i < getStack().size(); i++) { + sum += getStack().get(i).getElevation(); + } + return sum / getStack().size(); } } diff --git a/H09/src/test/java/h09/EnclosureTest.java b/H09/src/test/java/h09/EnclosureTest.java index f6b5c2f..db8e7e3 100644 --- a/H09/src/test/java/h09/EnclosureTest.java +++ b/H09/src/test/java/h09/EnclosureTest.java @@ -1,8 +1,15 @@ package h09; +import h09.abilities.Swims; +import h09.animals.Animal; +import h09.animals.Fish; +import h09.animals.Lion; +import h09.animals.Penguin; import org.junit.jupiter.api.Test; import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired; +import static org.junit.jupiter.api.Assertions.*; + /** * An example JUnit test class. */ @@ -12,7 +19,25 @@ public class EnclosureTest { @StudentImplementationRequired("H9.5.1") public void testForEach() { // TODO: H9.5.1 - org.tudalgo.algoutils.student.Student.crash("H9.5.1 - Remove if implemented"); + Lion lia = new Lion("Lia", 1); + Lion lib = new Lion("Lib", 1); + Lion lic = new Lion("Lic", 1); + + // Creating lion enclosure... + GroundEnclosure lionEnclosure = new GroundEnclosure<>(); + lionEnclosure.getStack().push(lia); + lionEnclosure.getStack().push(lib); + lionEnclosure.getStack().push(lic); + + assertTrue(lia.isHungry()); + assertTrue(lib.isHungry()); + assertTrue(lic.isHungry()); + + lionEnclosure.forEach(Lion::eat); + + assertFalse(lia.isHungry()); + assertFalse(lib.isHungry()); + assertFalse(lic.isHungry()); } @@ -20,6 +45,35 @@ public class EnclosureTest { @StudentImplementationRequired("H9.5.2") public void testFilter() { // TODO: H9.5.2 - org.tudalgo.algoutils.student.Student.crash("H9.5.2 - Remove if implemented"); + // crating fish + Penguin tux = new Penguin("tux", 1, -5); + tux.eat(); + + Penguin windoof = new Penguin("windoof", 1, -5); + + WaterEnclosure enclosure = new WaterEnclosure<>(); + enclosure.getStack().push(tux); + enclosure.getStack().push(windoof); + + assertFalse(tux.isHungry()); + assertTrue(windoof.isHungry()); + + enclosure + .filterFunc(WaterEnclosure::new, Animal::isHungry) + .filterFunc(WaterEnclosure::new, Enclosure.SWIMS_AT_LOW_ELEVATION) + .forEach(Penguin::swimUp); + + assertTrue(tux.getElevation() < Swims.HIGH_ELEVATION); + assertTrue(windoof.getElevation() > Swims.HIGH_ELEVATION); + + enclosure + .filterFunc(WaterEnclosure::new, Animal::isHungry) + .forEach(Enclosure.EAT_AND_SINK()); + + assertTrue(tux.getElevation() < Swims.HIGH_ELEVATION); + assertTrue(windoof.getElevation() < Swims.HIGH_ELEVATION); + + assertFalse(tux.isHungry()); + assertFalse(windoof.isHungry()); } } diff --git a/H09/src/test/java/h09/ExampleZooTest.java b/H09/src/test/java/h09/ExampleZooTest.java index 32f633f..8b0bc0c 100644 --- a/H09/src/test/java/h09/ExampleZooTest.java +++ b/H09/src/test/java/h09/ExampleZooTest.java @@ -17,13 +17,13 @@ public class ExampleZooTest { fishEnclosure.getStack().push(new Fish("Fisch", 3)); // can be used after H9.3.1 -// System.out.println("Get fish elevation..."); -// fishEnclosure.forEach(fish -> System.out.println(fish.getName() + ": " + fish.getElevation())); -// -// System.out.println("\nLet fish swim up..."); -// fishEnclosure.forEach(Fish::swimUp); -// fishEnclosure.forEach(Fish::swimUp); -// fishEnclosure.forEach(Fish::swimUp); + System.out.println("Get fish elevation..."); + fishEnclosure.forEach(fish -> System.out.println(fish.getName() + ": " + fish.getElevation())); + + System.out.println("\nLet fish swim up..."); + fishEnclosure.forEach(Fish::swimUp); + fishEnclosure.forEach(Fish::swimUp); + fishEnclosure.forEach(Fish::swimUp); System.out.println("\nFeed the fish..."); fishEnclosure.feed(); @@ -40,27 +40,27 @@ public class ExampleZooTest { penguinGroundEnclosure.getStack().push(new Penguin("Penge", 30)); System.out.println("\nMigrating the Penguins to a WaterEnclosure..."); -// WaterEnclosure penguinWaterEnclosure = new WaterEnclosure<>(); -// while (penguinGroundEnclosure.getStack().size() > 0) { -// Penguin penguin = penguinGroundEnclosure.getStack().pop(); -// penguinWaterEnclosure.getStack().push(penguin); -// } + WaterEnclosure penguinWaterEnclosure = new WaterEnclosure<>(); + while (penguinGroundEnclosure.getStack().size() > 0) { + Penguin penguin = penguinGroundEnclosure.getStack().pop(); + penguinWaterEnclosure.getStack().push(penguin); + } // can be used after H9.3.2 -// System.out.println("\nRemoving old penguins..."); -// penguinWaterEnclosure.filterObj(Enclosure.IS_OLD.negate()); -// System.out.println(penguinWaterEnclosure.getStack().size() + " young penguin(s) left."); -// -// System.out.println("\nSleep /age again"); -// penguinWaterEnclosure.forEach(Animal::sleep); -// -// // can be used after H9.3.3 -// System.out.println("\nLooking for hungry and old Penguins..."); -// System.out.println(penguinWaterEnclosure.countHungry() + " hungry penguins."); -// System.out.println(penguinWaterEnclosure.filterFunc(WaterEnclosure::new, Enclosure.IS_OLD).getStack().size() + " old penguins."); -// -// System.out.println("\nFeed old penguins and let them sleep..."); -// penguinWaterEnclosure.filterFunc(WaterEnclosure::new, Enclosure.IS_OLD).forEach(Enclosure.FEED_AND_SLEEP); + System.out.println("\nRemoving old penguins..."); + penguinWaterEnclosure.filterObj(Enclosure.IS_OLD.negate()); + System.out.println(penguinWaterEnclosure.getStack().size() + " young penguin(s) left."); + + System.out.println("\nSleep /age again"); + penguinWaterEnclosure.forEach(Animal::sleep); + + // can be used after H9.3.3 + System.out.println("\nLooking for hungry and old Penguins..."); + System.out.println(penguinWaterEnclosure.countHungry() + " hungry penguins."); + System.out.println(penguinWaterEnclosure.filterFunc(WaterEnclosure::new, Enclosure.IS_OLD).getStack().size() + " old penguins."); + + System.out.println("\nFeed old penguins and let them sleep..."); + penguinWaterEnclosure.filterFunc(WaterEnclosure::new, Enclosure.IS_OLD).forEach(Enclosure.FEED_AND_SLEEP); } } diff --git a/solution/H06/gradle/libs.versions.toml b/solution/H06/gradle/libs.versions.toml index 2a961b5..a245538 100644 --- a/solution/H06/gradle/libs.versions.toml +++ b/solution/H06/gradle/libs.versions.toml @@ -1,3 +1,3 @@ [plugins] -algomate = { id = "org.tudalgo.algomate", version = "0.7.1" } +algomate = { id = "org.tudalgo.algomate", version = "0.7.0" } style = { id = "org.sourcegrade.style", version = "3.0.0" } diff --git a/solution/H07/build.gradle.kts b/solution/H07/build.gradle.kts index d4cda26..0b67281 100644 --- a/solution/H07/build.gradle.kts +++ b/solution/H07/build.gradle.kts @@ -34,13 +34,4 @@ jagr { rubricProviderName.set("h07.H07_RubricProvider") } } - graders { - val graderPrivate by creating { - graderName.set("H07-Private") - rubricProviderName.set("h07.H07_RubricProvider") - configureDependencies { - implementation(libs.algoutils.tutor) - } - } - } } diff --git a/solution/H07/gradle/libs.versions.toml b/solution/H07/gradle/libs.versions.toml index 2a961b5..a245538 100644 --- a/solution/H07/gradle/libs.versions.toml +++ b/solution/H07/gradle/libs.versions.toml @@ -1,3 +1,3 @@ [plugins] -algomate = { id = "org.tudalgo.algomate", version = "0.7.1" } +algomate = { id = "org.tudalgo.algomate", version = "0.7.0" } style = { id = "org.sourcegrade.style", version = "3.0.0" } diff --git a/solution/H08/settings.gradle.kts b/solution/H08/settings.gradle.kts index 959cdf2..b7cd8f7 100644 --- a/solution/H08/settings.gradle.kts +++ b/solution/H08/settings.gradle.kts @@ -8,8 +8,4 @@ dependencyResolutionManagement { } } -<<<<<<<< Updated upstream:solution/H08/settings.gradle.kts rootProject.name = "H08-Root" -======== -rootProject.name = "H09-Student" ->>>>>>>> Stashed changes:H09/settings.gradle.kts diff --git a/solution/H08/src/main b/solution/H08/src/main index 96a2e25..1640a28 120000 --- a/solution/H08/src/main +++ b/solution/H08/src/main @@ -1 +1 @@ -/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H08/src/main \ No newline at end of file +/home/osh/Desktop/FOP-2425-Marathon/H08/src/main \ No newline at end of file diff --git a/solution/H08/src/test b/solution/H08/src/test index e9bb0fe..8c29963 120000 --- a/solution/H08/src/test +++ b/solution/H08/src/test @@ -1 +1 @@ -/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H08/src/test \ No newline at end of file +/home/osh/Desktop/FOP-2425-Marathon/H08/src/test \ No newline at end of file diff --git a/solution/H09/jagr.conf b/solution/H09/jagr.conf new file mode 100644 index 0000000..dbd1da5 --- /dev/null +++ b/solution/H09/jagr.conf @@ -0,0 +1,70 @@ +# The locations of the following directories may be configured here +dir { + # Grader jar ingest directory + graders=graders + # Runtime dependencies for submissions + libs=libs + # Rubrics export directory + rubrics=rubrics + # Submissions ingest directory + submissions=submissions + # Submission export directory + submissions-export=submissions-export +} +executor { + # + # The maximum amount of concurrency to use for grading. + # For a given concurrency n, Jagr will ensure that a maximum of n threads or processes are used concurrently that actively run + # submission code. + concurrency=4 + # + # The JVM arguments to use for grading. These arguments are passed to the JVM that runs the grading code. + # This only applies to the "process" mode, as the "thread" and "single" modes do not spawn a new JVM. + # + jvm-args=[] + # + # The executor mode to use. The following options are available: + # - "single" :: + # Runs every TestCycle consecutively in the main thread. This mode does not create any extra processes or threads for grading. + # + # - "thread" :: + # Creates a separate thread for every TestCycle. This mode greatly speeds up the grading process, especially with a large + # amount of submissions. The overhead of creating, managing and synchronizing threads is minimal compared to the performance + # benefits. However, this mode has the danger of creating "unkillable" threads (e.g. from certain kinds of infinite loops) + # which dramatically slow down the grading process through resource starvation of the host machine. + # + # The maximum number of concurrent threads used for grading is defined by the option "concurrency". + # + # - "process" :: + # Creates a separate process for every TestCycle. This mode has the most overhead, but is also the most defensive against + # "badly behaving" code. A certain amount of sandboxing can be achieved in this mode, which is not possible in the other modes + # such as "thread" or "single". + # + # The maximum number of concurrent child process used for grading is defined by the option "concurrency". + mode=process + # + # The grading thread's maximum permitted elapsed userTime in milliseconds since the last timeout before an + # AssertionFailedError is thrown. If a thread's userTime satisfies + # (userTime - lastTimeout) > individualTimeout, + # the current userTime is stored for comparison later, and an AssertionFailedError is thrown to be caught by JUnit. + timeout-individual=10000 + # + # The grading thread's maximum permitted elapsed userTime in milliseconds (from thread start) before an + # AssertionFailedError is thrown. If a thread's userTime satisfies + # ((userTime - lastTimeout) > individualTimeout) && (userTime > totalTimeout), + # an AssertionFailedError is thrown to be caught by JUnit. Note that lastTimeout is not reset in this case, and all further + # invocations of checkTimeout() will result in an AssertionFailedError + timeout-total=150000 +} +extras { + moodle-unpack { + assignment-id-regex=".*Abgabe[^0-9]*(?[0-9]{1,2}).*[.]zip" + enabled=true + student-regex=".* - (?([a-z]{2}[0-9]{2}[a-z]{4})|([a-z]+_[a-z]+))/submissions/.*[.]jar" + } +} +transformers { + timeout { + enabled=true + } +} diff --git a/solution/H09/src/main b/solution/H09/src/main index 21e66ea..64528ca 120000 --- a/solution/H09/src/main +++ b/solution/H09/src/main @@ -1 +1 @@ -/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H09/src/main \ No newline at end of file +/home/osh/Desktop/FOP-2425-Marathon/H09/src/main \ No newline at end of file diff --git a/solution/H09/src/test b/solution/H09/src/test index e62cbc6..eff0849 120000 --- a/solution/H09/src/test +++ b/solution/H09/src/test @@ -1 +1 @@ -/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H09/src/test \ No newline at end of file +/home/osh/Desktop/FOP-2425-Marathon/H09/src/test \ No newline at end of file diff --git a/solution/H10/src/main b/solution/H10/src/main index f3448ee..8104529 120000 --- a/solution/H10/src/main +++ b/solution/H10/src/main @@ -1 +1 @@ -/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H10/src/main \ No newline at end of file +/home/osh/Desktop/FOP-2425-Marathon/H10/src/main \ No newline at end of file diff --git a/solution/H10/src/test b/solution/H10/src/test index 8a7072b..1713cc9 120000 --- a/solution/H10/src/test +++ b/solution/H10/src/test @@ -1 +1 @@ -/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H10/src/test \ No newline at end of file +/home/osh/Desktop/FOP-2425-Marathon/H10/src/test \ No newline at end of file diff --git a/solution/H11/src/main b/solution/H11/src/main index 0bd7ed0..d9ce9bb 120000 --- a/solution/H11/src/main +++ b/solution/H11/src/main @@ -1 +1 @@ -/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H11/src/main \ No newline at end of file +/home/osh/Desktop/FOP-2425-Marathon/H11/src/main \ No newline at end of file diff --git a/solution/H11/src/test b/solution/H11/src/test index bcc3216..bb424b0 120000 --- a/solution/H11/src/test +++ b/solution/H11/src/test @@ -1 +1 @@ -/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H11/src/test \ No newline at end of file +/home/osh/Desktop/FOP-2425-Marathon/H11/src/test \ No newline at end of file diff --git a/solution/H12/src/main b/solution/H12/src/main index 22eee3e..896a6ca 120000 --- a/solution/H12/src/main +++ b/solution/H12/src/main @@ -1 +1 @@ -/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H12/src/main \ No newline at end of file +/home/osh/Desktop/FOP-2425-Marathon/H12/src/main \ No newline at end of file diff --git a/solution/H12/src/test b/solution/H12/src/test index a1eb1bf..5844f30 120000 --- a/solution/H12/src/test +++ b/solution/H12/src/test @@ -1 +1 @@ -/home/osh/Desktop/FOP-2425-Marathon/FOP-2425-Marathon/H12/src/test \ No newline at end of file +/home/osh/Desktop/FOP-2425-Marathon/H12/src/test \ No newline at end of file