-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Abhijit Sarkar
committed
Jan 4, 2024
1 parent
f064049
commit 7d89649
Showing
24 changed files
with
341 additions
and
15 deletions.
There are no files selected for viewing
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package list | ||
|
||
// P11 (*) Modified run-length encoding. | ||
// Modify the result of problem P10 in such a way that if an element has no | ||
// duplicates it is simply copied into the result list. Only elements with | ||
// duplicates are transferred as (N, E) terms. | ||
// | ||
// Example: | ||
// scala> encodeModified(List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e)) | ||
// res0: List[Any] = List((4,'a), 'b, (2,'c), (2,'a), 'd, (4,'e)) | ||
|
||
object P11: | ||
|
||
def encodeModified[A](l: List[A]): List[A | (Int, A)] = | ||
P09 | ||
.pack(l) | ||
// size takes O(n) time on lists. | ||
.map(xs => if xs.tail.isEmpty then xs.head else (xs.size, xs.head)) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package list | ||
|
||
// P12 (**) Decode a run-length encoded list. | ||
// Given a run-length code list generated as specified in problem P10, | ||
// construct its uncompressed version. | ||
// | ||
// Example: | ||
// scala> decode(List((4, 'a), (1, 'b), (2, 'c), (2, 'a), (1, 'd), (4, 'e))) | ||
// res0: List[Symbol] = List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e) | ||
|
||
object P12: | ||
|
||
def decode[A](l: List[(Int, A)]): List[A] = | ||
l.flatMap((len, x) => List.fill(len)(x)) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package list | ||
|
||
// P13 (**) Run-length encoding of a list (direct solution). | ||
// Implement the so-called run-length encoding data compression method | ||
// directly. I.e. don't use other methods you've written (like P09's | ||
// pack); do all the work directly. | ||
// | ||
// Example: | ||
// scala> encodeDirect(List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e)) | ||
// res0: List[(Int, Symbol)] = List((4,'a), (1,'b), (2,'c), (2,'a), (1,'d), (4,'e)) | ||
|
||
object P13: | ||
|
||
def encodeDirect[A](l: List[A]): List[(Int, A)] = | ||
l.foldRight(List.empty[(Int, A)]): | ||
case (x, Nil) => List((1, x)) | ||
case (x, acc @ ((_, y) :: _)) if x != y => (1, x) :: acc | ||
case (_, (n, y) :: ys) => (n + 1, y) :: ys |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package list | ||
|
||
// P14 (*) Duplicate the elements of a list. | ||
// Example: | ||
// scala> duplicate(List('a, 'b, 'c, 'c, 'd)) | ||
// res0: List[Symbol] = List('a, 'a, 'b, 'b, 'c, 'c, 'c, 'c, 'd, 'd) | ||
|
||
object P14: | ||
|
||
def duplicate[A](l: List[A]): List[A] = | ||
l.flatMap(x => List(x, x)) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package list | ||
|
||
// P15 (**) Duplicate the elements of a list a given number of times. | ||
// Example: | ||
// scala> duplicateN(3, List('a, 'b, 'c, 'c, 'd)) | ||
// res0: List[Symbol] = List('a, 'a, 'a, 'b, 'b, 'b, 'c, 'c, 'c, 'c, 'c, 'c, 'd, 'd, 'd) | ||
|
||
object P15: | ||
|
||
def duplicateN[A](n: Int, l: List[A]): List[A] = | ||
l.flatMap(x => List.fill(n)(x)) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package list | ||
|
||
// P16 (**) Drop every Nth element from a list. | ||
// Example: | ||
// scala> drop(3, List('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k)) | ||
// res0: List[Symbol] = List('a, 'b, 'd, 'e, 'g, 'h, 'j, 'k) | ||
|
||
object P16: | ||
|
||
def drop[A](n: Int, l: List[A]): List[A] = | ||
// Other ways: | ||
// xs.withFilter(...).map(...) | ||
// for (..) yield | ||
// xs.flatMap(...) | ||
l.zipWithIndex.collect: | ||
case (x, i) if (i + 1) % n != 0 => x |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package list | ||
|
||
// P17 (*) Split a list into two parts. | ||
// The length of the first part is given. Use a Tuple for your result. | ||
// | ||
// Example: | ||
// scala> split(3, List('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k)) | ||
// res0: (List[Symbol], List[Symbol]) = (List('a, 'b, 'c),List('d, 'e, 'f, 'g, 'h, 'i, 'j, 'k)) | ||
object P17: | ||
|
||
def split[A](n: Int, l: List[A]): (List[A], List[A]) = l match | ||
case Nil => (Nil, Nil) | ||
case xs if n == 0 => (Nil, xs) | ||
case x :: xs => | ||
split((n - 1), xs) match | ||
case (left, right) => (x :: left, right) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package list | ||
|
||
// P18 (**) Extract a slice from a list. | ||
// Given two indices, I and K, the slice is the list containing the elements | ||
// from and including the Ith element up to but not including the Kth | ||
// element of the original list. Start counting the elements with 0. | ||
// | ||
// Example: | ||
// scala> slice(3, 7, List('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k)) | ||
// res0: List[Symbol] = List('d, 'e, 'f, 'g) | ||
object P18: | ||
|
||
def slice[A](start: Int, end: Int, l: List[A]): List[A] = | ||
if end < start | ||
then throw new IllegalArgumentException("invalid bounds") | ||
else P17.split(start, l)(1).take(end - start) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package list | ||
|
||
// P19 (**) Rotate a list N places to the left. | ||
// Examples: | ||
// scala> rotate(3, List('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k)) | ||
// res0: List[Symbol] = List('d, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'a, 'b, 'c) | ||
// | ||
// scala> rotate(-2, List('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k)) | ||
// res1: List[Symbol] = List('j, 'k, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i) | ||
|
||
object P19: | ||
|
||
def rotate[A](n: Int, l: List[A]): List[A] = | ||
val k = Math.floorMod(n, l.size) | ||
val (left, right) = P17.split(k, l) | ||
right ++ left |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package list | ||
|
||
// P20 (*) Remove the Kth element from a list. | ||
// Return the list and the removed element in a Tuple. Elements are | ||
// numbered from 0. | ||
// | ||
// Example: | ||
// scala> removeAt(1, List('a, 'b, 'c, 'd)) | ||
// res0: (List[Symbol], Symbol) = (List('a, 'c, 'd),'b) | ||
|
||
object P20: | ||
|
||
def removeAt[A](n: Int, l: List[A]): (List[A], A) = | ||
P17.split(n, l) match | ||
case (_, Nil) => throw new NoSuchElementException("n too large") | ||
case (left, right) => (left ++ right.tail, right.head) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package list | ||
|
||
import munit.ScalaCheckSuite | ||
import org.scalacheck.Prop.forAllNoShrink | ||
import org.scalacheck.Gen | ||
|
||
class P11Suite extends ScalaCheckSuite: | ||
|
||
property("modified run-length encoding"): | ||
forAllNoShrink(Gen.listOf(Gen.choose(1, 5))) { (lst: List[Int]) => | ||
val xs = lst.flatMap(n => List.fill(n)(n)) | ||
val obtained = P11.encodeModified(xs) | ||
val expected = xs | ||
.foldRight(List.empty[(Int, Int)])((x, acc) => | ||
if (acc.isEmpty || acc.head(1) != x) | ||
then (1, x) :: acc | ||
else (acc.head(0) + 1, acc.head(1)) :: acc.tail | ||
) | ||
.map((len, x) => if len == 1 then x else (len, x)) | ||
assertEquals(obtained, expected) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package list | ||
|
||
import munit.ScalaCheckSuite | ||
import org.scalacheck.Prop.forAllNoShrink | ||
import org.scalacheck.Gen | ||
|
||
class P12Suite extends ScalaCheckSuite: | ||
|
||
property("decode run-length encoded list"): | ||
forAllNoShrink(Gen.listOf(Gen.choose(1, 5))) { (lst: List[Int]) => | ||
val xs = lst.map(x => (x, x)) | ||
val obtained = P12.decode(xs) | ||
val expected = lst.flatMap(x => List.fill(x)(x)) | ||
assertEquals(obtained, expected) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package list | ||
|
||
import munit.ScalaCheckSuite | ||
import org.scalacheck.Prop.forAllNoShrink | ||
import org.scalacheck.Gen | ||
|
||
class P13Suite extends ScalaCheckSuite: | ||
|
||
property("run-length encoding direct"): | ||
forAllNoShrink(Gen.listOf(Gen.choose(1, 5))) { (lst: List[Int]) => | ||
val xs = lst.flatMap(n => List.fill(n)(n)) | ||
val obtained = P13.encodeDirect(xs) | ||
val expected = P10.encode(xs) | ||
assertEquals(obtained, expected) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package list | ||
|
||
import munit.ScalaCheckSuite | ||
import org.scalacheck.Prop.forAllNoShrink | ||
import org.scalacheck.Gen | ||
|
||
class P14Suite extends ScalaCheckSuite: | ||
|
||
property("duplicate the elements"): | ||
forAllNoShrink(Gen.listOf(ListGen.genInt)) { (lst: List[Int]) => | ||
val obtained = P14.duplicate(lst) | ||
val expected = lst.flatMap(n => List.fill(2)(n)) | ||
assertEquals(obtained, expected) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package list | ||
|
||
import munit.ScalaCheckSuite | ||
import org.scalacheck.Prop.forAllNoShrink | ||
import org.scalacheck.Gen | ||
import scala.util.Random | ||
|
||
class P15Suite extends ScalaCheckSuite: | ||
|
||
property("duplicate the elements N times"): | ||
forAllNoShrink(Gen.listOf(ListGen.genInt)) { (lst: List[Int]) => | ||
val n = Random.between(1, 5) | ||
val obtained = P15.duplicateN(n, lst) | ||
val expected = lst.flatMap(x => List.fill(n)(x)) | ||
assertEquals(obtained, expected) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package list | ||
|
||
import munit.ScalaCheckSuite | ||
import org.scalacheck.Prop.forAllNoShrink | ||
import org.scalacheck.Gen | ||
import scala.util.Random | ||
|
||
class P16Suite extends ScalaCheckSuite: | ||
|
||
property("drop every Nth element"): | ||
forAllNoShrink(Gen.listOf(ListGen.genInt)) { (lst: List[Int]) => | ||
val n = | ||
if lst.isEmpty | ||
then 0 | ||
else Random.between(1, lst.size + 1) | ||
val obtained = P16.drop(n, lst) | ||
// guard in for-comprehension is sugar for withFilter. | ||
val expected = for ((x, i) <- lst.zipWithIndex if (i + 1) % n != 0) yield x | ||
assertEquals(obtained, expected) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package list | ||
|
||
import munit.ScalaCheckSuite | ||
import org.scalacheck.Prop.forAllNoShrink | ||
import org.scalacheck.Gen | ||
import scala.util.Random | ||
|
||
class P17Suite extends ScalaCheckSuite: | ||
|
||
property("split a list into two parts"): | ||
forAllNoShrink(Gen.listOf(ListGen.genInt)) { (lst: List[Int]) => | ||
val n = | ||
if lst.isEmpty | ||
then 0 | ||
else Random.between(1, lst.size + 1) | ||
val obtained = P17.split(n, lst) | ||
val expected = lst.splitAt(n) | ||
assertEquals(obtained, expected) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package list | ||
|
||
import munit.ScalaCheckSuite | ||
import org.scalacheck.Prop.forAllNoShrink | ||
import org.scalacheck.Gen | ||
import scala.util.Random | ||
|
||
class P18Suite extends ScalaCheckSuite: | ||
|
||
property("extract a slice"): | ||
forAllNoShrink(Gen.listOf(ListGen.genInt)) { (lst: List[Int]) => | ||
val end = | ||
if lst.isEmpty | ||
then 0 | ||
else Random.between(1, lst.size + 1) | ||
val start = if end == 0 then 0 else Random.between(0, end) | ||
val obtained = P18.slice(start, end, lst) | ||
val expected = lst.splitAt(start)._2.take(end - start) | ||
assertEquals(obtained, expected, s"start=${start}, end=${end}") | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package list | ||
|
||
import munit.FunSuite | ||
|
||
class P19Suite extends FunSuite: | ||
|
||
test("rotate a list N places to the left"): | ||
val xs = ('a' to 'k').toList | ||
val obtained1 = P19.rotate(3, xs) | ||
val expected1 = List('d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'a', 'b', 'c') | ||
assertEquals(obtained1, expected1) | ||
|
||
val obtained2 = P19.rotate(-2, xs) | ||
val expected2 = List('j', 'k', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i') | ||
assertEquals(obtained2, expected2) |
Oops, something went wrong.