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) } }