Last active
February 12, 2017 05:03
-
-
Save geoand/492d6d328c0205cc3a33ab66f50be4c4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fun <T> List<T>.collate(size: Int, step: Int = size): List<List<T>> { | |
require(size >= 0) {"size must not be negative"} | |
require(step <= size) {"step must be at most equal to size"} | |
return collateRec(this, size, step, listOf()) | |
} | |
private tailrec fun <T> collateRec(list : List<T>, size: Int, step: Int, accumulator: List<List<T>>) : List<List<T>> { | |
if(list.isEmpty()) { | |
return accumulator | |
} | |
if(list.size < size) { | |
return accumulator + listOf(list) | |
} | |
return collateRec(list.subList(step, list.size), size, step, accumulator + listOf((list.subList(0, size)))) | |
} | |
//Spec code | |
import org.assertj.core.api.Assertions.assertThat | |
import org.assertj.core.api.Assertions.assertThatExceptionOfType | |
import org.jetbrains.spek.api.Spek | |
class ListCollateSpec : Spek({ | |
fun assertAppropriateExceptionThrown(block: () -> Unit) { | |
assertThatExceptionOfType(IllegalArgumentException::class.java).isThrownBy(block) | |
} | |
describe("List.collate invalid arguments") { | |
val list = (1..12).toList() | |
it("should throw exception because size is negative") { | |
assertAppropriateExceptionThrown { list.collate(-1, 2) } | |
} | |
it("should throw exception because step is larger than size") { | |
assertAppropriateExceptionThrown { list.collate(1, 2) } | |
} | |
it("should throw exception because step is again larger than size") { | |
assertAppropriateExceptionThrown { list.collate(10, 11)} | |
} | |
} | |
describe("List.collate no step cases") { | |
val list = (1..12).toList() | |
it("should return 12 parts of size 1 with no common elements") { | |
val collatedList = list.collate(1) | |
assertThat(collatedList).containsExactly(listOf(1), listOf(2), listOf(3), listOf(4), listOf(5), listOf(6), listOf(7), listOf(8), listOf(9), listOf(10), listOf(11), listOf(12)) | |
} | |
it("should return 6 parts of size 2 with no common elements") { | |
val collatedList = list.collate(2) | |
assertThat(collatedList).containsExactly(listOf(1, 2), listOf(3, 4), listOf(5, 6), listOf(7, 8), listOf(9, 10), listOf(11, 12)) | |
} | |
it("should return 4 parts of size 3 with no common elements") { | |
val collatedList = list.collate(3) | |
assertThat(collatedList).containsExactly(listOf(1, 2, 3), listOf(4, 5, 6), listOf(7, 8, 9), listOf(10, 11, 12)) | |
} | |
it("should return 3 parts of size 4 with no common elements") { | |
val collatedList = list.collate(4) | |
assertThat(collatedList).containsExactly(listOf(1, 2, 3, 4), listOf(5, 6, 7, 8), listOf(9, 10, 11, 12)) | |
} | |
it("should return 2 parts of size 6 with no common elements") { | |
val collatedList = list.collate(6) | |
assertThat(collatedList).containsExactly(listOf(1, 2, 3, 4, 5, 6), listOf(7, 8, 9, 10, 11, 12)) | |
} | |
it("should return 1 part of size 12 with no common elements") { | |
val collatedList = list.collate(12) | |
assertThat(collatedList).containsExactly((1..12).toList()) | |
} | |
it("should return a list where the last item is smaller") { | |
val collatedList = (1..8).toList().collate(3) | |
assertThat(collatedList).containsExactly(listOf(1, 2, 3), listOf(4, 5, 6), listOf(7, 8)) | |
} | |
} | |
describe("List.collate with step cases") { | |
val list = (1..12).toList() | |
it("should return 11 parts of size 2 and a final part of size 1 containing the last element") { | |
val collatedList = list.collate(2, 1) | |
assertThat(collatedList).containsExactly( | |
listOf(1, 2), listOf(2, 3), listOf(3, 4), listOf(4, 5), listOf(5, 6), listOf(6, 7), | |
listOf(7, 8), listOf(8, 9), listOf(9, 10), listOf(10, 11), listOf(11, 12), listOf(12) | |
) | |
} | |
it("should return 3 parts of size 6 and a final part of size 3") { | |
val collatedList = list.collate(6, 3) | |
assertThat(collatedList).containsExactly(listOf(1, 2, 3, 4, 5, 6), listOf(4, 5, 6, 7, 8, 9), listOf(7, 8, 9, 10, 11, 12), listOf(10, 11, 12)) | |
} | |
it("should return on part of size 7 and one of size 6") { | |
val collatedList = list.collate(7, 6) | |
assertThat(collatedList).containsExactly(listOf(1, 2, 3, 4, 5, 6, 7), listOf(7, 8, 9, 10, 11, 12)) | |
} | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment