Kotlin CP Reference
Today, I participated in Kotlin Heros 11. I got 4th place, narrowly missing out on getting USD128 :( Anyways, I have participated in a few Kotlin Heros contests before but today is the first time where I actually coded mainly in Kotlin, as in previous contests, I just coded in C++ and use gpt to convert to Kotlin… so here is my reference to my future self for future editions of Kotlin Heros
Compilation
$ kotlinc A.kt
$ kotlin AKt.class
Compiling a Kotlin file produces some .class
files, one for the the entire program and others for various classes in your program. As far as I can tell, the main .class
is named {X}Kt.class
? I don’t know a way to change it either, so that’s about it
IO
I forgot where i copied this from, but this is fast
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
import java.util.*
import kotlin.math.*
class Reader(inputStream: InputStream) {
private val reader = BufferedReader(InputStreamReader(inputStream))
private var tokenizer: StringTokenizer? = null
fun next(): String {
while (true) {
tokenizer.let {
if (it == null || !it.hasMoreTokens()) {
tokenizer = StringTokenizer(reader.readLine())
} else {
return it.nextToken()
}
}
}
}
}
val reader = Reader(System.`in`)
fun read() = reader.next()
fun readInt() = read().toInt()
fun readLong() = read().toLong()
fun readDouble() = read().toDouble()
fun readStrings(n: Int) = Array(n) { read() }
fun readInts(n: Int) = IntArray(n) { readInt() }
fun readLongs(n: Int) = LongArray(n) { readLong() }
fun readDoubles(n: Int) = DoubleArray(n) { readDouble() }
Output is quite simple, it is print()
and println()
which is quite intuitive to use
Both functions accepts template arguments such as print("$a $b")
, be careful when printing a[i]
as we have to do print("${a[i]}")
or else our compiler will think that we are doing print("${a}[i]")
.
Basic Syntax
Variables are declared as var name:type = value
, we can omit either type
or value
(but not both) and the compiler will infer it
Kotlin does not have automatic type upgrading, that means you cannot assign a Long
value to a Int
. This is particularly annoying if you are like me and use #define int long long
because array indices are forced to be Int
. Another annoying case is that in C++ we are used to doing stuff like if (x)
to check that Int x
is not zero, but in Kotlin, we need to explicitly make it into a Boolean
expression
Bitwise operations have totally different syntax, see https://www.programiz.com/kotlin-programming/bitwise
tl;dr, the operations are or
, and
, xor
, inv()
, shl
and shr
For loops have the following syntax
for (i in a..b)
for (i in b downTo a)
for (i in a..b step c)
for (i in b downTo a step c)
The equivalent code in C++ is
for (int i=a;i<=b;i++)
for (int i=b;i>=a;i--)
for (int i=a;i<=b;i+=c)
for (int i=b;i>=a;i-=c)
A useful loop in Kotlin is repeat(x){}
, for problems with multitest, it is useful to write repeat(readInt()){}
Functions have the syntax fun name(arg1:type1, arg2:type2):type {}
, type
can be ommitted when the compiler can infer it but the argument types cannot be ommited.
Suppose we want to unpack the elements of an array arr
, the correct syntax is var (a,b,c) = arr
, this is most useful when reading multiple variables where we can write var (a,b,c) = readInts(3)
.
We can also import whatever class we want from Java. An example is CF1958H where we have to use big integer, so we just import import java.math.BigInteger
.
Pairs and Structs
Pairs are supported natively in Kotlin. The datatype is defined by Pair<type1,type2>
, but of course we can omit it when defining variables to give the syntax var a = Pair(v1,v2)
. We access elements as a.first
and a.second
The analogue of structs is data
, see https://kotlinlang.org/docs/data-classes.html.
The syntax is quite intuitive, you create a new data
with data class A(var a: type1, var b: type1)
, create a new object with var obj = A(x,y)
and then access variables inside objects with obj.a
and obj.b
.
Lists and Sorting
Arrays have the syntax var arr = Array<type>(len){ value }
, we can omit either type but cannot omit value. Therefore something like a 2D array can be defined like var arr = Array(len){ Array(len2){0} }
, where it is shorthand for the super long var arr = Array<Array<Int>>(len){ Array<Int>(len2){0} }
. Accessing and modifying elements is the usual arr[x]
.
ArrayLists are same as Java ArrayList, the syntax is:
var v = ArrayList<type>()
, initializationv[x]
, accesses thex
-th elementv.add(x)
, appendsx
to end ofv
v.last()
, access the last element ofv
v.removeLast()
, pops the last element ofv
Syntax for sorting is arr.sort()
, we can also sort by customer comparator with syntax arr.sortWith(compareBy{brr[it]});
Segment Tree
Code taken from https://codeforces.com/contest/1571/submission/236726134.
class Seg(){
var arr : Array<Long> = Array(300005*4){-1000000000000000000}
fun update(i:Int, k:Long, s:Int = 0, e:Int = 300005, u:Int = 1){
var m=(s+e)/2
arr[u]=max(arr[u],k)
if (s==e) return
else{
if (i<=m) update(i,k,s,m,u*2)
else update(i,k,m+1,e,u*2+1)
}
}
fun query(i:Int,j:Int, s:Int = 0, e:Int=300005,u:Int=1):Long{
var m=(s+e)/2
if (s==i && e==j) return arr[u]
else if (j<=m) return query(i,j,s,m,u*2)
else if (m<i) return query(i,j,m+1,e,u*2+1)
else return max(query(i,m,s,m,u*2),query(m+1,j,m+1,e,u*2+1))
}
}
If I am doing anything stupid, please tell me in the comments because I only cared that my code compiles