Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
39 kB
6
Indexable
Never
kotlin.controlflow.datastructure

1. collections
    1.1. lists
        1.1.1. Exercise.kt

fun main() {
    sumOfList()
}

fun sumOfList() {
    val list = readln().split(" ").map { it.toInt() }.toList()
    println(list.sum())
}

#############################

        1.1.2. List.kt

fun main() {
    methodsAndProperties()
}

fun initialization() {
    val num = MutableList(3) {0}

    val cars = listOf("BMW", "Honda", "Mercedes")
    println(cars) // output: [BMW, Honda, Mercedes]

    // cars[0] = "Renault" // Error

    val staff = emptyList<String>()
    println(staff) // output: []

    val names = listOf("Emma", "Kim")
    val list = buildList {
        add("Marta")
        addAll(names)
        add("Kira")
    }
    println(list) // output: [Marta, Emma, Kim, Kira]

    var places = listOf<String>("Paris", "Moscow", "Tokyo") // note var keyword
    places += "Saint-Petersburg" // reassignment, slow operation
    println(places) // output: [Paris, Moscow, Tokyo, Saint-Petersburg]
}

fun methodsAndProperties() {
    val partyList = listOf("Fred", "Emma", "Isabella", "James", "Olivia")
    println(partyList.size)
    println(partyList.isEmpty())
    println(partyList.indices)
    println(partyList.indexOf("Thieu"))
    println(partyList.contains("Emma"))

    val sum = partyList.sumOf { it.length }
    println(sum)
}

fun iteration() {
    val participants = listOf("Fred", "Emma", "Isabella")

    for (participant in participants) {
        println("Hello $participant!")
    }

    for (index in participants.indices) {
        println(participants[index])
    }
}

#################################

        1.1.3. MutableList.kt

fun main() {
//    exercise()

}

fun initializing() {
    var cars = mutableListOf<String>()
    println(cars) // output: []

    cars = mutableListOf("Ford", "Toyota", "Audi", "Mazda", "Tesla")
    println(cars) // output: [Ford, Toyota, Audi, Mazda, Tesla]

    cars = listOf("Ford", "Toyota").toMutableList()
    cars.add("Tesla")
    println(cars) // output: [Ford, Toyota, Tesla]
}

fun addingAndReplacingElements() {
    // MutableList has the same properties and methods as List: size, get(index), isEmpty(), indexOf(element), contains(element), and so on.

    // it has additional functionality for changing the contents:
    val products  = mutableListOf("Milk", "Cheese", "Coke")
    products.add("Chips")
    products [0] = "Water" // or finalList.set(0, "Water")
    println(products ) // output: [Water, Cheese, Coke, Chips]

    val dadsProducts = listOf("Banana", "Watermelon", "Apple")
    products .addAll(dadsProducts)
}

fun removingElements() {
    val products = mutableListOf("Milk", "Cheese", "Coke")

    products.removeAt(0)
    println(products) // output: [Cheese, Coke]

    products.remove("Coke")
    println(products) // output: [Cheese]

    products.clear()
    println(products) // output: []
}

fun exercise() {
    val roots = mutableListOf<Int>()
    val a = readln().toInt()
    val b = readln().toInt()
    val c = readln().toInt()
    val d = readln().toInt()

    for (x in 0..1000) {
        if (a * x * x * x + b * x * x + c * x + d == 0) {
            roots.add(x)
        }
    }

    for (x in roots) {
        println(x)
    }
}

###################################

    1.2. maps
        1.2.1. Exercise.kt

fun main() {
    examMarks()
}

fun examMarks() {
    val studentsMarks = mutableMapOf<String, Int>()
    var name = ""
    var score = 0

    while(true) {
        name = readln()
        if (name == "stop") {
            break
        }
        score = readln().toInt()

        if (!studentsMarks.containsKey(name)) {
            studentsMarks[name] = score
        }
    }

    println(studentsMarks)
}

fun makeMyWishList(wishList: Map<String, Int>, limit: Int): MutableMap<String, Int> {
    // write here
    val limitWishList: MutableMap<String, Int> = wishList.filter { (_, price) ->
        price <= limit
    }.toMutableMap()

    return limitWishList
}

###################################

        1.2.2. Map.kt

fun main() {
    mapCollection()
    mapInitialization()
}

fun mapCollection() {
    // A Map is an immutable collection that holds pairs of objects (keys and values)
    // and supports efficiently retrieving values corresponding to each key.
    val student = mapOf(
        "Thieu" to 12,
        "Hien" to 10,
        "Tung" to 12,
        "Quan" to 11
    )
    println(student)  // {Thieu=1, Hieu=2, Tung=10, Quan=5}

    val grade = student["Thieu"]
    println("Thieu's grade is $grade")
}

fun mapElement() {
    // An entry in a Map is represented by the special Pair type designated for generic pairs of two values.
    var (name, grade) = Pair("Zhenya", 5) // easy way to get the first and the second values
    println("Student name is: $name And their grade is: $grade")

    val p = Pair(2, 3)
    println("${p.first} ${p.second}") // 2 3
    val (first, second) = p
    println("$first $second")

    val (name2, grade2) = "Vlad" to 4
    println("Student name is: $name2 And their grade is: $grade2")
}

fun mapInitialization() {
    // val staff = mapOf<String, Int>("John" to 1000)  // mapOf<K, V>(vararg pairs: Pair<K, V>
    val staff = mapOf("Mike" to 1500)

    // Empty map
    val emptyStringToDoubleMap = emptyMap<String, Double>()

    // Builder function
    val values = mapOf<String, Int>("Second" to 2, "Third" to 3)
    val map = buildMap<String, Int> {
        this["First"] = 1
        putAll(values)
        put("Fourth", 4)
    }
    println(map.values)
}

fun methodsAndProperties() {
    val employees = mapOf(
        "Mike" to 1500,
        "Jim" to 500,
        "Sara" to 1000
    )

    if (employees.isNotEmpty()) {
        println("Number of employees: ${employees.size}")
        println("Mike wants to earn ${employees["Mike"]}")
    }

    val isWanted = employees.containsKey("Jim")
    println("Does Jim want to be our employee? It's $isWanted")

    val isAnyoneWilling = employees.containsValue(500)
    println("Is anyone willing to earn $500? It's $isAnyoneWilling")
}

fun iterating() {
    val employees = mapOf(
        "Mike" to 1500,
        "Jim" to 500,
        "Sara" to 1000
    )

    for (employee in employees)
        println("${employee.key} ${employee.value}")

    for (names in employees.keys) { }

    for (earns in employees.values) { }

    for ((k, v) in employees)
        println("$k $v")

}

//fun bill(priceList: Map<String, Int>, shoppingList: MutableList<String>): Int {
//    // put your code here
//    var totalPrice = 0
//
//    for (product in shoppingList) {
//        if (priceList.containsKey(product)) {
//            totalPrice += priceList[product]
//        }
//    }
//
//    return totalPrice
//}

############################

        1.2.3. MutableMap.kt

fun main() {
    removingElements()
}

fun introduce() {
    var staff = mapOf( // you cannot reassign an immutable reference, so you need to use var
        "John" to 500,
        "Mike" to 1000,
        "Lara" to 1300
    )
    staff += "Jane" to 700 // reassignment
    println(staff) // output: {John=500, Mike=1000, Lara=1300, Jane=700}

    staff = mutableMapOf(
        "John" to 500,
        "Mike" to 1000,
        "Lara" to 1300
    )

    staff["Nika"] = 999

    println(staff) // output: {John=500, Mike=1000, Lara=1300, Nika=999}
}

fun initialization() {
    val students = mutableMapOf("Nika" to 19, "Mike" to 23)
    println(students) // output: {Nika=19, Mike=23}

    val mapCarsPerYear = mapOf(1999 to 30000, 2021 to 202111)
    val carsPerYear = mapCarsPerYear.toMutableMap()
    carsPerYear[2020] = 2020
    println(carsPerYear) // output: {1999=30000, 2021=202111, 2020=2020}}
}

fun addingElements() {
    // MutableMap has the same properties and methods as Map: size, isEmpty(), containsKey(key), containsValue(element), and so on.

    val groupOfStudents = mutableMapOf<String, Int>() // empty mutable map
    groupOfStudents.put("John", 4)
    groupOfStudents["Mike"] = 5
    groupOfStudents["Anastasia"] = 10

    val studentsFromOregon = mapOf("Alexa" to 7)

    groupOfStudents.putAll(studentsFromOregon)

    println(groupOfStudents) // output: {John=4, Mike=5, Anastasia=10, Alexa=7}

    // When you try to associate a specified value in the map with a key that already exists, the existing value will be overwritten.
    val groceries = mutableMapOf<String, Int>()
    groceries["Potato"] = 5
    println(groceries)  // output: {Potato=5}
    groceries["Potato"] = 10
    println(groceries)  // output: {Potato=10}

    // You can also add an element to a map using the plusAssign operator syntax, like in the example below:
    groceries += mapOf("Potato" to 5)
    groceries += "Sprite" to 1
    println(groceries)
}

fun removingElements() {
    val groceries = mutableMapOf(
        "Potato" to 10,
        "Coke" to 5,
        "Chips" to 7
    )

    groceries.remove("Potato")
    println(groceries) // output: {Coke=5, Chips=7}

    groceries.clear()
    println(groceries) // output: {}

    val cars = mutableMapOf<String, Double>()
    cars["Ford"] = 100.500
    cars["Kia"] = 500.15

    println(cars)  // output: {Ford=100.5, Kia=500.15}

    cars -= "Kia"
    cars -= "Thieu"
    println(cars)  // output: {Ford=100.5}
}

#######################################

    1.3. sets
        1.3.1. Exercise.kt

fun main() {
    comparison()

}

fun solution(strings: MutableList<String>): Set<String> {
    // put your code here
    return strings.toSet()
}

fun subtraction(numbers1: Set<Int>, numbers2: Set<Int>): Int {
    // put your code here
    return (numbers1 - numbers2).size
}

fun combination(first: Set<String>, second: Set<String>): Set<String> {
    // put your code here
    return first + second
}

fun comparison() {
    val numbers1 = setOf(8, 11, 12, 13)
    val numbers2 = setOf(8, 13, 12, 11)

    println(numbers1 == numbers2)  // true

    val mutableList = mutableListOf(13, 8, 12)
    println(numbers1.containsAll(mutableList))  // true
}

fun evenFilter(numbers: Set<Int>): Set<Int> {
    // put your code here
    return numbers.filter { num -> num % 2 == 0 }.toSet()
}

fun test (elements: MutableSet<Int>, element: Int): MutableSet<Int> {
    // put your code here
    return if (elements.contains(element)) {
        mutableSetOf()
    } else {
        elements
    }
}

fun solution(setSource: Set<String>, listSource: MutableList<String>): MutableSet<String> {
    // put your code here
    return (setSource + listSource.toSet()).toMutableSet()
}

fun numberInASet() {
    val n = readln().toInt()

    val mySet = mutableSetOf<Int>()
    repeat(n) {
        mySet.add(readln().toInt())
    }

    val m = readln().toInt()

    println(
        if (mySet.contains(m)) "YES" else "NO"
    )
}

fun littleMoreAndLittleLess(newSet: MutableSet<String>, oldSet: Set<String>): MutableSet<String> {
    newSet.addAll(oldSet.filter { it.startsWith("A", ignoreCase = true) })
    return newSet
}

##################################

        1.3.2. MutableSet.kt

fun main() {

}

fun initialization() {
    val students = mutableSetOf("Joe", "Elena", "Bob")
    println(students) // [Joe, Elena, Bob]

    val points = mutableSetOf<Int>()
    println(points) // []

    val students2 = setOf("Joe", "Elena", "Bob").toMutableSet()
    students2.add("Bob")
    println(students2) // [Joe, Elena, Bob]
}

fun addingElements() {
    // MutableSet has the same properties and methods as Set: size, isEmpty(), indexOf(element), contains(element), first(), last(), and so on.

    val words = mutableSetOf<String>("Apple", "Coke")
    val friendsWords = mutableSetOf<String>("Banana", "Coke")

    words.add("Phone")
    words.add("Controller")

    friendsWords.add("Phone")
    friendsWords.add("Pasta")
    friendsWords.add("Pizza")

    words.addAll(friendsWords)

    val addWords: Set<String> = words.plus("Orange")  // plus() khong them vao Mutable Set cu ma tra ve mot Set moi

    println(words) // [Apple, Coke, Phone, Controller, Banana, Pasta, Pizza]
}

fun removingElements() {
    val groceries = mutableSetOf("Apple", "Water", "Banana", "Pen")

    groceries.remove("Apple")
    println(groceries) // [Water, Banana, Pen]

    val uselessGroceries = setOf("Banana", "Pen")
    groceries.removeAll(uselessGroceries)
    println(groceries) // [Water]

    groceries.clear()
    println(groceries) // []
}

fun iteratingThroughElements() {
    val places = mutableSetOf("Saint-Petersburg", "Moscow", "Grodno", "Rome")

    for (place in places) {
        println(place)
    }

    // Saint-Petersburg
    // Moscow
    // Grodno
    // Rome
}

######################################

        1.3.3. Set.kt

/*
Set is an unordered collection of elements that does not allow duplicates. It is an immutable collection
 */

fun main() {
//    introducing()
//    methodsAndProperties()
    iterating()
}

fun introducing() {
    val visitors = setOf<String>("Vlad", "Vanya", "Liza", "Liza")
    println(visitors) // output: [Vlad, Vanya, Liza]
}

fun setInitialization() {
    val languages = setOf("English", "Russian", "Italian")

    val numbers = emptySet<Int>()
    println(numbers) // output: []

    val letters = setOf<Char>('b', 'c')
    val set = buildSet<Char> {
        add('a')
        addAll(letters)
        add('d')
    }
    println(set) // output: [a, b, c, d]
}

fun methodsAndProperties() {
    val visitors = setOf("Andrew", "Mike", "Paula", "Tanya", "Julia")

    println("How many people visited our cafe today? ${visitors.size}") // 2
    println("Was our cafe empty today? It's ${visitors.isEmpty()}") // Was our cafe empty today? It's false

    println("Is it true that Tanya came? It's ${visitors.contains("Tanya")}") // Is it true that Tanya came? It's true
    println("And what is her index? ${visitors.indexOf("Tanya")}" ) // And her index is 3

    println(visitors.first())
    println(visitors.last())

    println(visitors.joinToString())

    val studentsOfAGroup = setOf("Bob", "Larry", "Vlad")
    val studentsInClass = setOf("Vlad")
    println("Are all the students in the group in class today? It's ${studentsInClass.containsAll(studentsOfAGroup)}")

    val productsList1 = setOf("Banana", "Lime", "Strawberry")
    val productsList2 = setOf("Strawberry")

    val finalProductsList1 = productsList1 + productsList2
    println(finalProductsList1) // [Banana, Lime, Strawberry]

    val finalProductsList2 = productsList1 - productsList2
    println(finalProductsList2) // [Banana, Lime]

    val groceries = mutableListOf("Pen", "Pineapple", "Apple", "Super Pen", "Apple", "Pen")
    println(groceries.toSet()) // [Pen, Pineapple, Apple, Super Pen]
}

fun iterating() {
    val visitors = setOf("Vlad", "Liza", "Vanya", "Nina")

    for (visitor in visitors ) {
        println("Hello $visitor!")
    }

    // output:
    // Hello Vlad!
    // Hello Liza!
    // Hello Vanya!
    // Hello Nina!

}

#########################################

    1.4. Collections.kt

/*
Collections are containers that support various ways to store and organize different objects and make them easily accessible.
A collection usually contains a number of objects (this number may be zero) of the same type.

Collections are an implementation of abstract data structures that can support the following operations:
    retrieving an element;
    removing an element;
    changing or replacing an element;
    adding a new element.

However, it is important to note that operations like adding, removing, and changing elements only apply to mutable collections.

Kotlin Standard Library provides the implementation for the basic types of collections: list, set, and map.
All three exist in mutable and immutable variations.
 */

fun main() {

}

fun commonPropertiesAndMethods() {
    // size - returns the size of your collection.
    // contains(element) - checks if the element is in your collection.
    // containsAll(elements) - checks if all elements of the collection elements are in your collection.
    // isEmpty() - shows whether the collection is empty or not.
    // joinToString() - converts the collection to a string.
    // indexOf(element) returns the index of the first entry of the element, or -1 if the element is not in the collection.

    // In addition, all mutable collections have some common methods. You can use them with any mutable collection, but they cannot be used with an immutable collection:
    // clear() - removes all elements from the collection.
    // remove(element) - removes the first occurrence of an element from your collection.
    // removeAll(elements) - removes from your collection all elements contained in the collection elements.
}

#####################################

2. datatype
    2.1. array
        2.1.1. Arrays.kt

fun main() {
//    creatingArrayWithSpecifiedElements()
//    creatingArrayWithSpecifiedSize()
//    readingArrayFromInput()
    comparingArrays()
}

fun creatingArrayWithSpecifiedElements() {
    // Kotlin can handle many types of arrays: IntArray, LongArray, DoubleArray, FloatArray, CharArray, ShortArray, ByteArray, BooleanArray
    // Note that Kotlin doesn't have a default StringArray type.

    // To create an array of a specified type, we need to invoke a special function and pass all elements to store them together

    val numbers = intArrayOf(1, 2, 3, 4, 5) // It stores 5 elements of the Int type
    println(numbers) // [I@214c265e
    println(numbers.joinToString()) // 1, 2, 3, 4, 5

    val characters = charArrayOf('K', 't', 'l') // It stores 3 elements of the Char type
    println(characters.joinToString()) // K, t, l

    val doubles = doubleArrayOf(1.25, 0.17, 0.4) // It stores 3 elements of the Double type
    println(doubles.joinToString()) // 1.25, 0.17, 0.4
}

fun creatingArrayWithSpecifiedSize() {
    // To create an array of a certain size, we need to write its type and pass it after the type name in round brackets (the constructor)

    val numbers = IntArray(5) // an array of 5 integer numbers
    println(numbers.joinToString()) // 0, 0, 0, 0, 0

    val doubles = DoubleArray(7) // an array of 7 doubles
    println(doubles.joinToString()) // 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0

    // Another option is to use the Array constructor that takes the array size and the function

    var num = IntArray(10) {
        if(it % 2 == 0) {
            it
        } else {
            it * 2
        }
    }
    println("num: ${num.joinToString()}") // 0, 2, 2, 6, 4, 10, 6, 14, 8, 18

    val onlyOne = IntArray(10) { 1 }
    println("Only 1: ${onlyOne.joinToString()}")

    val onlyMinusOne = IntArray(10).apply { fill(-1) }
    println("Only -1: ${onlyMinusOne.joinToString()}")
}

fun readingArrayFromInput() {
    // on each line single numbers from 1 to 5
    var numbers = IntArray(5) { readln().toInt() }
    println(numbers.joinToString()) // 1, 2, 3, 4, 5

    // read an array in a single line
    numbers = readln().split(" ").map { it.toInt() }.toIntArray()
    println(numbers.joinToString())

    // Mot cach khac cho phep bo qua ngat dong va extra spaces trong input
    // Su dung regular expressions

    val regex = "\\s+".toRegex()
    val str = "1 2\t\t3 4\n5 6"
    println(str)
    val nums = str.split(regex).map { it.toInt() }.toTypedArray()
    println(nums.joinToString()) // 1, 2, 3, 4, 5, 6
}

fun arraySize() {
    // You cannot change the size of an array, but you can modify the elements.
    val numbers = intArrayOf(1, 2, 3, 4, 5)
    println(numbers.size) // 5
}

fun accessingElements() {
    val numbers = IntArray(3) // numbers: 0, 0, 0

    numbers[0] = 1 // numbers: 1, 0, 0
    numbers[1] = 2 // numbers: 1, 2, 0
    numbers[2] = numbers[0] + numbers[1] // numbers: 1, 2, 3

    println(numbers[0]) // 1, the first element
    println(numbers[2]) // 3, the last element

    val alphabet = charArrayOf('a', 'b', 'c', 'd')
    println(alphabet.first())   // 'a'
    println(alphabet.last())    // 'd'
    println(alphabet.lastIndex) // 3
}

fun comparingArrays() {
    val numbers1 = intArrayOf(1, 2, 3, 4)
    val numbers2 = intArrayOf(1, 2, 3, 4)
    val numbers3 = intArrayOf(1, 2, 3)

    println(numbers1.contentEquals(numbers2)) // true
    println(numbers1.contentEquals(numbers3)) // false

    val simpleArray = intArrayOf(1, 2, 3, 4)
    val similarArray = intArrayOf(1, 2, 3, 4)

    println(simpleArray == simpleArray)  // true, simpleArray points to the same object
    println(simpleArray == similarArray) // false, similarArray points to another object
}

########################################

    2.2. booleans
        2.2.1. Boolean.kt

/*
 Trong Kotlin (va Java), khong the gan gia tri integer cho bien Boolean -> 0 khong giong nhu false
 */

fun main() {
    val t = true  // t is true
    val f = false // f is false
    println(t) // true
    println(f) // false

    val b: Boolean = readlnOrNull()!!.toBoolean() // True -> true, TRuE -> true,..
    println(b)

    println("true".toBooleanStrict())     // true
    // println("True".toBooleanStrict())  // program crashes
    println("false".toBooleanStrict())    // false
    // println("faLse".toBooleanStrict()) // program crashes

    println("true".toBooleanStrictOrNull())  // true
    println("false".toBooleanStrictOrNull()) // false
    println("faLse".toBooleanStrictOrNull()) // null

    val b1 = false xor false // false
    val b2 = false xor true  // true
    val b3 = true xor false  // true
    val b4 = true xor true   // false
}

########################################

    2.3. chartype
        2.3.1. Character.kt

fun main() {
    readCharacter()
    val lowerCaseLetter: Char = 'a'
    val upperCaseLetter: Char = 'Q'
    val number: Char = '1'
    val space: Char = ' '
    val dollar: Char = '$'

    var ch = '\u0040' // it represents '@'
    println(ch) // @

}

fun readCharacter() {
    val ch = readln().first()
    println(ch.isUpperCase() || ch.isDigit() && ch != '0')
}

fun convert() {
    var ch = 'a'
    println(ch.code)   // 97
    val num = 97
    println(num.toChar()) // a
}

fun howToReadCharacters() {
    val ch: Char = readln().first()
}

fun retrievingSubsequentCharacters() {
    val ch1 = 'b'
    val ch2 = ch1 + 1 // 'c'
    val ch3 = ch2 - 2 // 'a'

    // val ch2 = 1 + ch1 // Error
    // val charSum = 'a' + 'b' // Error

    var ch = 'A'
    ch += 10
    println(ch)   // 'K'
    println(++ch) // 'L'
    println(++ch) // 'M'
    println(--ch) // 'L'
}

fun escapeSequences() {
//    '\n' is the newline character;
//
//    '\t' is the tab character;
//
//    '\r' is the carriage return character;
//
//    '\\' is the backslash character itself;
//
//    '\'' is the single quote mark;
//
//    '\"' is the double quote mark.

    print('\t') // makes a tab
    print('a')  // prints 'a'
    print('\n') // goes to a new line
    print('c')  // prints 'c'
}

fun relationalOperations() {
    println('a' < 'c')  // true
    println('x' >= 'z') // false

    println('D' == 'D') // true
    println('Q' != 'q') // true because capital and small letters are not the same

    println('A' < 'a')  // true because capital Latin letters are placed before small ones
}

fun processingCharacters() {
    println('1'.isDigit())

    println('A'.isLetter())

    println('a'.isLetterOrDigit())

    println('A'.isUpperCase())

    println('b'.isLowerCase())

    println(' '.isWhitespace() && '\n'.isWhitespace() && '\t'.isWhitespace())

    println('e'.uppercase()) // "E"

    println('e'.uppercaseChar()) // 'E'
}

####################################

    2.4. conversion
        2.4.1. Conversion.kt

import kotlin.math.sqrt

fun main() {
    // Kotlin does not permit implicit conversions to avoid precision loss or unforeseen outcomes.
    // For instance, a Long cannot automatically convert to an Int.

    val longValue = 100L
    //val intValue: Int = longValue

    bestPractices()
}

fun explicitTypeConversion() {
    // Type cast

    val num: Int = 100

    val res: Double = sqrt(num.toDouble())
    println(res) // 10.0
    println(num) // 100, it is not modified

    val smallNum: Short = num.toShort()
    val bigNum: Long = num.toLong() // Khi chuyen tu loai be sang loai lon cung bat buoc phai su dung ham (Khac voi Java)

    val ch: Char = num.toChar()
    val n1: Int = ch.code

    val l: Long = 100_000_000_000_000
    val n2: Int = l.toInt() // 276447232; type overflow
    println(n2)

    // Chu y khi convert sang kieu Short hoac Byte
    val floatNumber = 10f
    val doubleNumber = 1.0

    // val shortNumber = floatNumber.toShort() // avoid this
    // val byteNumber = doubleNumber.toByte()  // avoid this

    val shortNumber = floatNumber.toInt().toShort() // correct way
    val byteNumber = doubleNumber.toInt().toByte()  // correct way

    // String conversion
    val n = 8     // Int
    val d = 10.09 // Double
    val c = '@'   // Char
    val b = true  // Boolean

    val s1 = n.toString() // "8"
    val s2 = d.toString() // "10.09"
    val s3 = c.toString() // "@"
    val s4 = b.toString() // "true"

    val b1 = "false".toBoolean() // false
    val b2 = "tru".toBoolean()   // false
    val b3 = "true".toBoolean()  // true
    val b4 = "TRUE".toBoolean()  // true
}

fun bestPractices() {
    // Use Explicit Conversions
    var intValue: Int = "123".toInt()

    // Check for null
    var strOrNull: String? = null
    var intOrNullValue: Int? = strOrNull?.toInt()

    // Handle NumberFormatException
    var str = "abc"
    intOrNullValue = try {
        str.toInt()
    } catch (e: NumberFormatException) {
        null
    }

    // Avoid loss of precision
    var longValue = 1_000_000_000L
    intValue = longValue.toInt()

    // Smart Casts with is
    if (strOrNull is String) {
        println(strOrNull.length)
    }

    // Use the as? Operator for Safe Casting: Use as? to safely cast to a type and to avoid ClassCastException.
    // This will return null if the operation fails.
    var x: Any = "Kotlin"
    var s: String? = x as? String  // s = "Kotlin"

    x = 1
    s = x as? String  // s = null


}

#########################################

        2.4.2. SmartCast.kt

fun main() {
    // unsafeCastOperator()
    // safeCastOperator()

    exampleFunction1<String>(123)
}

fun isOperator() {
    val obj: Any = "Hello, Kotlin"
    if (obj is String) {
        println(obj.uppercase())
    } else {
        println("obj is not a String")  // obj !is String
    }

    // idioms in Kotlin
    fun processInput(input: Any) {
        when (input) {
            is Int -> println("Input is an integer")
            is String -> println("Input is a string")
            is Double -> println("Input is a double")
            else -> println("Unknown input")
        }
    }
}

fun smartCast() {
    // When a nullable type is checked with the is operator,
    // Kotlin automatically casts the object to a non-nullable type.
    fun printLength(obj: Any) {
        if (obj is String) {
            println(obj.length)
        }
    }
}

fun unsafeCastOperator() {
    // The as keyword is used to cast an object to a non-nullable type.
    // If the object cannot be cast to the specified type, the as operator throws a ClassCastException.
    var obj: Any = "Hello, Kotlin"
    var str: String = obj as String // Unsafe cast operator
    println(str.uppercase())

    obj = 1.2
    var intValue: Int = obj as Int
    println(intValue)  // ClassCastException.
}

fun safeCastOperator() {
    // The as? operator is used to cast an object to a nullable type.
    // If the object cannot be cast to the specified type, the as? operator returns null.
    val obj: Any = 123
    val str: String? = obj as? String // Safe (nullable) cast operator
    if (str != null) {
        println(str.uppercase())
    }
}

// Generics type checks and casts
// Note: actual type of a generic object is not known at runtime
// Therefore, certain operations, like creating a new instance of a type parameter or
// checking if a type parameter is a subtype of another class, are not possible.
inline fun <reified T> exampleFunction1(obj: Any) {
    if (obj is T) {
        println("obj is an instance of type parameter T")
    } else {
        println("obj is not an instance of type parameter T")
    }
}

fun <T> exampleFunction2(obj: Any) {
    val tObj: T? = obj as? T
    if (tObj != null) {
        // obj can be safely cast to type parameter T
    } else {
        // obj cannot be cast to type parameter T
    }
}

#####################################

        2.4.3. TypeCoercion.kt

fun main() {
    val num: Int = 100
    val longNum: Long = 1000
    val result = num + longNum // 1100, Long

    val bigNum: Long = 100000
    val doubleNum: Double = 0.0
    val bigFraction = bigNum - doubleNum // 100000.0, Double

    // Short and Byte
    val one: Byte = 1
    val two: Byte = 2
    val three = one + two // 3, Int

    val fourteen: Short = 14
    val ten: Short = 10
    val four = fourteen - ten // 4, Int

    val hundred: Short = 100
    val five: Byte = 5
    val zero = hundred % five // 0, Int

    val six: Byte = 6
    val seven: Byte = 7
    val eleven = (six + seven).toByte() // 11, Byte
}

##################################

    2.5. floatingpoint
        2.5.1. FloatingPointType.kt

import java.util.*

fun main() {
    // Double
    val one = 1.0
    val negNumber = -1.75
    val pi = 3.1415

    // Float
    val b: Float = 8.75f
    val e = 2.71828f

    val number = one + 1.5 // 2.5
    val c = b + negNumber  // 7, Double, the type is inferred from the context

    errorDuringComputation()

    val floatNum = readln().format(Locale.US).toFloat()
    println(floatNum)

    exploringPackages()
}

fun errorDuringComputation() {
    println(3.3 / 3) // prints 1.0999999999999999

    val num = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1
    println(num) // it prints 0.9999999999999999
}

fun decimalSeparator() {
    // It is crucial to use the correct decimal separator.
    // The separator is locale-dependent, such as a dot for the US locale.
    val floatNum = readln().format(Locale.US).toFloat()
}

fun exploringPackages() {
    val a: Int = 10
    println(a.inc())
}

#################################

    2.6. integer
        2.6.1. IntegerNumber

fun main() {
    intAndLongIntegerType()
}

fun intAndLongIntegerType() {
    val two = 2  // Int
    val ten = 10 // Int

    val twelve = two + ten // 12
    val eight = ten - two  // 8
    val twenty = two * ten // 20
    val five = ten / two   // 5
    val zero = ten % two   // 0, no remainder

    val longNumber1 = 1_000_000_000_000_000
    val longNumber2: Long = 1_000_000
    val longNumber3 = 1000L

    val result = longNumber1 + longNumber2 - longNumber3
    println(result) // 1000000000999000
}

/*
 an unsigned 8-bit integer, ranges from 0 to 255
 an unsigned 16-bit integer, ranges from 0 to 65535
 an unsigned 32-bit integer, ranges from 0 to 4 294 967 295 (2^32-1)
 an unsigned 64-bit integer, ranges from 0 to 18 446 744 073 709 551 615 (2^64-1)
 */
fun unsignedInteger() {
    val uByte: UByte = 5u
    val uShort: UShort = 10U
    val smallSize = 100u // UInt by default
    val smallLong = 10uL // ULong because it is marked with "uL"


}

#################################

    2.7. nullable
        2.7.1. NullableAndNonNullable.kt

fun main() {
    nullability()
    accessingNullableVariable()
}

fun nullability() {
    // There are just a few ways how NPE may occur in Kotlin:
    // 1. explicit call of throw NullPointerException()
    // 2. !! syntax
    // 3. bad initializations, such as constructors and superclass constructors

    // Every reference in Kotlin can be either nullable or not.
    var str: String = "abc" // non-nullable variable
    var name: String? = null // nullable variable

    println(name)
}

fun accessingNullableVariable() {
    var name: String? = null

    if (name != null) {
        print(name.length)
    }

    println(name?.length) // This ?. pair of symbols is called a safe call in Kotlin.
    println(name?.length ?: 0)
}

#################################

    2.8. string
        2.8.1. StringBasics.kt

fun main() {

    rawString()
}

fun lengthOfString() {
    val language = "Kotlin"
    println(language.length) // 6
}

fun concatenatingString() {
    val one = "1"
    val two = "2"
    val twelve = one + two
    println(one)      // 1, no changes
    println(two)      // 2, no changes
    println(twelve)   // 12
}

fun appendingValuesToString() {
    val stringPlusBoolean = "abc" + 10 + true
    println(stringPlusBoolean) // abc10true

    // val errorString = 10 + "abc" // an error here!

    val charPlusString = 'a' + "bc"
    println(charPlusString) // abc
    val stringPlusChar = "de" + 'f'
    println(stringPlusChar) // def
}

fun repeatString() {
    print("Hello".repeat(4)) // HelloHelloHelloHello
}

fun rawString() {
    // escape sequences
    println("\'H\' is the first letter of \"Hello world!\" string.")

    // raw string
    val largeString = """
    This is the house that Jack built.
      
    This is the malt that lay in the house that Jack built.
       
    This is the rat that ate the malt
    That lay in the house that Jack built.
       
    This is the cat
    That killed the rat that ate the malt
    That lay in the house that Jack built.
    """.trimIndent() // removes the first and the last lines and trims indents
    println(largeString)

    val unevenString = """
        123
         456
          789""".trimIndent()
    print(unevenString)
    println()

    val rawString = """123
         456
          789
    """.trimIndent()
    print(rawString )
}

#################################

        2.8.2. StringTemplates.kt

fun main() {
    getPattern()

}

fun stringTemplate() {
    val city = "Paris"
    val temp = "24"

    println("Now, the temperature in $city is $temp degrees Celsius.")
}

const val month = "(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)"
fun getPattern(): String = """\d{2} $month \d{4}"""

fun templateForExpression() {
    val language = "Kotlin"
    println("$language has ${language.length} letters in the name")
    println("$language has $language.length letters in the name")
}

################################

        2.8.3. TripleQuoted.kt

const val question = "life, the universe, and everything"
const val answer = 42

val tripleQuotedString = """
    question = "$question"
    answer = $answer""".trimIndent()

fun main() {
    println(tripleQuotedString)
}

#################################

        2.8.4. WorkWithStrings.kt

fun main() {
    val array = readln().split(" ")
    println("${array[0][0]}. ${array[1]}, ${array[2]} years old")
}

fun accessCharacters() {
    val greeting = "Hello"

    val first = greeting[0]  // 'H'
    val second = greeting[1] // 'e'
    val five = greeting[4]   // 'o'

    val last = greeting[greeting.length - 1] // 'o'
    val prelast = greeting[greeting.length - 2] // 'l'

    println(greeting.first())   // 'H'
    println(greeting.last())    // 'o'
    println(greeting.lastIndex) // 4
}

fun emptyString() {
    val emptyString = ""
    println(emptyString.length == 0) //true
    println(emptyString.isEmpty()) //true
}

fun immutability() {
    val valString = "string"
    // valString[3] = 'o' // an error here!
    var varString = "string"
    // varString[3] = 'o' // an error here too!
    varString = "strong" // legal
}

fun comparingStrings() {
    val first = "first"
    val second = "second"
    var str = "first"

    println(first == str)    // true
    println(first == second) // false
    println(first != second) // true
}

#######################################

    2.9. Main.kt

fun main() {

    // Integer
    val zero = 0 // Int
    val one = 1  // Int
    val oneMillion = 1_000_000  // Int

    val twoMillion = 2_000_000L           // Long because it is tagged with L
    val bigNumber = 1_000_000_000_000_000 // Long, Kotlin automatically chooses it (Int is too small)
    val ten: Long = 10                    // Long because the type is specified

    val shortNumber: Short = 15 // Short because the type is specified
    val byteNumber: Byte = 15   // Byte because the type is specified

    // Floating-point
    val pi = 3.1415              // Double
    val e = 2.71828f             // Float because it is tagged with f
    val fraction: Float = 1.51f  // Float because the type is specified

    println(Int.MIN_VALUE)  // -2147483648
    println(Int.MAX_VALUE)  // 2147483647
    println(Long.MIN_VALUE) // -9223372036854775808
    println(Long.MAX_VALUE) // 9223372036854775807

    println(Int.SIZE_BYTES) // 4
    println(Int.SIZE_BITS)  // 32

    // Character
    val lowerCaseLetter = 'a'
    val upperCaseLetter = 'Q'
    val number = '1'
    val space = ' '
    val dollar = '$'

    // Boolean
    val enabled = true
    val bugFound = false

    // String
    val creditCardNumber = "1234 5678 9012 3456"
    val message = "Learn Kotlin instead of Java."
    val greeting: String
    greeting = "Hello"
}

#######################################

    2.10. Range.kt

fun main() {
    val a = 1
    var b = 10
    var c = 11
    val within = c in a..b  // a <= c && c <= b

    // a..b is a closed-ended range.
    // a until b is a open-ended range.

    println(5 in 5 until  15)  // true
    println(15 in 5 until 15) // false

    var withinExclRight = c in a..b - 1 // a <= c && c < b
    withinExclRight = c in a until b // a <= c && c < b (the recommended way)

    val notWithin = 100 !in 10..99 // true

    val range = 10..20 // IntRange
    println(30 in range) // false

    println('b' in 'a'..'c') // true
    println('k' in 'a'..'e') // false
    println("hello" in "he".."hi") // true
    println("abc" !in "aab".."aac") // true
}

#######################################

    2.11. TypeSystem.kt

/*
Kotlin la ngon ngu go kieu tinh (statically-typed language), co nghia la no thuc hien kiem tra kieu trong qua trinh
bien dich -> loi duoc kiem tra truoc khi chuong trinh chay -> dan den ma it loi hon va dang tin cay hon
 */

fun main() {
    staticTyping()

}

fun staticTyping() {
    // Kotlin's static typing assures that the types of variables are known at compile time,
    // optimising performance and improving clarity.
    val message: String = "Hello, Kotlin!"
    println(message)
}

fun advantagesOfTypeSystem() {
    // Null safety
    var a: String = "abc"
    //a = null // Compile error

    var b: String? = "abc"
    b = null // OK

    // Smart casts
    if (b is String) {
        println(b.length)
    }

    // Type inference: Kotlin has efficient type inference capabilities, indicating you don't always need to state the type clearly.
    val language = "Kotlin" // Type inferred as String

    // Extension Functions
    fun String.addExclamation() = "$this!"
    println("Hello".addExclamation()) // Output: Hello!
}
Leave a Comment