diff --git a/complexityExample/files/solution/name/panitz/util/LL.java b/complexityExample/files/solution/name/panitz/util/LL.java new file mode 100644 index 0000000000000000000000000000000000000000..fb2a718781d9182dd6a7fb44b35a4046770fe73a --- /dev/null +++ b/complexityExample/files/solution/name/panitz/util/LL.java @@ -0,0 +1,311 @@ + + +package name.panitz.util; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Consumer; +import java.util.Comparator; + +import java.util.NoSuchElementException; + +public sealed interface LL<E> permits LL.Nil, LL.Cons{ + + static int binSearch(int x,int[] xs){ + var low = 0; + var up = xs.length-1; + while (low<=up){ + var middle = (low+up)/2; + if (xs[middle]==x) return middle; + if (low==middle) low=up; + if (low==up) break; + if (xs[middle]>x) up = middle; + else if (xs[middle]<x) low = middle; + } + return -1; + } + + record Nil<E>() implements LL<E>{ + @Override public String toString(){return "[]";} + } + + record Cons<E>(E hd,LL<E> tl) implements LL<E>{ + @Override public String toString(){ + return show(true,new StringBuffer("[")); + } + } + + default boolean isEmpty(){return this instanceof Nil;} + + default E head(){ + if (this instanceof Cons<E> c) return c.hd(); + throw new NoSuchElementException("head on empty list"); + } + + default LL<E> tail(){ + if (this instanceof Cons<E> c) return c.tl(); + throw new NoSuchElementException("tail on empty list"); + } + + @SuppressWarnings("rawtypes") + final LL nil = new Nil<>(); + @SuppressWarnings("unchecked") + static <E>LL<E> nil(){return nil;} + + static <E>LL<E> cons(E hd,LL<E> tl){return new Cons<>(hd,tl);} + + @SafeVarargs + static <E>LL<E> of(E...es){ + LL<E> r = nil(); + for (int i=es.length-1;i>=0;i--) r = cons(es[i],r); + return r; + } + + default String show(boolean first,StringBuffer result){ + if (isEmpty()) { + result.append("]"); + return result.toString(); + } + if (!first)result.append(", "); + result.append(head()); + return tail().show(false,result); + } + + + default int length(){ + if (isEmpty())return 0; + return 1+tail().length(); + /*var r = 0; + for (var it=this;!it.isEmpty();it=it.tail()) + r++; + return r;*/ + + } + + + default E last1(){ + if (tail().isEmpty()) return head(); + return tail().last1(); + } + + /* Version mit Deconstruction Pattern. Seit Java 19 ein neues preview feature. + (scheint ab Java 21 festes feature zu werden.) + */ + @SuppressWarnings("preview") + default E last(){ + return switch (this) { + case Cons<E>(E x,Nil<E>()) -> x; + case Cons<E> xs -> xs.tail().last(); + case Nil<E>() -> throw new NoSuchElementException(); + }; + } + + + + + default LL<E> append(LL<E> that){ + if (this instanceof Cons) return cons(head(),tail().append(that)); + else return that; + } + + + + + default LL<E> drop(int i){ + if (this instanceof Cons<E> c && i>0) + return c.tail().drop(i-1); + return this; + } + + + + + default LL<E> take(int i){ + if (this instanceof Cons && i>0) + return cons(head(),tail().take(i-1)); + return nil(); + } + + + + + default LL<E> sublist(int from, int length) { + return drop(from).take(length); + } + + + + /* Die ineffizientere rekursive Lösung. */ + default LL<E> reverse1(){ + if (this instanceof Cons) + return tail().reverse1().append(cons(head(),nil())); + return nil(); + } + + /* Die iterative Lösung. */ + default LL<E> reverse(){ + LL<E> rs = nil(); + for (var it=this;!it.isEmpty();it=it.tail()) + rs = cons(it.head(),rs); + return rs; + } + + + + default LL<E> intersperse(E e){ + if (isEmpty()||tail().isEmpty()) return this; + return cons(head(),cons(e,tail().intersperse(e))); + } + + + + default boolean isPrefixOf(LL<E> that){ + if (isEmpty()) return true; + if (that.isEmpty()) return false; + return head().equals(that.head())&&tail().isPrefixOf(that.tail()); + } + + + + default boolean isSuffixOf(LL<E> that){ + return this.reverse().isPrefixOf(that.reverse()); + } + + + + default boolean isInfixOf(LL<E> that){ + return isPrefixOf(that)|| + (!that.isEmpty()&&isInfixOf(that.tail())); + } + + + + default E get(int i){ + if (isEmpty()||i<0) throw new IndexOutOfBoundsException(); + if (i==0) return head(); + return tail().get(i-1); + } + + + + default LL<E> rotate(){return tail().append(of(head()));} + + + + default LL<LL<E>> tails(){ + if (isEmpty()) return of(nil()); + return cons(this,tail().tails()); + } + + + + default void forEach(Consumer<? super E> con) { + if (isEmpty()) return; + con.accept(head()); + tail().forEach(con); + } + + + + + default boolean containsWith(Predicate< ? super E> p) { + if (isEmpty()) return false; + return p.test(head())||tail().containsWith(p); + } + + + + + default boolean contains(E el) { + return containsWith(x->x.equals(el)); + } + + + + + default LL<E> dropWhile(Predicate< ? super E> p){ + if (this instanceof Cons<E> c && p.test(head())) + return c.tail().dropWhile(p); + return this; + } + + + + default LL<E> takeWhile(Predicate< ? super E> p){ + if (this instanceof Cons && p.test(head())) + return cons(head(),tail().takeWhile(p)); + return nil(); + } + + + + default LL<E> filter(Predicate<? super E> p){ + if (isEmpty()) return nil(); + if (p.test(head())) return cons(head(), tail().filter(p)); + return tail().filter(p); + } + + + + default <R> LL<R> map(Function<? super E, ? extends R> f){ + if (this instanceof Cons) + return cons(f.apply(head()), tail().map(f)); + return nil(); + } + + + record Pair<A,B>(A fst,B snd){ + @Override public String toString(){return "("+fst()+", "+snd()+")";} + } + + + default <B> LL<Pair<E,B>> zip(LL<B> that){ + if (isEmpty()||that.isEmpty()) return nil(); + return cons(new Pair<>(head(),that.head()),tail().zip(that.tail())); + } + + + + default Pair<LL<E>,LL<E>> span(Predicate<? super E> p){ + if (isEmpty()) return new Pair<>(nil(),nil()); + if (!p.test(head())) return new Pair<>(nil(),this); + var r = tail().span(p); + return new Pair<>(cons(head(),r.fst()),r.snd()); + } + + + + + + default Pair<LL<E>,LL<E>> partition(Predicate<? super E> p){ + if (isEmpty()) return new Pair<>(nil(),nil()); + var r = tail().partition(p); + return p.test(head()) + ?new Pair<>(cons(head(),r.fst()),r.snd()) + :new Pair<>(r.fst(),cons(head(),r.snd())) + ; + } + + + + + + default boolean isSorted(Comparator<? super E> cmp){ + return isEmpty() + ||tail().isEmpty() + ||cmp.compare(head(),tail().head())<=0 && tail().isSorted(cmp); + } + + + + + + default LL<E> qsort(Comparator<? super E> cmp){ + if (isEmpty()) return nil(); + var p = tail().partition(x->cmp.compare(head(),x)>=0); + return p.fst().qsort(cmp).append(cons(head(),p.snd().qsort(cmp))); + } + + + + +} diff --git a/complexityExample/files/template/name/panitz/util/LL.java b/complexityExample/files/template/name/panitz/util/LL.java new file mode 100644 index 0000000000000000000000000000000000000000..fb2a718781d9182dd6a7fb44b35a4046770fe73a --- /dev/null +++ b/complexityExample/files/template/name/panitz/util/LL.java @@ -0,0 +1,311 @@ + + +package name.panitz.util; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Consumer; +import java.util.Comparator; + +import java.util.NoSuchElementException; + +public sealed interface LL<E> permits LL.Nil, LL.Cons{ + + static int binSearch(int x,int[] xs){ + var low = 0; + var up = xs.length-1; + while (low<=up){ + var middle = (low+up)/2; + if (xs[middle]==x) return middle; + if (low==middle) low=up; + if (low==up) break; + if (xs[middle]>x) up = middle; + else if (xs[middle]<x) low = middle; + } + return -1; + } + + record Nil<E>() implements LL<E>{ + @Override public String toString(){return "[]";} + } + + record Cons<E>(E hd,LL<E> tl) implements LL<E>{ + @Override public String toString(){ + return show(true,new StringBuffer("[")); + } + } + + default boolean isEmpty(){return this instanceof Nil;} + + default E head(){ + if (this instanceof Cons<E> c) return c.hd(); + throw new NoSuchElementException("head on empty list"); + } + + default LL<E> tail(){ + if (this instanceof Cons<E> c) return c.tl(); + throw new NoSuchElementException("tail on empty list"); + } + + @SuppressWarnings("rawtypes") + final LL nil = new Nil<>(); + @SuppressWarnings("unchecked") + static <E>LL<E> nil(){return nil;} + + static <E>LL<E> cons(E hd,LL<E> tl){return new Cons<>(hd,tl);} + + @SafeVarargs + static <E>LL<E> of(E...es){ + LL<E> r = nil(); + for (int i=es.length-1;i>=0;i--) r = cons(es[i],r); + return r; + } + + default String show(boolean first,StringBuffer result){ + if (isEmpty()) { + result.append("]"); + return result.toString(); + } + if (!first)result.append(", "); + result.append(head()); + return tail().show(false,result); + } + + + default int length(){ + if (isEmpty())return 0; + return 1+tail().length(); + /*var r = 0; + for (var it=this;!it.isEmpty();it=it.tail()) + r++; + return r;*/ + + } + + + default E last1(){ + if (tail().isEmpty()) return head(); + return tail().last1(); + } + + /* Version mit Deconstruction Pattern. Seit Java 19 ein neues preview feature. + (scheint ab Java 21 festes feature zu werden.) + */ + @SuppressWarnings("preview") + default E last(){ + return switch (this) { + case Cons<E>(E x,Nil<E>()) -> x; + case Cons<E> xs -> xs.tail().last(); + case Nil<E>() -> throw new NoSuchElementException(); + }; + } + + + + + default LL<E> append(LL<E> that){ + if (this instanceof Cons) return cons(head(),tail().append(that)); + else return that; + } + + + + + default LL<E> drop(int i){ + if (this instanceof Cons<E> c && i>0) + return c.tail().drop(i-1); + return this; + } + + + + + default LL<E> take(int i){ + if (this instanceof Cons && i>0) + return cons(head(),tail().take(i-1)); + return nil(); + } + + + + + default LL<E> sublist(int from, int length) { + return drop(from).take(length); + } + + + + /* Die ineffizientere rekursive Lösung. */ + default LL<E> reverse1(){ + if (this instanceof Cons) + return tail().reverse1().append(cons(head(),nil())); + return nil(); + } + + /* Die iterative Lösung. */ + default LL<E> reverse(){ + LL<E> rs = nil(); + for (var it=this;!it.isEmpty();it=it.tail()) + rs = cons(it.head(),rs); + return rs; + } + + + + default LL<E> intersperse(E e){ + if (isEmpty()||tail().isEmpty()) return this; + return cons(head(),cons(e,tail().intersperse(e))); + } + + + + default boolean isPrefixOf(LL<E> that){ + if (isEmpty()) return true; + if (that.isEmpty()) return false; + return head().equals(that.head())&&tail().isPrefixOf(that.tail()); + } + + + + default boolean isSuffixOf(LL<E> that){ + return this.reverse().isPrefixOf(that.reverse()); + } + + + + default boolean isInfixOf(LL<E> that){ + return isPrefixOf(that)|| + (!that.isEmpty()&&isInfixOf(that.tail())); + } + + + + default E get(int i){ + if (isEmpty()||i<0) throw new IndexOutOfBoundsException(); + if (i==0) return head(); + return tail().get(i-1); + } + + + + default LL<E> rotate(){return tail().append(of(head()));} + + + + default LL<LL<E>> tails(){ + if (isEmpty()) return of(nil()); + return cons(this,tail().tails()); + } + + + + default void forEach(Consumer<? super E> con) { + if (isEmpty()) return; + con.accept(head()); + tail().forEach(con); + } + + + + + default boolean containsWith(Predicate< ? super E> p) { + if (isEmpty()) return false; + return p.test(head())||tail().containsWith(p); + } + + + + + default boolean contains(E el) { + return containsWith(x->x.equals(el)); + } + + + + + default LL<E> dropWhile(Predicate< ? super E> p){ + if (this instanceof Cons<E> c && p.test(head())) + return c.tail().dropWhile(p); + return this; + } + + + + default LL<E> takeWhile(Predicate< ? super E> p){ + if (this instanceof Cons && p.test(head())) + return cons(head(),tail().takeWhile(p)); + return nil(); + } + + + + default LL<E> filter(Predicate<? super E> p){ + if (isEmpty()) return nil(); + if (p.test(head())) return cons(head(), tail().filter(p)); + return tail().filter(p); + } + + + + default <R> LL<R> map(Function<? super E, ? extends R> f){ + if (this instanceof Cons) + return cons(f.apply(head()), tail().map(f)); + return nil(); + } + + + record Pair<A,B>(A fst,B snd){ + @Override public String toString(){return "("+fst()+", "+snd()+")";} + } + + + default <B> LL<Pair<E,B>> zip(LL<B> that){ + if (isEmpty()||that.isEmpty()) return nil(); + return cons(new Pair<>(head(),that.head()),tail().zip(that.tail())); + } + + + + default Pair<LL<E>,LL<E>> span(Predicate<? super E> p){ + if (isEmpty()) return new Pair<>(nil(),nil()); + if (!p.test(head())) return new Pair<>(nil(),this); + var r = tail().span(p); + return new Pair<>(cons(head(),r.fst()),r.snd()); + } + + + + + + default Pair<LL<E>,LL<E>> partition(Predicate<? super E> p){ + if (isEmpty()) return new Pair<>(nil(),nil()); + var r = tail().partition(p); + return p.test(head()) + ?new Pair<>(cons(head(),r.fst()),r.snd()) + :new Pair<>(r.fst(),cons(head(),r.snd())) + ; + } + + + + + + default boolean isSorted(Comparator<? super E> cmp){ + return isEmpty() + ||tail().isEmpty() + ||cmp.compare(head(),tail().head())<=0 && tail().isSorted(cmp); + } + + + + + + default LL<E> qsort(Comparator<? super E> cmp){ + if (isEmpty()) return nil(); + var p = tail().partition(x->cmp.compare(head(),x)>=0); + return p.fst().qsort(cmp).append(cons(head(),p.snd().qsort(cmp))); + } + + + + +} diff --git a/complexityExample/files/test/config.properties b/complexityExample/files/test/config.properties new file mode 100644 index 0000000000000000000000000000000000000000..4692023f626d275a5a9e08964bdc0fc862231114 --- /dev/null +++ b/complexityExample/files/test/config.properties @@ -0,0 +1,6 @@ +classFile=name.panitz.util.LL + +#traceMethodInvocations=true +invocationCounter=length,take,append,reverse,contains,last,addAll,drop,sublist,intersperse,isPrefixOf,isSuffixOf,isInfixOf,rotate,tails,zip + +iterationCounter=binSearch \ No newline at end of file diff --git a/complexityExample/files/test/name/panitz/util/LLTest.java b/complexityExample/files/test/name/panitz/util/LLTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f5452d9dd6b3b2852d7bc52a21bc91f36db2d078 --- /dev/null +++ b/complexityExample/files/test/name/panitz/util/LLTest.java @@ -0,0 +1,503 @@ +package name.panitz.util; +import static name.panitz.util.LL.*; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; +import java.util.Collection; + +import org.junit.Before; +import org.junit.Test; + +public class LLTest { + + LL<String> xs; + LL<String> ys; + LL<Integer> is; + LL<Integer> is2; + int i = 0; + + + + @Before + public void setUp() throws Exception { + xs = nil(); + ys = nil(); + is = nil(); + is2 = nil(); + i = 0; + CounterFields.resetCounters(); + } + + @Test + public void tesBinSearch1() { + int[] xs = {1,2,3,4,5,6,7,8,9,10}; + assertEquals(")",2,binSearch(3,xs)); + } + @Test + public void tesBinSearch1Complexity() { + int[] xs = {1,2,3,4,5,6,7,8,9,10}; + binSearch(3,xs); + assertTrue("counting binSearch Aufrufe",2>=CounterFields.binSearchIterationCount); + } + @Test + public void tesBinSearch2Complexity() { + int[] xs = {1,2,3,4,5,6,7,8,9,10}; + binSearch(12,xs); + assertTrue("counting binSearch Aufrufe",5>=CounterFields.binSearchIterationCount); + } + @Test + public void testLength1() { + assertEquals("nil().length()",0,nil().length()); + } + + @Test + public void testLength2() { + assertEquals("of(42).length()",1,of(42).length()); + } + @Test + public void testLength2Complexity() { + of(42).length(); + assertTrue("counting length Aufrufe",2>=CounterFields.lengthInvocationCount); + } + @Test + public void testLength3() { + assertEquals("of(1,2,3,4,5).length()",5,of(1,2,3,4,5).length()); + } + @Test + public void testLength3Complexity() { + of(1,2,3,4,5).length(); + assertTrue("counting length Aufrufe",6>=CounterFields.lengthInvocationCount); + } + + @Test + public void testAppen1() { + assertEquals("nil().append(nil())",nil(),nil().append(nil())); + } + + @Test + public void testAppend2() { + assertEquals("of(1).append(nil())",of(1),of(1).append(nil())); + } + @Test + public void testAppend3() { + assertEquals("of(1).append(of(2,3,4))",of(1,2,3,4),of(1).append(of(2,3,4))); + } + @Test + public void testAppend4() { + assertEquals("of(1).append(nil())",of(1),of(1).append(nil())); + } + @Test + public void testAppend5() { + assertEquals("of(1,2,3,4).append(of(2,3,4))",of(1,2,3,4,2,3,4),of(1,2,3,4).append(of(2,3,4))); + } + + + @Test + public void testContainsWith1() { + assertFalse("containsWith muss für leere Liste false ergeben.", xs.containsWith(x -> true)); + xs = cons("freunde",xs); + assertFalse("containsWith muss für Prädikat (x->false) immer false ergeben.", xs.containsWith(x -> false)); + assertTrue("containsWith muss für Prädikat (x->true) immer true ergeben.", xs.containsWith(x -> true)); + assertTrue("containsWith falsch für Prädikat (x->x.equals(\"freunde\")), obwohl Wort in Liste ist.", + xs.containsWith(x -> x.equals("freunde"))); + assertFalse("containsWith falsch für Prädikat (x->x.equals(\"friends\")), wenn Wort nicht in Liste ist.", + xs.containsWith(x -> x.equals("friends"))); + assertTrue(of(1,2,3,4,5,6,7).containsWith(x->x%3==0)); + + } + + @Test + public void testContains1() { + xs = of("A","B","C","D","E","F","G"); + assertTrue("contains findet erstes element nicht.", xs.contains("a".toUpperCase()+"")); + assertTrue("contains findet letztes element nicht.", xs.contains("G".toUpperCase()+"")); + assertTrue("contains findet mittleres element nicht.", xs.contains("D".toUpperCase()+"")); + assertFalse("contains findet element nicht.", xs.contains("a")); + } + @Test + public void testContains2() { + assertFalse("contains findet element in leerer Liste.", xs.contains("a")); + } + + + @Test + public void testisPrefixOf1() { + xs = of("A","B","C","D","E","F","G"); + ys = of("C","D","E"); + assertFalse("", xs.isPrefixOf(ys)); + assertFalse("", ys.isPrefixOf(xs)); + assertTrue("", ys.isPrefixOf(ys)); + assertTrue("", xs.isPrefixOf(xs)); + } + + @Test + public void testisPrefixOf2() { + xs = LL.of("A","B","C","D","E","F","G"); + ys = LL.of("A","B","C"); + assertTrue("", ys.isPrefixOf(xs)); + assertFalse("", xs.isPrefixOf(ys)); + } + @Test + public void testisPrefixOf3() { + xs = LL.of("A","B","C","D","E","F","G"); + assertTrue("", ys.isPrefixOf(xs)); + assertFalse("", xs.isPrefixOf(ys)); + } + + @Test + public void testisSuffixOf1() { + xs = of("A","B","C","D","E","F","G"); + ys = of("C","D","E"); + assertFalse("", xs.isSuffixOf(ys)); + assertFalse("", ys.isSuffixOf(xs)); + assertTrue("", ys.isSuffixOf(ys)); + assertTrue("", xs.isSuffixOf(xs)); + } + + @Test + public void testisSuffixOf2() { + xs = LL.of("A","B","C","D","E","F","G"); + ys = LL.of("E","F","G"); + assertTrue("", ys.isSuffixOf(xs)); + assertFalse("", xs.isSuffixOf(ys)); + } + @Test + public void testisSuffixOf3() { + xs = LL.of("A","B","C","D","E","F","G"); + assertTrue("", ys.isSuffixOf(xs)); + assertFalse("", xs.isSuffixOf(ys)); + } + + + @Test + public void testisInfixOf1() { + xs = of("A","B","C","D","E","F","G"); + ys = of("C","D","E"); + assertFalse("", xs.isInfixOf(ys)); + assertTrue("", ys.isInfixOf(xs)); + assertTrue("", ys.isInfixOf(ys)); + assertTrue("", xs.isInfixOf(xs)); + } + + @Test + public void testisInfixOf2() { + xs = LL.of("A","B","C","D","E","F","G"); + ys = LL.of("E","F","G"); + assertTrue("", ys.isInfixOf(xs)); + assertFalse("", xs.isInfixOf(ys)); + } + @Test + public void testisInfixOf3() { + xs = LL.of("A","B","C","D","E","F","G"); + assertTrue("", ys.isInfixOf(xs)); + assertFalse("", xs.isInfixOf(ys)); + } + + + + @Test + public void last1() { + xs = LL.of("A","B","C","D","E","F","G"); + assertEquals("","G",xs.last()); + } + + @Test + public void last2() { + xs = LL.of("A"); + assertEquals("","A",xs.last()); + } + + + @Test + public void append1() { + xs = LL.of("A","B","C","D","E","F","G"); + assertEquals("",xs,xs.append(ys)); + assertEquals("",xs,ys.append(xs)); + } + @Test + public void append2() { + xs = LL.of("A","B","C"); + ys = LL.of("D","E","F","G"); + assertEquals("",LL.of("A","B","C","D","E","F","G"),xs.append(ys)); + } + + @Test + public void testDrop1() { + xs = LL.of("A","B","C","D","E","F","G"); + ys = LL.of("C","D","E","F","G"); + assertEquals("falsches Ergebnis für: " + xs + ".drop(2)", ys, xs.drop(2)); + } + + @Test + public void testDropWhile1() { + assertEquals("of(1,2,3,4,1,5,6,7,8,1).dropWhile(x->x<5)", of(5,6,7,8,1), of(1,2,3,4,1,5,6,7,8,1).dropWhile(x->x<5)); + } + @Test + public void testDropWhile2() { + assertEquals("of(1,2,3,4).dropWhile(x->false)", of(1,2,3,4), of(1,2,3,4).dropWhile(x->false)); + } + @Test + public void testDropWhile3() { + assertEquals("of(1,2,3,4).dropWhile(x->true)", of(), of(1,2,3,4).dropWhile(x->true)); + } + + @Test + public void testTakeWhile1() { + assertEquals("of(1,2,3,4,1,5,6,7,8,1).takeWhile(x->x<5)", of(1,2,3,4,1), of(1,2,3,4,1,5,6,7,8,1).takeWhile(x->x<5)); + } + @Test + public void testTakeWhile2() { + assertEquals("of(1,2,3,4).takeWhile(x->false)", of(), of(1,2,3,4).takeWhile(x->false)); + } + @Test + public void testTakeWhile3() { + assertEquals("of(1,2,3,4).takeWhile(x->true)", of(1,2,3,4), of(1,2,3,4).takeWhile(x->true)); + } + + + @Test + public void testDrop2() { + xs = LL.of("A","B","C","D","E","F","G"); + assertEquals("falsches Ergebnis für: " + xs + ".drop(0)", xs, xs.drop(0)); + } + @Test + public void testDrop3() { + xs = LL.of("A","B","C","D","E","F","G"); + assertEquals("falsches Ergebnis für: " + xs + ".drop(10)", ys, xs.drop(10)); + } + + @Test + public void testTake1() { + xs = LL.of("A","B","C","D","E","F","G"); + ys = LL.of("A","B","C"); + assertEquals("falsches Ergebnis für: " + xs + ".take(3)", ys, xs.take(3)); + } + + @Test + public void testTake2() { + xs = LL.of("A","B","C","D","E","F","G"); + assertEquals("falsches Ergebnis für: " + xs + ".take(0)", ys, xs.take(0)); + } + @Test + public void testTake3() { + xs = LL.of("A","B","C","D","E","F","G"); + assertEquals("falsches Ergebnis für: " + xs + ".take(10)", xs, xs.take(10)); + } + + + @Test + public void testSublist1() { + xs = LL.of("A","B","C","D","E","F","G"); + ys = LL.of("C","D","E"); + assertEquals("falsches Ergebnis für: " + xs + ".sublist(2,3)", ys, xs.sublist(2, 3)); + } + + @Test + public void testSublist2() { + assertEquals("falsches Ergebnis für sublist auf leerer Liste", nil(), xs.sublist(2, 4)); + } + + @Test + public void testForEach1() { + xs = LL.of("hallo","welt","hello","illja"); + xs.forEach((x) -> i++); + assertEquals("forEach wird nicht für alle Elemente durchlaufen", 4, i); + } + + @Test + public void testForEach2() { + is.forEach((x) -> i++); + assertEquals("forEach darf für leere Liste nichts machen", 0, i); + } + + @Test + public void testMap1() { + is = LL.of(1,2,3,4); + String isString = is.toString(); + xs = LL.of("1","2","3","4"); + assertEquals(isString + ".map(x -> x.toString()) ist falsch", xs, is.map(x -> x.toString())); + } + + @Test + public void testMap2() { + assertEquals("map auf leerer List ist falsch", nil(), is.map(x -> x + "")); + } + + @Test + public void testMap3() { + is = LL.of(1,2,3,4); + is2 = LL.of(1,4,9,16); + assertEquals("map rechnet falsch", is2, is.map(x->x*x)); + } + + @Test + public void testFilter1() { + is = LL.of(1,2,3,4); + is2 = LL.of(2,4); + String isString = is + ""; + assertEquals(isString + ".filter(x -> x%2 == 0)", is2, is.filter(x -> x % 2 == 0)); + } + + @Test + public void testFilter2() { + xs = LL.of("A","B","C","D","E","F","G"); + // String xsString = xs+""; + assertEquals("Prädikat, das immer false ist, muss leere Liste durch filter erzeugen", nil(), xs.filter(x -> false)); + } + + @Test + public void testFilter3() { + xs = LL.of("A","B","C","D","E","F","G"); + ys = LL.of("A","B","C","D","E","F","G"); + + assertEquals("Prädikat, das immer true ist, muss alle Listenelemente im Ergebnius haben.", ys, + xs.filter(x -> true)); + } + + @Test + public void reverse1() { + xs = LL.of("A","B","C","D","E","F","G"); + ys = LL.of("G","F","E","D","C","B","A"); + assertEquals("reverse geht nicht",ys,xs.reverse()); + } + @Test + public void reverse2() { + assertEquals("reverse geht nicht",ys,xs.reverse()); + } + + + @Test + public void intersperse1() { + assertEquals("intersperse geht nicht",ys,xs.intersperse(" ")); + } + @Test + public void intersperse2() { + assertEquals("intersperse geht nicht",of("A"),of("A").intersperse(" ")); + } + @Test + public void intersperse3() { + assertEquals("intersperse geht nicht",of("A"," ","B"),of("A","B").intersperse(" ")); + } + @Test + public void intersperse4() { + assertEquals("intersperse geht nicht",of(1,42,2,42,3),of(1,2,3).intersperse(42)); + } + + @Test + public void get1() { + assertEquals("get geht nicht",42,of(1,2,3,42,5).get(3).intValue()); + } + @Test + public void get2() { + try{ + assertEquals("get geht nicht",42,of(1,2,3,42,5).get(16).intValue()); + fail("Exception not thrown in get with wrong index"); + }catch(Exception e){ + } + } + @Test + public void get3() { + assertEquals("get geht nicht",1,of(1,2,3,42,5).get(0).intValue()); + } + @Test + public void zip1() { + assertEquals("zip falsch", of(new Pair<>(1, "A"), new Pair<>(2, "B"), new Pair<>(3, "C"), new Pair<>(4, "D")),of(1,2,3,4,5,6).zip(of("A","B","C","D"))); + } + + @Test + public void zip2() { + assertEquals("zip falsch", nil(),of(1,2,3,4,5,6).zip(nil())); + } + @Test + public void zip3() { + assertEquals("zip falsch", nil(),nil().zip(of(1,2,3))); + } + @Test + public void span1() { + assertEquals("span falsch",new Pair<>(of(1,2,3),of(4,5,6,1,2,3)),of(1,2,3,4,5,6,1,2,3).span(x->x<4)); + } + @Test + public void span2() { + assertEquals("span falsch",new Pair<>(of(1,2,3,4,5,6,1,2,3),of()),of(1,2,3,4,5,6,1,2,3).span(x->true)); + } + @Test + public void span3() { + assertEquals("span falsch",new Pair<>(of(),of(1,2,3,4,5,6,1,2,3)),of(1,2,3,4,5,6,1,2,3).span(x->false)); + } + + @Test + public void partition1() { + assertEquals("partition falsch",new Pair<>(of(1,2,3,1,2,3),of(4,5,6)),of(1,2,3,4,5,6,1,2,3).partition(x->x<4)); + } + @Test + public void partition2() { + assertEquals("partition falsch",new Pair<>(of(1,2,3,4,5,6,1,2,3),of()),of(1,2,3,4,5,6,1,2,3).partition(x->true)); + } + @Test + public void partition3() { + assertEquals("partition falsch",new Pair<>(of(),of(1,2,3,4,5,6,1,2,3)),of(1,2,3,4,5,6,1,2,3).partition(x->false)); + } + + @Test + public void isSorted1() { + assertTrue("isSorted",nil().isSorted((x,y)->0)); + assertTrue("isSorted",of(42).isSorted((x,y)->0)); + } + @Test + public void isSorte2() { + assertTrue("isSorted",of(5,24,1,32,999).isSorted((x,y)->0)); + assertTrue("isSorted",of(5,24,1,32,999).isSorted((x,y)->-1)); + assertFalse("isSorted",of(5,24,1,32,999).isSorted((x,y)->x-y)); + } + @Test + public void isSorted3() { + assertTrue("isSorted",of(5,24,111,321,999).isSorted((x,y)->x-y)); + } + @Test + public void qsort1() { + assertEquals("sortieren falsch",of(0, 1, 2, 3, 4, 4, 5, 22, 33, 423, 435, 453, 2345),of(1,2,4,5,435,4,2345,33,3,453,423,22,0).qsort((x,y)->x-y)); + } + @Test + public void qsort2() { + assertEquals("sortieren falsch",nil(),nil().qsort((x,y)->0)); + } + @Test + public void qsort3() { + assertEquals("sortieren falsch",of(2345, 453, 435, 423, 33, 22, 5, 4, 4, 3, 2, 1, 0 ),of(1,2,4,5,435,4,2345,33,3,453,423,22,0).qsort((x,y)->y-x)); + } + + @Test + public void rotate1() { + assertEquals("rotate falsch",of("A"),of("A").rotate()); + } + @Test + public void rotate2() { + assertEquals("rotate falsch",of("B","C","A"),of("A","B","C").rotate()); + } + @Test + public void rotate3() { + assertEquals("rotate falsch",of("A","B"),of("B","A").rotate()); + } + @Test + public void tails1() { + assertEquals("tails falsch",of(nil()),nil().tails()); + } + @Test + public void tails2() { + assertEquals("tails falsch",of(of(1),nil()),of(1).tails()); + } + @Test + public void tails3() { + assertEquals("tails falsch",of(of(1,2),of(2),nil()),of(1,2).tails()); + } + @Test + public void tails4() { + assertEquals("tails falsch",of(of(1,2,3),of(2,3),of(3),nil()),of(1,2,3).tails()); + } + + +} diff --git a/complexityExample/meta.xml b/complexityExample/meta.xml new file mode 100644 index 0000000000000000000000000000000000000000..62be1fda160c11d1dd439d6bfe97d50186a422ea --- /dev/null +++ b/complexityExample/meta.xml @@ -0,0 +1,11 @@ +<task id="complexityExample" lang="Java" attempts="5"> + <name>Ein Record für Date</name> + <evaluator image="registry.gitlab.com/sveneric/subato/executor_java15:1">java15</evaluator> + <description>Schreiben Sie Methoden mit passender Komplexität.</description> + <files> + <file public="true" type="template" path="name/panitz/util/LL.java"/> + <file public="false" type="solution" path="name/panitz/util/LL.java"/> + <file public="false" type="test" path="name/panitz/util/LLTest.java"/> + <file public="false" type="test" path="config.properties"/> + </files> +</task> diff --git a/complexityExample/text/text.html b/complexityExample/text/text.html new file mode 100644 index 0000000000000000000000000000000000000000..7c89b545c5ac0a2a9db0571749025946344396e3 --- /dev/null +++ b/complexityExample/text/text.html @@ -0,0 +1 @@ +<div></div>