1
1
Fork 0

Added new solutions for the last sections

This commit is contained in:
Svetlana Isakova 2020-09-27 00:27:15 +02:00
parent 296d6e3fe0
commit 334cf23a9c
291 changed files with 3671 additions and 1845 deletions

View File

@ -1,38 +1,4 @@
## Type Checking (#1)
Modify `TypeCheck3.kt` by moving `rotate()` into `Shape` and returning `Shape`
to an `interface`. Notice how `turn()` becomes much cleaner.
> Solution 1
```kotlin
// TypeChecking/TypeCheckingSoln1.kt
package typecheckingsoln1
import atomictest.eq
import typechecking.name
interface Shape {
fun draw() = "${this.name}: Draw"
fun rotate() = ""
}
class Circle : Shape
class Square : Shape {
override fun rotate() = "Square: Rotate"
}
class Triangle : Shape {
override fun rotate() = "Triangle: Rotate"
}
fun turn(s: Shape) = s.rotate()
fun main() {
val shapes = listOf(Circle(), Square())
shapes.map { it.draw() } eq
"[Circle: Draw, Square: Draw]"
shapes.map { turn(it) } eq
"[, Square: Rotate]"
}
```
to an `interface`. Notice how `turn()` becomes much cleaner.

View File

@ -1,10 +1,10 @@
package typeCheckingExercise1
import org.junit.Assert
import org.junit.Test
import util.unimplementedTest
class TestTypeCheckingExercise1 {
@Test fun testSolution() {
Assert.assertTrue("Tests not implemented for the task", false)
unimplementedTest()
}
}

View File

@ -4,135 +4,4 @@ Add a `DecomposableBottle` to both `BeverageContainer2.kt` (remove `recycle()`)
and `BeverageContainer3.kt`. `DecomposableBottle`'s recycling `String` is
"Decomposition tank".
Notice the different experience between the two examples.
> Solution 2a
```kotlin
// TypeChecking/TypeCheckingSoln2a.kt
package typecheckingsoln2a
import atomictest.eq
sealed class BeverageContainer {
abstract fun open(): String
abstract fun pour(): String
}
sealed class Can : BeverageContainer() {
override fun open() = "Pop Top"
override fun pour() = "Can: Pour"
}
class SteelCan : Can()
class AluminumCan : Can()
sealed class Bottle : BeverageContainer() {
override fun open() = "Remove Cap"
override fun pour() = "Bottle: Pour"
}
class GlassBottle : Bottle()
sealed class PlasticBottle : Bottle()
class PETBottle : PlasticBottle()
class HDPEBottle : PlasticBottle()
class DecomposableBottle : PlasticBottle()
fun BeverageContainer.recycle2() =
when(this) {
is Can -> when(this) {
is SteelCan -> "Recycle Steel"
is AluminumCan -> "Recycle Aluminum"
}
is Bottle -> when(this) {
is GlassBottle -> "Recycle Glass"
is PlasticBottle -> when(this) {
is PETBottle -> "Recycle PET"
is HDPEBottle -> "Recycle HDPE"
is DecomposableBottle -> "Decomposition tank"
}
}
}
fun main() {
val refrigerator = listOf(
SteelCan(), AluminumCan(),
GlassBottle(),
PETBottle(), HDPEBottle(),
DecomposableBottle()
)
refrigerator.map { it.open() } eq
"[Pop Top, Pop Top, Remove Cap, " +
"Remove Cap, Remove Cap, Remove Cap]"
refrigerator.map { it.recycle2() } eq
"[Recycle Steel, Recycle Aluminum, " +
"Recycle Glass, " +
"Recycle PET, Recycle HDPE, " +
"Decomposition tank]"
}
```
> Solution 2b
```kotlin
// TypeChecking/TypeCheckingSoln2b.kt
package typecheckingsoln2b
import atomictest.eq
import typechecking.name
interface BeverageContainer {
fun open(): String
fun pour() = "${this.name}: Pour"
fun recycle(): String
}
abstract class Can : BeverageContainer {
override fun open() = "Pop Top"
}
class SteelCan : Can() {
override fun recycle() = "Recycle Steel"
}
class AluminumCan : Can() {
override fun recycle() = "Recycle Aluminum"
}
abstract class Bottle : BeverageContainer {
override fun open() = "Remove Cap"
}
class GlassBottle : Bottle() {
override fun recycle() = "Recycle Glass"
}
abstract class PlasticBottle : Bottle()
class PETBottle : PlasticBottle() {
override fun recycle() = "Recycle PET"
}
class HDPEBottle : PlasticBottle() {
override fun recycle() = "Recycle HDPE"
}
class DecomposableBottle : PlasticBottle() {
override fun recycle() = "Decomposition tank"
}
fun main() {
val refrigerator = listOf(
SteelCan(), AluminumCan(),
GlassBottle(),
PETBottle(), HDPEBottle(),
DecomposableBottle()
)
refrigerator.map { it.open() } eq
"[Pop Top, Pop Top, Remove Cap, " +
"Remove Cap, Remove Cap, Remove Cap]"
refrigerator.map { it.recycle() } eq
"[Recycle Steel, Recycle Aluminum, " +
"Recycle Glass, " +
"Recycle PET, Recycle HDPE, " +
"Decomposition tank]"
}
```
Notice the different experience between the two examples.

View File

@ -1,10 +1,10 @@
package typeCheckingExercise2
import org.junit.Assert
import org.junit.Test
import util.unimplementedTest
class TestTypeCheckingExercise2 {
@Test fun testSolution() {
Assert.assertTrue("Tests not implemented for the task", false)
unimplementedTest()
}
}

View File

@ -5,73 +5,4 @@ modifications to other components). Change `basic()` to use a `when`
expression.
What does this gain you, since the `else` clauses in the `when` expressions
still make sense?
> Solution 3
```kotlin
// TypeChecking/TypeCheckingSoln3.kt
package typecheckingsoln3
import atomictest.eq
import typechecking.name
sealed class Insect {
open fun walk() = "${this.name}: walk"
open fun fly() = "${this.name}: fly"
}
class HouseFly : Insect()
class Flea : Insect() {
override fun fly() =
throw Exception("Flea cannot fly")
fun crawl() = "Flea: crawl"
}
fun Insect.basic() =
this.walk() + " " +
when(this) {
is Flea -> this.crawl()
else -> this.fly()
}
interface SwimmingInsect {
fun swim() = "${this.name}: swim"
}
interface WaterWalker {
fun walkWater() =
"${this.name}: walk on water"
}
class WaterBeetle : Insect(), SwimmingInsect
class WaterStrider : Insect(), WaterWalker
class WhirligigBeetle : Insect(),
SwimmingInsect, WaterWalker
fun Insect.water() =
when(this) {
is SwimmingInsect -> this.swim()
is WaterWalker -> this.walkWater()
else -> "${this.name}: drown"
}
fun main() {
val insects = listOf(
HouseFly(), Flea(), WaterStrider(),
WaterBeetle(), WhirligigBeetle()
)
insects.map { it.basic() } eq
"[HouseFly: walk HouseFly: fly, " +
"Flea: walk Flea: crawl, " +
"WaterStrider: walk WaterStrider: fly, " +
"WaterBeetle: walk WaterBeetle: fly, " +
"WhirligigBeetle: walk " +
"WhirligigBeetle: fly]"
insects.map { it.water() } eq
"[HouseFly: drown, Flea: drown, " +
"WaterStrider: walk on water, " +
"WaterBeetle: swim, " +
"WhirligigBeetle: swim]"
}
```
still make sense?

View File

@ -1,10 +1,10 @@
package typeCheckingExercise3
import org.junit.Assert
import org.junit.Test
import util.unimplementedTest
class TestTypeCheckingExercise3 {
@Test fun testSolution() {
Assert.assertTrue("Tests not implemented for the task", false)
unimplementedTest()
}
}

View File

@ -0,0 +1,23 @@
// CreatingGenerics/CreatingGenericsSoln1.kt
package creatingGenericsExercise1
import atomictest.eq
fun interface Items<T> {
fun next(): T?
}
fun <T> itemIter(vararg items: T): Items<T> {
var index = 0
return Items {
if (index >= items.size) null
else items[index++]
}
}
fun main() {
val s = itemIter("A", "B", "C")
(0..3).map { s.next() } eq "[A, B, C, null]"
val i = itemIter(1, 2, 3, 4, 5, 6, 7)
(0..10).mapNotNull { i.next() } eq
"[1, 2, 3, 4, 5, 6, 7]"
}

View File

@ -0,0 +1,6 @@
type: edu
files:
- name: src/Task.kt
visible: true
- name: test/Tests.kt
visible: false

View File

@ -0,0 +1,14 @@
## Creating Generics (#1)
Create a generic interface called `Items` with a single function `next()` that
returns an object of the generic type, or `null`. Make `Items` usable for
[SAM conversions](#sam-conversions).
Create a generic function called `itemIter()` that takes a `vararg items` of
the type parameter and returns an `Items` object produced with a SAM
conversion. The `Items` object closes over a `var index` to indicate the
current element in `items`. Each call to `next()` produces the current element
and increments `index`. When there are no more `items`, `next()` returns
`null`.
The code in `main()` tests your solution.

View File

@ -0,0 +1,10 @@
package creatingGenericsExercise1
import org.junit.Test
import util.unimplementedTest
class TestCreatingGenericsExercise1 {
@Test fun testSolution() {
unimplementedTest()
}
}

View File

@ -0,0 +1,27 @@
// CreatingGenerics/CreatingGenericsSoln2.kt
package creatingGenericsExercise2
import creatinggenerics.Crate
import atomictest.eq
class CrateList<T> : ArrayList<Crate<T>>() {
private class
DecoratedCrate<T>(contents: T) :
Crate<T>(contents) {
override fun toString() = "[${get()}]"
}
fun add(item: T) {
add(DecoratedCrate(item))
}
}
fun main() {
val intCrates = CrateList<Int>()
(0..7).forEach { intCrates.add(it) }
intCrates eq
"[[0], [1], [2], [3], [4], [5], [6], [7]]"
val stringCrates = CrateList<String>()
('a'..'h').map { it.toString() }
.forEach { stringCrates.add(it) }
stringCrates eq
"[[a], [b], [c], [d], [e], [f], [g], [h]]"
}

View File

@ -0,0 +1,6 @@
type: edu
files:
- name: src/Task.kt
visible: true
- name: test/Tests.kt
visible: false

View File

@ -0,0 +1,12 @@
## Creating Generics (#2)
Create a generic class `CrateList` that inherits from an `ArrayList` of
`Crate`. `Crate` has no `toString()`. To solve this problem, create a nested
`private` class called `DecoratedCrate` that takes a generic argument of
`contents` and inherits from `Crate`. Add a `toString()` to `DecoratedCrate`
that produces a `String` consisting of the result of calling `get()` inside
square brackets.
Define a member function `add()` that takes a generic `item` argument, creates
a `DecoratedCrate` with it and adds the result to the `ArrayList`. The code in
`main()` tests your solution.

View File

@ -0,0 +1,10 @@
package creatingGenericsExercise2
import org.junit.Test
import util.unimplementedTest
class TestCreatingGenericsExercise2 {
@Test fun testSolution() {
unimplementedTest()
}
}

View File

@ -0,0 +1,27 @@
// CreatingGenerics/CreatingGenericsSoln3.kt
package creatingGenericsExercise3
import creatinggenerics.Can
import creatinggenerics.Grape
interface InCrate<in T> {
fun put(item: T)
}
interface OutCrate<out T> {
fun get(): T
}
class Crate<T>(private var contents: T) :
InCrate<T>, OutCrate<T> {
override fun put(item: T) {
contents = item
}
override fun get(): T = contents
}
fun main() {
val cg: Crate<Grape> = Crate(Grape())
val oc: OutCrate<Can> = cg
val cc: Crate<Can> = Crate(Can())
val ic: InCrate<Grape> = cc
}

View File

@ -0,0 +1,6 @@
type: edu
files:
- name: src/Task.kt
visible: true
- name: test/Tests.kt
visible: false

View File

@ -0,0 +1,6 @@
## Creating Generics (#3)
Convert `InCrate` and `OutCrate` to interfaces. Create a new version of `Crate`
that implements both `InCrate` and `OutCrate`. The code in `main()` tests your
solution by upcasting from `Crate<Grape>` to `OutCrate<Can>` and from
`Crate<Can>` to `InCrate<Grape>`.

View File

@ -0,0 +1,10 @@
package creatingGenericsExercise3
import org.junit.Test
import util.unimplementedTest
class TestCreatingGenericsExercise3 {
@Test fun testSolution() {
unimplementedTest()
}
}

View File

@ -1,2 +1,5 @@
content:
- Examples
- Exercise 1
- Exercise 2
- Exercise 3

View File

@ -0,0 +1,51 @@
// ExtensionLambdas/ExtensionLambdasSoln1.kt
package extensionLambdasExercise1
import atomictest.eq
import kotlinx.collections.immutable.*
fun createString(
build: StringBuilder.() -> Unit
): String {
val sb = StringBuilder()
sb.build()
return sb.toString()
}
fun <T> createList(
build: ArrayList<T>.() -> Unit
): List<T> {
val list = ArrayList<T>()
list.build()
return list.toImmutableList()
}
fun <K, V> createMap(
build: HashMap<K, V>.() -> Unit
): Map<K, V> {
val map = HashMap<K, V>()
map.build()
return map.toImmutableMap()
}
@OptIn(ExperimentalStdlibApi::class)
fun main() {
createString {
(1..10).forEach { append(it) }
} eq buildString {
(1..10).forEach { append(it) }
}
createList<String> {
(1..10).forEach { add(it.toString()) }
} eq buildList {
(1..10).forEach { add(it.toString()) }
}
createMap<Char, Int> {
('a'..'j').forEachIndexed { n, c ->
put(c, n)
}
} eq buildMap {
('a'..'j').forEachIndexed { n, c ->
put(c, n)
}
}
}

View File

@ -0,0 +1,6 @@
type: edu
files:
- name: src/Task.kt
visible: true
- name: test/Tests.kt
visible: false

View File

@ -0,0 +1,20 @@
## Extension Lambdas (#1)
Define the following functions so they behave the same as their standard
library counterparts:
- `createString()` behaves like `buildString()`. Start by creating a new
instance of `StringBuilder`, call the extension lambda argument on it, then
return the `String` result.
- `createList()` behaves like `buildList()`. This function has one generic
parameter. Create an `ArrayList<T>`, call the extension lambda argument on it,
and return the `List` in immutable form.
- `createMap()` behaves like `buildMap()`. This function has two generic
parameters. Create a `HashMap<K, V>`, call the extension lambda argument on it,
and return the `Map` in immutable form.
The code in `main()` tests your functions against the standard library
versions. Notice that `buildList()` and `buildMap()` infer their generic
parameters.

View File

@ -0,0 +1,10 @@
package extensionLambdasExercise1
import org.junit.Test
import util.unimplementedTest
class TestExtensionLambdasExercise1 {
@Test fun testSolution() {
unimplementedTest()
}
}

View File

@ -0,0 +1,49 @@
// ExtensionLambdas/ExtensionLambdasSoln2.kt
package extensionLambdasExercise2
import sandwich.*
import atomictest.eq
fun sandwich2(
prepare: Sandwich.() -> Unit = { this },
fillings: Sandwich.() -> Unit
): Sandwich {
val sandwich = Sandwich()
sandwich.prepare()
sandwich.fillings()
return sandwich
}
fun Sandwich.sandwich3(
fillings: Sandwich.() -> Unit
): Sandwich {
fillings()
return this
}
val PBJ1 = sandwich2 {
add(PeanutButter())
add(GrapeJelly())
}
val PBJ2 = sandwich2({ toast() }) {
add(PeanutButter())
add(GrapeJelly())
}
val PBJ3 = Sandwich().toast().sandwich3 {
add(PeanutButter())
add(GrapeJelly())
}
val PBJ4 = Sandwich().toast().sandwich3 {
add(PeanutButter())
add(GrapeJelly())
}.grill()
fun main() {
PBJ1 eq "[PeanutButter, GrapeJelly]"
PBJ2 eq "[Toast, PeanutButter, GrapeJelly]"
PBJ3 eq "[Toast, PeanutButter, GrapeJelly]"
PBJ4 eq
"[Toast, PeanutButter, GrapeJelly, Grill]"
}

View File

@ -0,0 +1,6 @@
type: edu
files:
- name: src/Task.kt
visible: true
- name: test/Tests.kt
visible: false

View File

@ -0,0 +1,11 @@
## Extension Lambdas (#2)
Import `sandwich.*` and create a function `sandwich2()` following the example
of `sandwich()`. Insert a first parameter `prepare`, which is an extension
lambda that allows the user to choose whether to toast the `Sandwich`, with the
default untoasted.
Add a function `sandwich3()` which is an extension function for `Sandwich`. The
user can provide a `Sandwich` receiver that may or may not be already toasted.
The starter code and the code in `main()` tests your functions.

View File

@ -0,0 +1,10 @@
package extensionLambdasExercise2
import org.junit.Test
import util.unimplementedTest
class TestExtensionLambdasExercise2 {
@Test fun testSolution() {
unimplementedTest()
}
}

View File

@ -0,0 +1,60 @@
// ExtensionLambdas/ExtensionLambdasSoln3.kt
package extensionLambdasExercise3
import atomictest.eq
open class Cleanser : ArrayList<String>() {
fun selectContainer() {
add("Container selected")
}
fun sealContainer() {
add("Container sealed")
}
fun detergent() { add("detergent") }
fun abrasive() { add("abrasive") }
fun ammonia() { add("ammonia") }
fun water() { add("water") }
}
class SprayCleanser : Cleanser() {
fun selectSprayer() {
add("Sprayer selected")
}
}
fun cleanser(
formula: Cleanser.() -> Unit
): Cleanser {
val result = Cleanser()
result.selectContainer()
result.formula()
result.sealContainer()
return result
}
fun sprayCleanser(
formula: SprayCleanser.() -> Unit
): SprayCleanser {
val result = SprayCleanser()
result.selectContainer()
result.selectSprayer()
result.formula()
result.sealContainer()
return result
}
fun main() {
val c: Cleanser = cleanser {
detergent()
abrasive()
}
c eq "[Container selected, detergent, " +
"abrasive, Container sealed]"
val sc: SprayCleanser = sprayCleanser {
detergent()
ammonia()
water()
}
sc eq "[Container selected, " +
"Sprayer selected, detergent, " +
"ammonia, water, Container sealed]"
}

View File

@ -0,0 +1,6 @@
type: edu
files:
- name: src/Task.kt
visible: true
- name: test/Tests.kt
visible: false

View File

@ -0,0 +1,5 @@
## Extension Lambdas (#3)
The starter code contains definitions for `class Cleanser` and `class
SprayCleanser`. Write the functions `cleanser()` and `sprayCleanser()` so the
code in `main()` works correctly.

View File

@ -0,0 +1,10 @@
package extensionLambdasExercise3
import org.junit.Test
import util.unimplementedTest
class TestExtensionLambdasExercise3 {
@Test fun testSolution() {
unimplementedTest()
}
}

View File

@ -1,2 +1,5 @@
content:
- Examples
- Exercise 1
- Exercise 2
- Exercise 3

View File

@ -1,24 +0,0 @@
// Hashing/EasyKeys.kt
package hashing
import atomictest.eq
data class Employee(
val first: String,
val last: String, val id: Int
)
fun main() {
val employees = HashSet(setOf(
Employee("Lucia", "Dubois", 1),
Employee("Bob", "Dobbs", 2),
Employee("Ilsa", "Schmidt", 3)))
employees.joinToString(separator = "\n") eq
"""
Employee(first=Bob, last=Dobbs, id=2)
Employee(first=Lucia, last=Dubois, id=1)
Employee(first=Ilsa, last=Schmidt, id=3)
""".trimIndent()
(Employee("Ilsa", "Schmidt", 3)
in employees) eq true
}

View File

@ -1,23 +0,0 @@
// Hashing/HashCodeFailure.kt
import atomictest.*
class NotDataClass(id: String)
data class DataClass(val id: String)
fun main() {
val key = NotDataClass("A")
val key2 = NotDataClass("A")
key.hashCode() neq key2.hashCode() // [1]
key.equals(key2) eq false // [2]
val hm = hashMapOf(key to "Hello")
hm[key] eq "Hello"
hm[key2] eq null // [3]
val dckey = DataClass("A")
val dckey2 = DataClass("A")
dckey.hashCode() eq dckey2.hashCode() // [4]
dckey.equals(dckey2) eq true // [5]
val hmdc = hashMapOf(dckey to "Hello")
hmdc[dckey] eq "Hello"
hmdc[dckey2] eq "Hello" // [6]
}

View File

@ -1,16 +0,0 @@
// Hashing/KeyFailure.kt
package hashing
import atomictest.eq
data class Key(var id: String)
fun main() {
val key = Key("A")
val hm = hashMapOf(key to "Hello")
hm eq "{Key(id=A)=Hello}"
hm[key] eq "Hello" // [1]
key.id = "Goodbye"
hm eq "{Key(id=Goodbye)=Hello}"
hm[key] eq null // [2]
}

View File

@ -1,49 +0,0 @@
// Hashing/Pets.kt
package hashing
import atomictest.eq
interface Pet {
companion object {
var n = 0
fun next() = n++
}
}
data class Cat(
val name: String,
val id: Int = Pet.next()
) : Pet
data class Dog(
val name: String,
val id: Int = Pet.next()
) : Pet
data class Rat(
val name: String,
val id: Int = Pet.next()
) : Pet
fun main() {
val pets = HashSet(setOf(
Cat("Elsie"),
Dog("Rufus"),
Rat("Fizzy"),
Cat("Stanford"),
Rat("Freckly"),
Rat("Fuzzy")))
pets.joinToString(separator = "\n") eq
"""
Cat(name=Stanford, id=3)
Rat(name=Freckly, id=4)
Rat(name=Fuzzy, id=5)
Rat(name=Fizzy, id=2)
Cat(name=Elsie, id=0)
Dog(name=Rufus, id=1)
""".trimIndent()
(pets.first() in pets) eq true
(Dog("Pugsly") in pets) eq false
// Because each object has a unique id:
(Dog("Rufus") in pets) eq false
}

View File

@ -1,22 +0,0 @@
// Hashing/SimpleHashing.kt
import atomictest.eq
fun main() {
val keys = 'A'..'z'
val hm = HashMap(
keys.associate { it to keys.indexOf(it) })
hm['Z'] eq 25
hm['x'] = 42
hm['x'] eq 42
val items = 'A'..'F'
val hs = HashSet(
items + items + items + items + items
)
hs eq "[A, B, C, D, E, F]"
('C' in hs) eq true
('c' in hs) eq false
hs.containsAll(('B'..'D').toSet()) eq true
hs.intersect(('D'..'Z').toSet()) eq
"[D, E, F]"
}

View File

@ -1,6 +0,0 @@
// Hashing/StringHashCode.kt
import atomictest.eq
fun main() {
"Hello".hashCode() eq "Hello".hashCode();
}

View File

@ -1,8 +0,0 @@
// Hashing/UnpredictableHashing.kt
import atomictest.eq
fun main() {
"Hash order is unpredictable".toHashSet() eq
"[H, , a, b, c, d, e, h, i, " +
"l, n, o, p, r, s, t, u]"
}

View File

@ -1,16 +0,0 @@
type: theory
files:
- name: src/SimpleHashing.kt
visible: true
- name: src/UnpredictableHashing.kt
visible: true
- name: src/Pets.kt
visible: true
- name: src/KeyFailure.kt
visible: true
- name: src/HashCodeFailure.kt
visible: true
- name: src/StringHashCode.kt
visible: true
- name: src/EasyKeys.kt
visible: true

View File

@ -1,2 +0,0 @@
id: 1305811
update_date: Tue, 12 May 2020 16:26:34 UTC

View File

@ -1,4 +0,0 @@
## Hashing
Examples accompanying the atom.
[Read "Hashing" atom online.](https://stepik.org/lesson/350555/step/1)

View File

@ -1,22 +0,0 @@
package hashingExercise1
data class Contact(
val name: String,
val number: String
)
class Person(val name: String)
fun main() {
val set1 = setOf(
Person("Alice"),
Person("Alice"))
val set2 = setOf(
Contact("Alice", "123-456"),
Contact("Alice", "123-456"))
set1.size // 1 or 2? Write you guess below.
set2.size // 1 or 2? Write you guess below.
}
fun getSet1Size(): Int = 2
fun getSet2Size(): Int = 1

View File

@ -1,15 +0,0 @@
type: edu
files:
- name: src/Task.kt
visible: true
placeholders:
- offset: 405
length: 1
placeholder_text: TODO()
- offset: 432
length: 1
placeholder_text: TODO()
- name: test/Tests.kt
visible: false
feedback_link: |
https://docs.google.com/forms/d/e/1FAIpQLSdkaliSwYkjiV21bZl0yP-In2g5p17sAQCfaGjyHx_QYMWTiQ/viewform?usp=pp_url&entry.189755027=Usability+%2F+Data+Classes+%2F+Exercise1

View File

@ -1,2 +0,0 @@
id: 1305812
update_date: Tue, 12 May 2020 16:26:35 UTC

View File

@ -1,26 +0,0 @@
## Hashing (#1)
Test your understanding of how `Set`s store instances of data classes. Guess the
size of `Set`s `set1` and `set2` in the following code:
```kotlin
data class Contact(
val name: String,
val number: String
)
class Person(val name: String)
fun main() {
val set1 = setOf(
Person("Alice"),
Person("Alice"))
val set2 = setOf(
Contact("Alice", "123-456"),
Contact("Alice", "123-456"))
set1.size // 1 or 2?
set2.size // 1 or 2?
}
```
You can easily check your guess by printing the contents of the `Set`s.

View File

@ -1,20 +0,0 @@
package hashingExercise1
import org.junit.Assert
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runners.MethodSorters
import util.TIMEOUT
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
class TestHashingExercise1 {
@Test(timeout = TIMEOUT)
fun testSizeOfFirstSet() {
Assert.assertTrue("Wrong answer for set1", getSet1Size() == 2)
}
@Test(timeout = TIMEOUT)
fun testSizeOfSecondSet() {
Assert.assertTrue("Wrong answer for set2", getSet2Size() == 1)
}
}

View File

@ -1,3 +0,0 @@
content:
- Examples
- Exercise 1

View File

@ -1,3 +0,0 @@
id: 354564
update_date: Tue, 12 May 2020 16:26:31 UTC
unit: 338605

View File

@ -1,35 +0,0 @@
// Immutability/ColorBlend.kt
package colorblend
import atomictest.eq
import paintcolors.Color
import paintcolors.Color.*
fun blend(a: Color, b: Color) = when {
a == b -> a
a == brown || b == brown -> brown
else -> when (a to b) {
red to blue, blue to red -> purple
red to yellow, yellow to red -> orange
blue to yellow, yellow to blue -> green
else -> {
// Interesting but not accurate:
val values = values()
values[
(a.ordinal + b.ordinal) % values.size]
}
}
}
fun test(
mix: (a: Color, b: Color) -> Color?
) {
mix(red, red) eq red
mix(purple, brown) eq brown
mix(red, yellow) eq orange
mix(yellow, blue) eq green
mix(purple, orange) eq blue // Not accurate
}
fun main() {
test(::blend)
}

View File

@ -1,16 +0,0 @@
// Immutability/DataClassCopy.kt
import atomictest.eq
data class DC(
val a: String,
val b: String,
val c: String,
val d: String
)
fun main() {
val dc = DC("one", "two", "three", "four")
val dc2 = dc.copy(b = "bouncy", d = "red")
dc eq "DC(a=one, b=two, c=three, d=four)"
dc2 eq "DC(a=one, b=bouncy, c=three, d=red)"
}

View File

@ -1,22 +0,0 @@
// Immutability/MutableBlendMap.kt
package mutableblendmap
import paintcolors.Color
class BlendMap {
private val map =
mutableMapOf<Pair<Color, Color>, Color>()
init {
for (a in Color.values()) {
for (b in Color.values()) {
map[a to b] = colorblend.blend(a, b)
}
}
}
fun blend(a: Color, b: Color) = map[a to b]
}
fun main() {
colorblend.test(BlendMap()::blend)
}

View File

@ -1,25 +0,0 @@
// Immutability/MutableBlendMap2.kt
package mutableblendmap2
import paintcolors.Color
class BlendMap {
private val
imap: Map<Pair<Color, Color>, Color>
init {
val map = mutableMapOf<
Pair<Color, Color>, Color>()
for (a in Color.values()) {
for (b in Color.values()) {
map[a to b] = colorblend.blend(a, b)
}
}
imap = map.toMap() // Read-only Map
}
fun blend(a: Color, b: Color) = imap[a to b]
}
fun main() {
colorblend.test(BlendMap()::blend)
}

View File

@ -1,7 +0,0 @@
// Immutability/PaintColors.kt
package paintcolors
enum class Color {
red, blue, yellow, purple,
green, orange, brown
}

View File

@ -1,19 +0,0 @@
// Immutability/ReadOnlyBlendMap.kt
package readonlyblendmap
import paintcolors.Color
val combinations = Color.values()
.flatMap { a ->
Color.values().map { b -> a to b }
}
val blendMap = combinations.map {
it to colorblend.blend(it.first, it.second)
}.toMap()
fun blend(a: Color, b: Color) =
blendMap[a to b]
fun main() {
colorblend.test(::blend)
}

View File

@ -1,19 +0,0 @@
// Immutability/ReadOnlyBlendMap2.kt
package readonlyblendmap2
import paintcolors.Color
val blendMap = Color.values()
.flatMap { a ->
Color.values().map { b -> a to b }
}
.map {
it to colorblend.blend(it.first, it.second)
}
.toMap()
fun blend(a: Color, b: Color) =
blendMap[a to b]
fun main() {
colorblend.test(::blend)
}

View File

@ -1,21 +0,0 @@
// Immutability/ReadOnlyBlendMap3.kt
package readonlyblendmap3
import paintcolors.Color
class BlendMap {
private val map = Color.values()
.flatMap { a ->
Color.values().map { b -> a to b }
}
.map {
it to colorblend.blend(
it.first, it.second)
}
.toMap()
fun blend(a: Color, b: Color) = map[a to b]
}
fun main() {
colorblend.test(BlendMap()::blend)
}

View File

@ -1,17 +0,0 @@
// Immutability/ReadOnlyBlendMap4.kt
package readonlyblendmap4
import paintcolors.Color
@ExperimentalStdlibApi
val map1: Map<Pair<Color, Color>, Color> =
buildMap {
for (a in Color.values()) {
for (b in Color.values()) {
this[a to b] = colorblend.blend(a, b)
}
}
}
fun main() {
//colorblend.test(BlendMap()::blend)
}

View File

@ -1,24 +0,0 @@
// Immutability/XYZFlatMap.kt
package xyzflatmap
enum class XYZ { x, y, z }
fun main() {
val flat = XYZ.values().flatMap { a ->
XYZ.values().map { b ->
a to b
}
}
flat.forEach { println(it) }
}
/* Output:
(x, x)
(x, y)
(x, z)
(y, x)
(y, y)
(y, z)
(z, x)
(z, y)
(z, z)
*/

View File

@ -1,23 +0,0 @@
// Immutability/XYZMap.kt
package xyzmap
enum class XYZ { x, y, z }
fun main() {
val normal = XYZ.values().map { a ->
println()
XYZ.values().map { b ->
print("$a:$b,"); a to b
}
}
println()
normal.forEach { println(it) }
}
/* Output:
x:x,x:y,x:z,
y:x,y:y,y:z,
z:x,z:y,z:z,
[(x, x), (x, y), (x, z)]
[(y, x), (y, y), (y, z)]
[(z, x), (z, y), (z, z)]
*/

View File

@ -1,24 +0,0 @@
type: theory
files:
- name: src/PaintColors.kt
visible: true
- name: src/ColorBlend.kt
visible: true
- name: src/MutableBlendMap.kt
visible: true
- name: src/MutableBlendMap2.kt
visible: true
- name: src/XYZMap.kt
visible: true
- name: src/XYZFlatMap.kt
visible: true
- name: src/ReadOnlyBlendMap.kt
visible: true
- name: src/ReadOnlyBlendMap2.kt
visible: true
- name: src/ReadOnlyBlendMap3.kt
visible: true
- name: src/ReadOnlyBlendMap4.kt
visible: true
- name: src/DataClassCopy.kt
visible: true

View File

@ -1,2 +0,0 @@
id: 1305810
update_date: Tue, 12 May 2020 16:26:30 UTC

View File

@ -1,4 +0,0 @@
## Immutability
Examples accompanying the atom.
[Read "Immutability" atom online.](https://stepik.org/lesson/350554/step/1)

View File

@ -1,2 +0,0 @@
content:
- Examples

View File

@ -1,3 +0,0 @@
id: 354563
update_date: Tue, 12 May 2020 16:26:27 UTC
unit: 338604

View File

@ -1,11 +0,0 @@
// LambdaWithReceiver/AnonymousFunction.kt
package lambdawithreceiver
import atomictest.eq
fun main() {
val divides = fun Int.(d: Int): Boolean {
return this % d == 0
}
10.divides(2) eq true
10.divides(3) eq false
}

View File

@ -1,22 +0,0 @@
// LambdaWithReceiver/BuildLists.kt
package buildinglists
import atomictest.eq
fun main() {
val strings: List<String> = buildList {
add("Chars:") // [1]
for (ch in 'a'..'d') {
add("$ch")
}
}
strings eq
listOf("Chars:", "a",