diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml
new file mode 100644
index 0000000..f5b372c
--- /dev/null
+++ b/.idea/checkstyle-idea.xml
@@ -0,0 +1,16 @@
+
+
+
+ 10.12.5
+ JavaOnly
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/kotlin/exercise2/task4/ProcessCountriesData.kt b/src/main/kotlin/exercise2/task4/ProcessCountriesData.kt
index 291e558..8b2c0cf 100644
--- a/src/main/kotlin/exercise2/task4/ProcessCountriesData.kt
+++ b/src/main/kotlin/exercise2/task4/ProcessCountriesData.kt
@@ -59,27 +59,32 @@ internal val countries = listOf(
*/
internal fun List.findCountryWithBiggestTotalArea(): Country {
- TODO("Implement me!!!")
+ return this.maxBy { it.totalAreaInSquareKilometers }
}
internal fun List.findCountryWithBiggestPopulation(): Country {
- TODO("Implement me!!!")
+ return this.maxBy { it.population }
}
internal fun List.findCountryWithHighestPopulationDensity(): Country {
- TODO("Implement me!!!")
+ return this.maxBy { it.population / it.totalAreaInSquareKilometers }
}
internal fun List.findCountryWithLowestPopulationDensity(): Country {
- TODO("Implement me!!!")
+ return this.minBy { it.population / it.totalAreaInSquareKilometers }
}
internal fun List.findLanguageSpokenInMostCountries(): String {
- TODO("Implement me!!!")
+ return this.flatMap { it.languages }
+ .groupingBy { it }
+ .eachCount()
+ .also { println("catalog: $it") }
+ .maxBy { it.value }
+ .key
}
internal fun List.filterCountriesThatSpeakLanguage(language: String): List {
- TODO("Implement me!!!")
+ return this.filter { it.languages.contains(language) }
}
diff --git a/src/main/kotlin/exercise2/task5/CreateUserDSL.kt b/src/main/kotlin/exercise2/task5/CreateUserDSL.kt
index 855c0cb..3d6951a 100644
--- a/src/main/kotlin/exercise2/task5/CreateUserDSL.kt
+++ b/src/main/kotlin/exercise2/task5/CreateUserDSL.kt
@@ -49,11 +49,12 @@ internal data class Address(
*/
internal fun user(initUser: User.() -> Unit): User {
- TODO("Implement me!!!")
+ return User().apply(initUser)
}
internal fun User.address(initAddress: Address.() -> Unit): User {
- TODO("Implement me!!!")
+ this.address = Address().apply(initAddress)
+ return this
}
fun main() {
diff --git a/src/main/kotlin/exercise3/task1/BalancedBrackets.kt b/src/main/kotlin/exercise3/task1/BalancedBrackets.kt
index 7a6958d..0550c15 100644
--- a/src/main/kotlin/exercise3/task1/BalancedBrackets.kt
+++ b/src/main/kotlin/exercise3/task1/BalancedBrackets.kt
@@ -1,5 +1,7 @@
package exercise3.task1
+import java.util.Stack
+
/**
* Task1: Balanced Brackets (Parentheses) Problem
*
@@ -24,9 +26,32 @@ package exercise3.task1
*
*/
-
internal fun isExpressionBalanced(expression: String): Boolean {
- TODO("Implement me!!!")
+ val stack = Stack()
+
+ fun isCorrectPop(bracket: Char): Boolean {
+ return !stack.isEmpty() && stack.pop() == bracket
+ }
+
+ for(bracket in expression) {
+ when(bracket) {
+ '{', '[', '(' -> stack.push(bracket)
+
+ '}' -> {
+ if(!isCorrectPop('{'))
+ return false
+ }
+ ']' -> {
+ if(!isCorrectPop('['))
+ return false
+ }
+ ')' -> {
+ if(!isCorrectPop('('))
+ return false
+ }
+ }
+ }
+ return stack.isEmpty()
}
fun main() {
diff --git a/src/main/kotlin/exercise3/task2/ParenthesesClusters.kt b/src/main/kotlin/exercise3/task2/ParenthesesClusters.kt
index 0e75083..edb525a 100644
--- a/src/main/kotlin/exercise3/task2/ParenthesesClusters.kt
+++ b/src/main/kotlin/exercise3/task2/ParenthesesClusters.kt
@@ -24,7 +24,26 @@ package exercise3.task2
*/
internal fun String.splitToBracketsClusters(): List {
- TODO("Implement me!!!")
+ val clusters = mutableListOf()
+ var numOfBrackets = 0
+ var clusterStartIndex = 0
+
+ for ((index, char) in this.withIndex()) {
+ when (char) {
+ '(' -> numOfBrackets++
+
+ ')' -> {
+ numOfBrackets--
+ if (numOfBrackets == 0) {
+ clusters.add(this.substring(clusterStartIndex, index + 1))
+ clusterStartIndex = index + 1
+ } else if (numOfBrackets < 0) {
+ return emptyList() // Unbalanced expression
+ }
+ }
+ }
+ }
+ return if (numOfBrackets == 0) clusters else emptyList()
}
fun main() {
diff --git a/src/main/kotlin/exercise3/task3/SherlockValidatesString.kt b/src/main/kotlin/exercise3/task3/SherlockValidatesString.kt
index 55680b8..cd74487 100644
--- a/src/main/kotlin/exercise3/task3/SherlockValidatesString.kt
+++ b/src/main/kotlin/exercise3/task3/SherlockValidatesString.kt
@@ -29,7 +29,26 @@ package exercise3.task3
*/
internal fun isSherlockValid(s: String): String {
- TODO("Implement me!!!")
+ val charCount = s.groupingBy { it }.eachCount()
+ val frequencies = charCount.values.toList()
+
+ if (frequencies.toSet().size == 1) {
+ return "YES"
+ }
+
+ if (frequencies.toSet().size == 2) {
+ val minFreq = frequencies.minOrNull()!!
+ val maxFreq = frequencies.maxOrNull()!!
+
+ if (frequencies.count { it == minFreq } == 1 && minFreq == 1) {
+ return "YES"
+ }
+
+ if (maxFreq - minFreq == 1 && frequencies.count { it == maxFreq } == 1) {
+ return "YES"
+ }
+ }
+ return "NO"
}
fun main() {
diff --git a/src/main/kotlin/exercise3/task4/TaxiParkTask.kt b/src/main/kotlin/exercise3/task4/TaxiParkTask.kt
index 0dfe831..762791a 100755
--- a/src/main/kotlin/exercise3/task4/TaxiParkTask.kt
+++ b/src/main/kotlin/exercise3/task4/TaxiParkTask.kt
@@ -10,7 +10,7 @@ package exercise3.task4
* Find all the drivers who performed no trips.
*/
internal fun TaxiPark.findFakeDrivers(): Set {
- TODO("Implement me!!!")
+ return allDrivers - trips.map { it.driver }.toSet()
}
/**
@@ -18,7 +18,9 @@ internal fun TaxiPark.findFakeDrivers(): Set {
* Find all the clients who completed at least the given number of trips.
*/
internal fun TaxiPark.findFaithfulPassengers(minTrips: Int): Set {
- TODO("Implement me!!!")
+ return allPassengers.filter { passenger ->
+ trips.count { passenger in it.passengers } >= minTrips
+ }.toSet()
}
/**
@@ -26,7 +28,12 @@ internal fun TaxiPark.findFaithfulPassengers(minTrips: Int): Set {
* Find all the passengers, who were taken by a given driver more than once.
*/
internal fun TaxiPark.findFrequentPassengers(driver: Driver): Set {
- TODO("Implement me!!!")
+ return trips.filter { it.driver == driver }
+ .flatMap { it.passengers }
+ .groupingBy { it }
+ .eachCount()
+ .filterValues { it > 1 }
+ .keys
}
/**
diff --git a/src/main/kotlin/exercise4/task1/BankAccount.kt b/src/main/kotlin/exercise4/task1/BankAccount.kt
index cea6c9a..4400a8a 100644
--- a/src/main/kotlin/exercise4/task1/BankAccount.kt
+++ b/src/main/kotlin/exercise4/task1/BankAccount.kt
@@ -32,21 +32,52 @@ package exercise4.task1
* The initial balance for this constructor should always be set to 0.
*/
+open class BankAccount(
+ private val accountNumber: String,
+ private val accHolderName: String,
+ private var balance: Double
+) {
+ constructor(accountNumber: String, accHolderName: String): this(accountNumber, accHolderName, 0.0)
+
+ open fun deposit(amount: Double): Boolean {
+ balance += amount
+ return true
+ }
+
+ open fun withdraw(amount: Double): Boolean {
+ if (amount <= balance) {
+ balance -= amount
+ return true
+ }
+ return false
+ }
+
+ fun getBalance(): Double {
+ return balance
+ }
+
+ open fun displayAccountInfo() {
+ println("Account Holder: $accHolderName")
+ println("Account Number: $accountNumber")
+ println("Balance: $balance")
+ println()
+ }
+}
fun main() {
- TODO("Uncomment the lines above after the Bank Account class is implemented.")
+
// Creating a Bank Account
-// val account = BankAccount("123456789", "John Doe")
+ val account = BankAccount("123456789", "John Doe")
// Displaying account information
-// account.displayAccountInfo()
+ account.displayAccountInfo()
// Depositing some money
-// account.deposit(1000.0)
+ account.deposit(1000.0)
// Withdrawing some money
-// account.withdraw(500.0)
+ account.withdraw(500.0)
// Displaying updated account information
-// account.displayAccountInfo()
+ account.displayAccountInfo()
}
diff --git a/src/main/kotlin/exercise4/task2/TransactionalBankAccount.kt b/src/main/kotlin/exercise4/task2/TransactionalBankAccount.kt
index d1cf6f4..f3b3412 100644
--- a/src/main/kotlin/exercise4/task2/TransactionalBankAccount.kt
+++ b/src/main/kotlin/exercise4/task2/TransactionalBankAccount.kt
@@ -1,5 +1,6 @@
package exercise4.task2
+import exercise4.task1.BankAccount
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.*
@@ -78,8 +79,104 @@ import java.util.*
* ```
*/
+enum class TType {
+ DEPOSIT, WITHDRAWAL
+}
+
+enum class TStatus {
+ SUCCESS, FAILURE
+}
+
+data class Transaction(
+ val transactionDate: LocalDateTime,
+ val transactionType: TType,
+ val amount: Double,
+ val oldBalance: Double,
+ val newBalance: Double,
+ val transactionStatus: TStatus
+)
+
+class TransactionalBankAccount(
+ accountNumber: String,
+ accHolderName: String,
+ balance: Double,
+) : BankAccount(accountNumber, accHolderName, balance) {
+
+ private val transactions: MutableList = mutableListOf()
+
+ override fun deposit(amount: Double): Boolean {
+ val oldBalance = getBalance()
+ super.deposit(amount)
+ val newBalance = getBalance()
+
+ transactions.add(Transaction(currentTime, TType.DEPOSIT, amount, oldBalance, newBalance, TStatus.SUCCESS))
+ return true
+ }
+
+ override fun withdraw(amount: Double): Boolean {
+ val oldBalance = getBalance()
+ val success = super.withdraw(amount)
+ val newBalance = getBalance()
+ val status = if (success) TStatus.SUCCESS else TStatus.FAILURE
+
+ transactions.add(Transaction(currentTime, TType.WITHDRAWAL, amount, oldBalance, newBalance, status))
+ return success
+ }
+ fun getAllTransactions(): List {
+ return transactions.sortedByDescending { it.transactionDate }
+ }
+ fun getAllTransactionsBy(predicate: (Transaction) -> Boolean): List {
+ return getAllTransactions().filter(predicate)
+ }
+
+ fun getTransactionsBetween(startDate: LocalDateTime, endDate: LocalDateTime): List {
+ return getAllTransactionsBy { it.transactionDate in startDate..endDate }
+ }
+
+ fun getAllFailedTransactions(): List {
+ return getAllTransactionsBy { it.transactionStatus == TStatus.FAILURE }
+ }
+
+ fun getAllSuccessfulTransaction(): List {
+ return getAllTransactionsBy { it.transactionStatus == TStatus.SUCCESS }
+ }
+
+ fun getAllFailedDeposits(): List {
+ return getAllTransactionsBy {it.transactionType == TType.DEPOSIT && it.transactionStatus == TStatus.FAILURE }
+ }
+
+ fun getAllFailedWithdrawals(): List {
+ return getAllTransactionsBy {it.transactionType == TType.WITHDRAWAL && it.transactionStatus == TStatus.FAILURE }
+ }
+
+ fun getAllSuccessfulDeposits(): List {
+ return getAllTransactionsBy { it.transactionType == TType.DEPOSIT && it.transactionStatus == TStatus.SUCCESS }
+ }
+
+ fun getAllSuccessfulWithdrawals(): List {
+ return getAllTransactionsBy { it.transactionType == TType.WITHDRAWAL && it.transactionStatus == TStatus.SUCCESS}
+ }
+
+ override fun displayAccountInfo() {
+ super.displayAccountInfo()
+ println("Transactions:\n")
+ if (transactions.isEmpty()) {
+ println("No transactions recorded\n")
+ } else {
+ transactions.forEach {
+ println("Transaction Date: ${it.transactionDate.prettyPrint()}")
+ println("Transaction Type: ${it.transactionType}")
+ println("Amount: ${it.amount}")
+ println("Old Balance: ${it.oldBalance}")
+ println("New Balance: ${it.newBalance}")
+ println("Status ${it.transactionStatus}")
+ println()
+ }
+ }
+ }
+}
private val currentTime: LocalDateTime get() = LocalDateTime.now()
@@ -91,17 +188,17 @@ private fun LocalDateTime.prettyPrint(): String {
fun main() {
println(currentTime.prettyPrint())
// Creating a Transactional Bank Account
-// val account = TransactionalBankAccount("123456789", "John Doe")
+ val account = TransactionalBankAccount("123456789", "John Doe", 0.0)
// Displaying account information
-// account.displayAccountInfo()
+ account.displayAccountInfo()
// Depositing some money
-// account.deposit(1000.0)
+ account.deposit(1000.0)
// Withdrawing some money
-// account.withdraw(500.0)
+ account.withdraw(500.0)
// Displaying updated account information
-// account.displayAccountInfo()
+ account.displayAccountInfo()
}
diff --git a/src/main/kotlin/exercise6/taskProjections/task1/Task.kt b/src/main/kotlin/exercise6/taskProjections/task1/Task.kt
index 7905d94..a2a1dd2 100644
--- a/src/main/kotlin/exercise6/taskProjections/task1/Task.kt
+++ b/src/main/kotlin/exercise6/taskProjections/task1/Task.kt
@@ -11,12 +11,12 @@ package exercise6.taskProjections.task1
**/
-interface Sender {
- fun send(item: Any)
+interface Sender {
+ fun send(item: T)
}
-class MailBox(private var box: Any? = null): Sender {
- override fun send(item: Any) {
+class MailBox(private var box: T? = null): Sender {
+ override fun send(item: T) {
printCurrentBoxState()
println("Sending the box: $item!")
box = item
@@ -32,12 +32,13 @@ class MailBox(private var box: Any? = null): Sender {
}
-class Postman(private val mailboxes: List): Sender {
- override fun send(item: Any) {
+class Postman(private val mailboxes: List>): Sender {
+ override fun send(item: T) {
mailboxes.forEach { it.send(item) }
}
}
+
interface Delivery
open class Postcard(open val origin: String) : Delivery
@@ -45,9 +46,9 @@ open class Postcard(open val origin: String) : Delivery
data class ExpressPostcard(val priceEuro: Int, override val origin: String) : Postcard(origin)
fun main() {
- // TODO: This code should became compilable
-// val postcardStorage = MailBox()
-// val expressPostcardStorage = MailBox()
+// TODO: This code should became compilable
+ val postcardStorage = MailBox()
+ val expressPostcardStorage = MailBox()
val expressPostcard = ExpressPostcard(15, "Serbia")
val postcard = Postcard("Germany")
@@ -55,4 +56,10 @@ fun main() {
// TODO: add code to create topRatedPostman and juniorPostman.
// The topRatedPostman can send ONLY express postcards
// The juniorPostman can send both regular and express postcards
+ val topRatedPostman = Postman(listOf(expressPostcardStorage))
+ val juniorPostman = Postman(listOf(postcardStorage))
+
+ topRatedPostman.send(expressPostcard)
+ juniorPostman.send(expressPostcard)
+ juniorPostman.send(postcard)
}
\ No newline at end of file
diff --git a/src/main/kotlin/exercise6/taskProjections/task2/Task.kt b/src/main/kotlin/exercise6/taskProjections/task2/Task.kt
index b28c6ae..cdefc06 100644
--- a/src/main/kotlin/exercise6/taskProjections/task2/Task.kt
+++ b/src/main/kotlin/exercise6/taskProjections/task2/Task.kt
@@ -10,6 +10,9 @@ package exercise6.taskProjections.task2
* If you did everything correct, you could not create a method create which accepts nothing and returns T
**/
+class Programmer {
+ fun learn(language: T) = println("I learned ${language.name}!")
+}
interface ProgrammingLanguage {
val name: String
}
@@ -18,16 +21,15 @@ class JvmLanguage(override val name: String) : ProgrammingLanguage
class BlockBasedLanguage(override val name: String) : ProgrammingLanguage
fun main() {
- TODO("Uncomment this code when you finish the task")
-// val programmer = Programmer()
-//
-// val jvmLanguages = listOf(JvmLanguage("Java"), JvmLanguage("Kotlin"))
-// jvmLanguages.forEach{ programmer.learn(it) } // OK
-//
-// val blockBasedLanguages = listOf(BlockBasedLanguage("Scratch"), JvmLanguage("Snap"))
-// blockBasedLanguages.forEach{ programmer.learn(it) } // OK
-//
-// (jvmLanguages + blockBasedLanguages).forEach{ programmer.learn(it) } // OK
-//
-//// val newLanguage: ProgrammingLanguage = programmer.create() // ERROR
+ val programmer = Programmer()
+
+ val jvmLanguages = listOf(JvmLanguage("Java"), JvmLanguage("Kotlin"))
+ jvmLanguages.forEach{ programmer.learn(it) } // OK
+
+ val blockBasedLanguages = listOf(BlockBasedLanguage("Scratch"), JvmLanguage("Snap"))
+ blockBasedLanguages.forEach{ programmer.learn(it) } // OK
+
+ (jvmLanguages + blockBasedLanguages).forEach{ programmer.learn(it) } // OK
+
+// val newLanguage: ProgrammingLanguage = programmer.create() // ERROR
}
diff --git a/src/main/kotlin/exercise6/taskProjections/task3/Task.kt b/src/main/kotlin/exercise6/taskProjections/task3/Task.kt
index 211a74f..17b1b04 100644
--- a/src/main/kotlin/exercise6/taskProjections/task3/Task.kt
+++ b/src/main/kotlin/exercise6/taskProjections/task3/Task.kt
@@ -36,11 +36,11 @@ class BlockBasedLanguageParser : LanguageParser {
}
fun main() {
- TODO("Create a new HashMap and uncomment code bellow")
-// parsersHashMap[JvmLanguage::class.java] = JvmLanguageParser()
-// parsersHashMap[BlockBasedLanguage::class.java] = BlockBasedLanguageParser()
-//
-// val scratch = BlockBasedLanguage()
-// val foundParser = parsersHashMap[scratch.javaClass]
-// foundParser?.parse(scratch)
+ val parsersHashMap = HashMap, LanguageParser<*>>()
+ parsersHashMap[JvmLanguage::class.java] = JvmLanguageParser()
+ parsersHashMap[BlockBasedLanguage::class.java] = BlockBasedLanguageParser()
+
+ val scratch = BlockBasedLanguage()
+ val foundParser = parsersHashMap[scratch.javaClass]
+ foundParser?.parse(scratch)
}
diff --git a/src/main/kotlin/exercise6/taskProjections/task4/Task.kt b/src/main/kotlin/exercise6/taskProjections/task4/Task.kt
index c2d86d9..e844ffe 100644
--- a/src/main/kotlin/exercise6/taskProjections/task4/Task.kt
+++ b/src/main/kotlin/exercise6/taskProjections/task4/Task.kt
@@ -7,6 +7,12 @@ package exercise6.taskProjections.task4
* that accepts two arrays with a generic type of Any and copy elements from the first array to the second one.
**/
+fun copy(first: Array, second: Array) {
+ for(i in first.indices) {
+ second[i] = first[i]
+ }
+}
+
fun main() {
val ints = arrayOf(1, 2, 3)
val any = Array(3) { "" }
@@ -17,10 +23,10 @@ fun main() {
println("_______")
println("_______")
- // TODO: uncomment this code
- // copy(ints, any)
+ copy(ints, any)
ints.forEach{ print("$it ") }
println()
any.forEach{ print("$it ")}
}
+
diff --git a/src/main/kotlin/exercise6/taskProjections/task5/Task.kt b/src/main/kotlin/exercise6/taskProjections/task5/Task.kt
index 9123785..2668d00 100644
--- a/src/main/kotlin/exercise6/taskProjections/task5/Task.kt
+++ b/src/main/kotlin/exercise6/taskProjections/task5/Task.kt
@@ -14,20 +14,34 @@ package exercise6.taskProjections.task5
* Create a new class "IntegerBuilder", that implements Builder and can convert String to Int
**/
+class Printer {
+ fun print(item: T) {
+ println("$item")
+ }
+}
+
+abstract class Builder {
+ abstract fun build(item: P): T
+}
+
+class IntegerBuilder : Builder() {
+ override fun build(item: String): Int {
+ return item.toInt()
+ }
+}
+
fun main() {
// [1]
- // TODO: uncomment me
-// val integerPrinter = Printer()
-// val stringPrinter = Printer()
-//
-// integerPrinter.print(2)
-// stringPrinter.print("Bla bla bla")
+ val integerPrinter = Printer()
+ val stringPrinter = Printer()
+
+ integerPrinter.print(2)
+ stringPrinter.print("Bla bla bla")
println("________")
// [2]
- // TODO: uncomment me
-// val intBuilder = IntegerBuilder()
-// val x = intBuilder.build("1")
-// println("We build [ $x ]")
+ val intBuilder = IntegerBuilder()
+ val x = intBuilder.build("1")
+ println("We build [ $x ]")
}
diff --git a/src/main/kotlin/exercise6/taskProjections/task6/Task.kt b/src/main/kotlin/exercise6/taskProjections/task6/Task.kt
index e897e4c..518fe1b 100644
--- a/src/main/kotlin/exercise6/taskProjections/task6/Task.kt
+++ b/src/main/kotlin/exercise6/taskProjections/task6/Task.kt
@@ -10,24 +10,22 @@ open class A
class B : A()
class C : A() { fun consume(other: A): C = this }
-// TODO: uncomment and fix me
-//fun funny(
-// source: Iterator?>,
-// target: MutableCollection?>,
-// base: ??,
-// how: ??
-//) {
-// var result: R = base
-// for (value in source) {
-// result = how(result, value)
-// target.add(result)
-// }
-//}
+fun funny(
+ source: Iterator,
+ target: MutableCollection,
+ base: R,
+ how: (R, T) -> S
+) {
+ var result: R = base
+ for (value in source) {
+ result = how(result, value)
+ target.add(result)
+ }
+}
fun main() {
- // TODO: uncomment me, it should not produce any compilation errors
-// val wtf = mutableListOf()
-// val src = mapOf(3.14 to B(), 2 to B(), "Hello" to B())
-// val c = C()
-// funny(src.values.iterator(), wtf, c) { r, t -> r.consume(t) }
+ val wtf = mutableListOf()
+ val src = mapOf(3.14 to B(), 2 to B(), "Hello" to B())
+ val c = C()
+ funny(src.values.iterator(), wtf, c) { r, t -> r.consume(t) }
}