From ef89a38de186a336d7eb2ef08a4d164f51a43960 Mon Sep 17 00:00:00 2001 From: Franck Rasolo Date: Wed, 21 Mar 2012 10:27:17 +0000 Subject: [PATCH] Added sequences that helped solve Project Euler problems --- libraries/stdlib/src/sequences/Sequences.kt | 10 +-- .../stdlib/test/sequences/SequenceTest.kt | 48 ++++++------- .../stdlib/test/sequences/SequencesTest.kt | 68 +++++++++++++++++++ 3 files changed, 97 insertions(+), 29 deletions(-) create mode 100644 libraries/stdlib/test/sequences/SequencesTest.kt diff --git a/libraries/stdlib/src/sequences/Sequences.kt b/libraries/stdlib/src/sequences/Sequences.kt index 2a098729179..002c5f0a10e 100644 --- a/libraries/stdlib/src/sequences/Sequences.kt +++ b/libraries/stdlib/src/sequences/Sequences.kt @@ -13,17 +13,17 @@ private fun asSequence(iterator: Iterator) = Sequence { if (iterator.h private fun asSequence(iterator: java.util.Iterator) = Sequence { if (iterator.hasNext()) iterator.next() else null } /** - * Produces the [cartesian square](http://en.wikipedia.org/wiki/Cartesian_product#Cartesian_square_and_Cartesian_power) - * as sequence of order pairs of elements lazily obtained from this range of elements + * Produces the [cartesian product](http://en.wikipedia.org/wiki/Cartesian_product#n-ary_product) as a sequence of ordered pairs of elements lazily obtained + * from two [[Iterable]] instances */ -fun Iterable.cartesianSquare(): Sequence<#(T, T)> { - val first = iterator(); var second = iterator(); var a: T? = null +fun Iterable.times(other: Iterable): Sequence<#(T, T)> { + val first = iterator(); var second = other.iterator(); var a: T? = null fun nextPair(): #(T, T)? { if (a == null && first.hasNext) a = first.next() if (second.hasNext) return #(a.sure(), second.next()) if (first.hasNext) { - a = first.next(); second = iterator() + a = first.next(); second = other.iterator() return #(a.sure(), second.next()) } return null diff --git a/libraries/stdlib/test/sequences/SequenceTest.kt b/libraries/stdlib/test/sequences/SequenceTest.kt index 1e53f7c28c1..9a02bd86b47 100644 --- a/libraries/stdlib/test/sequences/SequenceTest.kt +++ b/libraries/stdlib/test/sequences/SequenceTest.kt @@ -13,13 +13,13 @@ import org.junit.Test class SequenceTest { Test fun filterReturnsTheExpectedSequence() { - val actual = (1..10).asSequence().filter { it % 2 == 0 }.toList() - assertEquals(arrayList(2, 4, 6, 8, 10), actual) + val actual = (1..10).asSequence().filter { it % 2 == 0 } + assertEquals(arrayList(2, 4, 6, 8, 10), actual.toList()) } Test fun filterReturnsAnEmptySequenceWhenNoElementMatchesThePredicate() { - val actual = sequence(1, 3, 4, 7).filter { it > 7 }.toList() - assertEquals(ArrayList(), actual) + val actual = sequence(1, 3, 4, 7).filter { it > 7 } + assertEquals(ArrayList(), actual.toList()) } Test fun foldReturnsTheExpectedReduction() { @@ -34,50 +34,50 @@ class SequenceTest { assertEquals(initialValue, actual) } + private val sum = { (a : Int, b : Int) -> a + b } + Test fun mapReturnsTheExpectedTransformation() { - val actual = sequence(1, 3, 4, 7).map { it * 2 }.toList() - assertEquals(arrayList(2, 6, 8, 14), actual) + val actual = sequence(1, 3, 4, 7).map { it * 2 } + assertEquals(arrayList(2, 6, 8, 14), actual.toList()) } Test fun takeReturnsTheFirstNElements() { - var actual = (1..5).asSequence().take(3).toList() - assertEquals(arrayList(1, 2, 3), actual) + var actual = (1..5).asSequence().take(3) + assertEquals(arrayList(1, 2, 3), actual.toList()) } Test fun takeReturnsTheEntireSequenceWhenTheNumberOfElementsIsGreaterThanItsSize() { - val actual = sequence(1, 2).take(3).toList() - assertEquals(arrayList(1, 2), actual) + val actual = sequence(1, 2).take(3) + assertEquals(arrayList(1, 2), actual.toList()) } Test fun takeReturnsAnEmptySequenceForAnEmptySequence() { - val actual = (1..0).asSequence().take(3).toList() - assertEquals(ArrayList(), actual) + val actual = (1..0).asSequence().take(3) + assertEquals(ArrayList(), actual.toList()) } Test fun takeReturnsAnEmptySequenceWhenTheNumberOfElementsToExtractIsZero() { - val actual = sequence(1, 2).take(0).toList() - assertEquals(ArrayList(), actual) + val actual = sequence(1, 2).take(0) + assertEquals(ArrayList(), actual.toList()) } Test fun takeReturnsAnEmptySequenceWhenTheNumberOfElementsToExtractIsNegative() { - val actual = sequence(1, 2).take(-1).toList() - assertEquals(ArrayList(), actual) + val actual = sequence(1, 2).take(-1) + assertEquals(ArrayList(), actual.toList()) } Test fun takeWhileReturnsTheFirstElementsMatchingAGivenPredicate() { - val actual = sequence(1, 2, 3, 4, 1, 2, 3, 4).takeWhile { it < 3 }.toList() - assertEquals(arrayList(1, 2), actual) + val actual = sequence(1, 2, 3, 4, 1, 2, 3, 4).takeWhile { it < 3 } + assertEquals(arrayList(1, 2), actual.toList()) } Test fun takeWhileReturnsTheEntireSequenceWhenThePredicateMatchesAllElements() { - val actual = sequence(1, 2, 3).takeWhile { it < 9 }.toList() - assertEquals(arrayList(1, 2, 3), actual) + val actual = sequence(1, 2, 3).takeWhile { it < 9 } + assertEquals(arrayList(1, 2, 3), actual.toList()) } Test fun takeWhileReturnsAnEmptySequenceWhenThePredicateMatchesNothing() { - val actual = sequence(1, 2, 3).takeWhile { it < 0 }.toList() - assertEquals(ArrayList(), actual) + val actual = sequence(1, 2, 3).takeWhile { it < 0 } + assertEquals(ArrayList(), actual.toList()) } - - private val sum = { (a : Int, b : Int) -> a + b } } diff --git a/libraries/stdlib/test/sequences/SequencesTest.kt b/libraries/stdlib/test/sequences/SequencesTest.kt new file mode 100644 index 00000000000..8df18129815 --- /dev/null +++ b/libraries/stdlib/test/sequences/SequencesTest.kt @@ -0,0 +1,68 @@ +package test.sequences + +import kotlin.sequences.grouped +import kotlin.sequences.sequence +import kotlin.sequences.sliding +import kotlin.sequences.times +import kotlin.util.arrayList + +import kotlin.test.assertEquals +import org.junit.Test + +class SequencesTest { + + Test fun timesComputesTheCartesianSquareOfAnIterable() { + val actual = (1..3) * (1..3) + val expected = arrayList( + #(1, 1), #(1, 2), #(1, 3), + #(2, 1), #(2, 2), #(2, 3), + #(3, 1), #(3, 2), #(3, 3) + ) + assertEquals(expected, actual.toList()) + } + + Test fun timesComputesTheCartesianProductOfTwoRanges() { + val actual = (1..3) * (4..7) + val expected = arrayList( + #(1, 4), #(1, 5), #(1, 6), #(1, 7), + #(2, 4), #(2, 5), #(2, 6), #(2, 7), + #(3, 4), #(3, 5), #(3, 6), #(3, 7) + ) + assertEquals(expected, actual.toList()) + } + + Test fun timesComputesTheCartesianProductOfTwoIterables() { + val actual = sequence(1, 3, 5, 7) * (4..6) + val expected = arrayList( + #(1, 4), #(1, 5), #(1, 6), + #(3, 4), #(3, 5), #(3, 6), + #(5, 4), #(5, 5), #(5, 6), + #(7, 4), #(7, 5), #(7, 6) + ) + assertEquals(expected, actual.toList()) + } + + Test fun groupedReturnsFixedSizeGroupsOfStrings() { + val digits = """ +62229893423380308135336276614282806444486645238749 +30358907296290491560440772390713810515859307960866 +70172427121883998797908792274921901699720888093776 +65727333001053367881220235421809751254540594752243 +""".trim().replaceAll("\\n", "") + + val actual = digits.grouped(50).toList().get(2) + assertEquals("70172427121883998797908792274921901699720888093776", actual) + } + + Test fun slidingOverALongStringOfDigits() { + val digits = """ +62229893423380308135336276614282806444486645238749 +30358907296290491560440772390713810515859307960866 +70172427121883998797908792274921901699720888093776 +65727333001053367881220235421809751254540594752243 +""".trim().replaceAll("\\n", "") + + val actual = digits.sliding(3).filter { Integer.parseInt(it) > 990 } + assertEquals(arrayList("998", "997"), actual.toList()) + } +}