diff --git a/src/main/kotlin/exercise1/task1/GradeCalculator.kt b/src/main/kotlin/exercise1/task1/GradeCalculator.kt index df111ab..d4a8883 100644 --- a/src/main/kotlin/exercise1/task1/GradeCalculator.kt +++ b/src/main/kotlin/exercise1/task1/GradeCalculator.kt @@ -40,13 +40,22 @@ import java.util.Scanner */ internal fun calculateGrade(score: Int): Int { - TODO("Implement me!!!") + return when { + score in 0..50 -> 5 + score in 51..60 -> 6 + score in 61..70 -> 7 + score in 71..80 -> 8 + score in 81..90 -> 9 + score in 91..100 -> 10 + else -> throw IllegalArgumentException("Score out of range 0-100") + } } fun main() { print("Enter student score: ") val scanner = Scanner(System.`in`) val score = scanner.nextInt() - - calculateGrade(score) + val grade = calculateGrade(score) + val msg = if(grade != 5) "Student's grade is: $grade" else "Student didn't pass the exam" + println(msg) } diff --git a/src/main/kotlin/exercise1/task2/PrintPyramid.kt b/src/main/kotlin/exercise1/task2/PrintPyramid.kt index d9c89c9..f2bc9db 100644 --- a/src/main/kotlin/exercise1/task2/PrintPyramid.kt +++ b/src/main/kotlin/exercise1/task2/PrintPyramid.kt @@ -57,7 +57,14 @@ package org.jetbrains.exercise1.task2 */ internal fun printPyramid(level: Int) { - TODO("Implement me!!!") + require (level in 3..15) { + "Level is out of range" + } + for(i in 1..level) { + val spaces = " ".repeat(level - i) + val stars = "*".repeat(2 * i - 1) + println("$spaces$stars$spaces") + } } fun main() { diff --git a/src/main/kotlin/exercise1/task3/ScrabbleWordScoreCalculator.kt b/src/main/kotlin/exercise1/task3/ScrabbleWordScoreCalculator.kt index c0e883c..64a6774 100644 --- a/src/main/kotlin/exercise1/task3/ScrabbleWordScoreCalculator.kt +++ b/src/main/kotlin/exercise1/task3/ScrabbleWordScoreCalculator.kt @@ -31,8 +31,18 @@ package org.jetbrains.exercise1.task3 * */ +val charMap = mapOf( + 'A' to 1, 'E' to 1, 'I' to 1, 'O' to 1, 'U' to 1, 'L' to 1, 'N' to 1, 'R' to 1, 'S' to 1, 'T' to 1, + 'D' to 2, 'G' to 2, + 'B' to 3, 'C' to 3, 'M' to 3, 'P' to 3, + 'F' to 4, 'H' to 4, 'V' to 4, 'W' to 4, 'Y' to 4, + 'K' to 5, + 'J' to 8, 'X' to 8, + 'Q' to 10, 'Z' to 10, +) + internal fun calculateWordScrabbleScore(word: String): Int { - TODO("Implement me!!!") + return word.sumOf { charMap.getOrDefault(it.uppercaseChar(), 0) } } fun main() { diff --git a/src/main/kotlin/exercise1/task4/PalindromeNumber.kt b/src/main/kotlin/exercise1/task4/PalindromeNumber.kt index 04a692d..2827e72 100644 --- a/src/main/kotlin/exercise1/task4/PalindromeNumber.kt +++ b/src/main/kotlin/exercise1/task4/PalindromeNumber.kt @@ -28,11 +28,19 @@ package org.jetbrains.exercise1.task4 */ internal fun isPalindrome(x: Int): Boolean { - TODO("Implement me!!!") + require(x in -1000000..1000000) { + "Number must be in range -1000000..1000000" + } + return when { + x < 0 -> false + x.toString().length == 1 -> true + x.toString() == x.toString().reversed() -> true + else -> false + } } fun main() { - val number = 121 + val number = 56465 if (isPalindrome(number)) { println("Number $number is a palindrome.") } else { diff --git a/src/main/kotlin/exercise1/task5/ReverseInteger.kt b/src/main/kotlin/exercise1/task5/ReverseInteger.kt index 447b8a1..bb12455 100644 --- a/src/main/kotlin/exercise1/task5/ReverseInteger.kt +++ b/src/main/kotlin/exercise1/task5/ReverseInteger.kt @@ -1,5 +1,7 @@ package org.jetbrains.exercise1.task5 +import kotlin.math.abs + /** * Task 5: Given an integer x, return x with its digits reversed. * @@ -27,10 +29,11 @@ package org.jetbrains.exercise1.task5 */ internal fun reverseInteger(x: Int): Int { - TODO("Implement me!!!") + require(x in -1000000..1000000) { "Number must be integer in range -1000000..1000000" } + val reversed = abs(x).toString().reversed() + return if (x < 0) ("-$reversed").toInt() else reversed.toInt() } - fun main() { - val integer = -321 + val integer = -78952 println("Reverse integer of number $integer is ${reverseInteger(integer)}") } diff --git a/src/main/kotlin/exercise2/task1/FindPairOfHighestSum.kt b/src/main/kotlin/exercise2/task1/FindPairOfHighestSum.kt index ddf425b..590c9c8 100644 --- a/src/main/kotlin/exercise2/task1/FindPairOfHighestSum.kt +++ b/src/main/kotlin/exercise2/task1/FindPairOfHighestSum.kt @@ -1,5 +1,6 @@ package exercise2.task1 +import exercise2.task2.findHighestSumPairFunctional import org.jetbrains.exercise2.common.isEqualsTo import org.jetbrains.exercise2.task3.findPairWithBiggestDifference @@ -18,7 +19,20 @@ import org.jetbrains.exercise2.task3.findPairWithBiggestDifference */ internal fun List.findHighestSumPair(): Pair { - TODO("Implement me!!") + require(this.size >= 2) { "List must have at least two integers." } + require(this.all { it in -1000..1000 }) + var maxSum = Integer.MIN_VALUE + var pair: Pair? = null + for((index, item) in this.dropLast(1).withIndex()) { + for(j in (index + 1) until this.size) { + val sum = item + this[j] + if(sum >= maxSum) { + maxSum = sum + pair = Pair(item, this[j]) + } + } + } + return pair!! } fun main() { diff --git a/src/main/kotlin/exercise2/task2/FindPairOfHighestSumFunctional.kt b/src/main/kotlin/exercise2/task2/FindPairOfHighestSumFunctional.kt index b1527fa..78a7cc2 100644 --- a/src/main/kotlin/exercise2/task2/FindPairOfHighestSumFunctional.kt +++ b/src/main/kotlin/exercise2/task2/FindPairOfHighestSumFunctional.kt @@ -1,5 +1,6 @@ package exercise2.task2 +import exercise2.task1.findHighestSumPair import org.jetbrains.exercise2.common.isEqualsTo import org.jetbrains.exercise2.task3.findPairWithBiggestDifference @@ -20,7 +21,9 @@ import org.jetbrains.exercise2.task3.findPairWithBiggestDifference */ internal fun List.findHighestSumPairFunctional(): Pair { - TODO("Implement me!!") + require(this.size >= 2) { "List must have at least two integers." } + require(this.all { it in -1000..1000 }) + return this.sortedDescending().let { sortedList -> sortedList.first() to sortedList[1] } } fun main() { diff --git a/src/main/kotlin/exercise2/task3/ConvertMethodToFunctionalApproach.kt b/src/main/kotlin/exercise2/task3/ConvertMethodToFunctionalApproach.kt index 47f814b..96a5a0b 100644 --- a/src/main/kotlin/exercise2/task3/ConvertMethodToFunctionalApproach.kt +++ b/src/main/kotlin/exercise2/task3/ConvertMethodToFunctionalApproach.kt @@ -1,5 +1,6 @@ package org.jetbrains.exercise2.task3 +import exercise2.task2.findHighestSumPairFunctional import org.jetbrains.exercise2.common.isEqualsTo import kotlin.math.abs @@ -17,24 +18,8 @@ import kotlin.math.abs */ internal fun List.findPairWithBiggestDifference(): Pair { - // TODO refactor me to functional approach and make tests pass!!! - var resultPair: Pair? = null - var biggestDifference = Int.MIN_VALUE - - for (i in this.indices) { - for (j in (i + 1) until this.size) { - val first = this[i] - val second = this[j] - val absDifference = abs(first - second) - - if (absDifference >= biggestDifference) { - biggestDifference = absDifference - resultPair = Pair(first, second) - } - } - } - - return resultPair!! + require(this.size >= 2) { "List must have at least two integers." } + return this.sortedDescending().let { sortedList -> sortedList.first() to sortedList.last() } } fun main() { diff --git a/src/main/kotlin/exercise2/task4/ProcessCountriesData.kt b/src/main/kotlin/exercise2/task4/ProcessCountriesData.kt index 291e558..2d29d4c 100644 --- a/src/main/kotlin/exercise2/task4/ProcessCountriesData.kt +++ b/src/main/kotlin/exercise2/task4/ProcessCountriesData.kt @@ -59,27 +59,33 @@ 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() + .toList() + .sortedByDescending { it.second } + .first() + .first } 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..eddbd74 100644 --- a/src/main/kotlin/exercise2/task5/CreateUserDSL.kt +++ b/src/main/kotlin/exercise2/task5/CreateUserDSL.kt @@ -49,11 +49,11 @@ 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!!!") + return apply { address = Address().apply(initAddress) } } fun main() { diff --git a/src/main/kotlin/exercise3/task1/BalancedBrackets.kt b/src/main/kotlin/exercise3/task1/BalancedBrackets.kt index 7a6958d..8cef3e1 100644 --- a/src/main/kotlin/exercise3/task1/BalancedBrackets.kt +++ b/src/main/kotlin/exercise3/task1/BalancedBrackets.kt @@ -26,7 +26,21 @@ package exercise3.task1 internal fun isExpressionBalanced(expression: String): Boolean { - TODO("Implement me!!!") + val openBrackets = listOf('(', '[', '{') + val closedBrackets = listOf(')', ']', '}') + var brackets = mutableListOf() + + + for(char in expression) { + when(char) { + in openBrackets -> brackets.add(char) + ')' -> if(brackets.isEmpty() || brackets.removeAt(brackets.size - 1) != '(') return false + ']' -> if(brackets.isEmpty() || brackets.removeAt(brackets.size - 1) != '[') return false + '}' -> if(brackets.isEmpty() || brackets.removeAt(brackets.size - 1) != '{') return false + } + } + + return brackets.isEmpty() } fun main() { diff --git a/src/main/kotlin/exercise3/task2/ParenthesesClusters.kt b/src/main/kotlin/exercise3/task2/ParenthesesClusters.kt index 0e75083..8238567 100644 --- a/src/main/kotlin/exercise3/task2/ParenthesesClusters.kt +++ b/src/main/kotlin/exercise3/task2/ParenthesesClusters.kt @@ -24,11 +24,35 @@ package exercise3.task2 */ internal fun String.splitToBracketsClusters(): List { - TODO("Implement me!!!") + var clusters = mutableListOf() + var open = 0 + var builder = StringBuilder() + this.forEach { + when { + it == '(' -> { + open++ + builder.append('(') + } + it == ')' -> { + open-- + builder.append(')') + } + else -> throw IllegalArgumentException("Invalid character") + } + + if(open == 0) { + clusters.add(builder.toString()) + builder = StringBuilder() + } + + if(open < 0) return emptyList() + } + if(open != 0) return emptyList() else return clusters } fun main() { val expressionsToClustersCatalog = mapOf( + "()(" to listOf("()"), "()()()" to listOf("()", "()", "()"), "((()))" to listOf("((()))"), "((()))(())()()(()())" to listOf("((()))", "(())", "()", "()", "(()())"), @@ -41,4 +65,6 @@ fun main() { "Expression $expression should be split to $expression clusters, but actual value was $actualClusters." } } + + } diff --git a/src/main/kotlin/exercise3/task3/SherlockValidatesString.kt b/src/main/kotlin/exercise3/task3/SherlockValidatesString.kt index 55680b8..09a99af 100644 --- a/src/main/kotlin/exercise3/task3/SherlockValidatesString.kt +++ b/src/main/kotlin/exercise3/task3/SherlockValidatesString.kt @@ -17,7 +17,7 @@ package exercise3.task3 * s = abcc * This is a valid string because we can remove one `c` and have `1` of each character in the remaining string. * - * s = abccc + * s = abcc * This string is not valid as we can only remove `1` occurrence of `c`. That leaves character frequencies of * {`a`: 1, `b`: 1, `c`: 2}. * ``` @@ -29,7 +29,19 @@ package exercise3.task3 */ internal fun isSherlockValid(s: String): String { - TODO("Implement me!!!") + require(s.length in 1..100000) { "String length must be in range from 1 to 10^5" } + require(s.all{ it in 'a'..'z' }) { "String must only contain small letters (a..z)" } + + val occurrences = s.groupingBy { it }.eachCount().map { it.value } + val cMin = occurrences.min() + val cMax = occurrences.max() + + return when { + cMin == cMax -> "YES" + cMax - cMin == 1 && occurrences.count { it == cMax } == 1 -> "YES" + cMin == 1 && occurrences.count { it == cMin } == 1 && occurrences.count { it == cMax } == occurrences.size - 1 -> "YES" + else -> "NO" + } } fun main() { @@ -38,7 +50,6 @@ fun main() { stringsToValidityCatalog.forEach { (string, expectedIsValid) -> val actualIsValid = isSherlockValid(string) val errorMessageFactory = { answer: String -> if (answer == "YES") "is valid" else "is not valid" } - require(expectedIsValid == actualIsValid) { "String \"$string\" is ${errorMessageFactory(expectedIsValid)}," + " but actual value was ${errorMessageFactory(actualIsValid)}." diff --git a/src/main/kotlin/exercise3/task4/TaxiParkTask.kt b/src/main/kotlin/exercise3/task4/TaxiParkTask.kt index 0dfe831..3eacacd 100755 --- a/src/main/kotlin/exercise3/task4/TaxiParkTask.kt +++ b/src/main/kotlin/exercise3/task4/TaxiParkTask.kt @@ -10,7 +10,9 @@ package exercise3.task4 * Find all the drivers who performed no trips. */ internal fun TaxiPark.findFakeDrivers(): Set { - TODO("Implement me!!!") + val realDriversNames = this.trips.map { it -> it.driver}.toSet() + val allDriversNames = this.allDrivers + return allDriversNames.subtract(realDriversNames) } /** @@ -18,7 +20,14 @@ 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!!!") + //test ovde ne prolazi, nisam siguran zasto + return this.trips + .flatMap { it.passengers } + .groupingBy { it } + .eachCount() + .filter{ it.value >= minTrips } + .map { it.key } + .toSet() } /** @@ -26,7 +35,22 @@ 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!!!") + val allPassengers = mutableListOf() + this.trips + .filter { it.driver == driver } + .map { it.passengers } + .forEach { + it.forEach { + allPassengers.add(it) + } + } + + return allPassengers.groupingBy { it } + .eachCount() + .filter { it.value > 1 } + .map { it.key } + .toSet() + } /** @@ -34,5 +58,17 @@ internal fun TaxiPark.findFrequentPassengers(driver: Driver): Set { * Find the passengers who had a discount for the majority of their trips. */ internal fun TaxiPark.findSmartPassengers(): Set { - TODO("Implement me!!!") + val passengersMap = trips + .flatMap { t -> t.passengers.map { p -> p to (t.discount != null) } } + .groupBy({ it.first }, { it.second }) + + return passengersMap.filterValues { discounts -> + val withDiscount = discounts.count { it } + val noDiscount = discounts.size - withDiscount + withDiscount > noDiscount + } + .map { it.key } + .toSet() } + +