summaryrefslogtreecommitdiff
path: root/Homework/cs4700/kotlin/Lists.kt
diff options
context:
space:
mode:
authorElizabeth Alexander Hunt <me@liz.coffee>2026-07-02 11:55:17 -0700
committerElizabeth Alexander Hunt <me@liz.coffee>2026-07-02 11:55:17 -0700
commit6bf4b90c90f15f4ab60833bddf5b5756d1a6b1f6 (patch)
treeed97e39ec77c5231ffd2c394493e68d00ddac5a4 /Homework/cs4700/kotlin/Lists.kt
downloadmisc-undergrad-main.tar.gz
misc-undergrad-main.zip
Diffstat (limited to 'Homework/cs4700/kotlin/Lists.kt')
-rw-r--r--Homework/cs4700/kotlin/Lists.kt154
1 files changed, 154 insertions, 0 deletions
diff --git a/Homework/cs4700/kotlin/Lists.kt b/Homework/cs4700/kotlin/Lists.kt
new file mode 100644
index 0000000..2839b8c
--- /dev/null
+++ b/Homework/cs4700/kotlin/Lists.kt
@@ -0,0 +1,154 @@
+// Do not remove or rename the package
+package lists
+
+/*
+* The following functions are helper functions that I am providing
+*/
+
+/*
+* Extend the List class with a "tail" getter to get the tail of a list.
+* Below is an example of how you would use tail
+* val a = listOf(1,2,3)
+* val t = a.tail
+* println("tail of $a is $t") // prints [2,3]
+*/
+val <T> List<T>.tail: List<T>
+get() = drop(1)
+
+/*
+* Extend the List class with a "head" getter to get the head of a list.
+* Below is an example of how you would use head
+* val a = listOf(1,2,3)
+* val h = a.head
+* println("head of $a is $h") // prints 1
+*/
+val <T> List<T>.head: T
+get() = first()
+
+/*
+* The isPrime function takes as input an Int
+* x : an Int object to test
+* and returns a Boolean
+* true if x is a prime
+* false if x is not a prime
+*/
+fun isPrime(x : Int) : Boolean {
+ if (x == 1)
+ return false
+ for (i in 2..(x-1)) {
+ if (x % i == 0) {
+ return false
+ }
+ }
+ return true
+}
+
+/* The compose function takes as input
+* f - A function that takes as input a value of type T and returns a value of type T
+* g - A function that takes as input a value of type T and returns a value of type T
+* and returns as output the composition of the functions
+* f(g(x))
+*/
+fun<T> compose(f: (T)->T, g:(T) -> T) : (T) -> T = { f(g(it)) }
+
+/* Be sure to document
+ your functions
+ describing inputs and outputs and what the function does
+ */
+
+/**
+ * @param limit is the upper bound of the list of natural numbers
+ * @return a list of natural numbers up to limit
+ */
+fun countingNumbers(limit : Int?) : List<Int>? {
+ if (limit == null)
+ return null
+ return (1..limit).map { it }
+}
+
+/**
+ * @param limit is the upper bound of the list of even numbers
+ * @return a list of even numbers up to limit
+ */
+fun evenNumbers(limit : Int?) : List<Int>? {
+ return countingNumbers(limit)?.filter( { it % 2 == 0 } )
+}
+
+/**
+ * @param limit is the upper bound of the list of prime numbers
+ * @return a list of prime numbers up to limit
+ */
+fun primeNumbers(limit : Int?) : List<Int>? {
+ return countingNumbers(limit)?.filter( { isPrime(it) } )
+}
+
+/**
+ * @param a is a null-safe list of elements of "Comparable" items
+ * @param b is a null-safe list of elements of "Comparable" items
+ * @return a sorted merge list of the elements of a and b
+ */
+fun<T: Comparable<T>> merge(a: List<T>?, b: List<T>?) : List<T>? {
+ if (a == null || b == null)
+ return null
+
+ val merged = mutableListOf<T>()
+
+ var aInd = 0
+ var bInd = 0
+
+ while (aInd < a.size && bInd < b.size) {
+ if (a[aInd] < b[bInd]) {
+ merged.add(a[aInd]);
+ aInd++;
+ continue;
+ }
+ merged.add(b[bInd]);
+ bInd++;
+ }
+
+ if (aInd < a.size)
+ merged += a.subList(aInd, a.size)
+
+ else if (bInd < b.size)
+ merged += b.subList(bInd, b.size)
+
+ return merged
+}
+
+/**
+ * @param a is a null-safe list of elements
+ * @return a list of "sublists" where result[i] = a[0..i]
+ */
+fun <T> subLists(a: List<T>?) : List<List<T>>? {
+ if (a == null)
+ return null
+ return (1..(a.size)).map( { a.subList(0, it) } )
+}
+
+/**
+ * @param a is a null-safe list of lists of elements
+ * @return the number of elements total in each sublist
+ */
+fun countElements(a: List<List<Any>? >?) : Int? {
+ if (a == null)
+ return a
+ return a.filter({ it != null }).fold(0, { acc, x -> acc + x!!.size })
+}
+
+/**
+ * @param a is a null-safe list of lists of elements
+ * @return the number of elements total in each sublist
+ */
+fun <T> listApply(f: (T, T) -> T, a: List<List<T>>?): List<T>? {
+ if (a == null)
+ return null
+ return a.map( { l: List<T> -> l.foldIndexed( l[0], { index, acc, arg -> if (index > 0) f(acc, arg) else arg } ) } );
+}
+
+/**
+ * @param a is a list of functions
+ * @return a function that the composition of the list of functions (from right to left)
+ */
+fun <T> composeList(a: List<(T) -> T>): (T) -> T {
+ return a.foldRight({ x -> x }, { acc, f: (T) -> T -> { x -> f(acc(x)) } });
+}