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>(), initialization
  • v[x], accesses the x-th element
  • v.add(x), appends x to end of v
  • v.last(), access the last element of v
  • v.removeLast(), pops the last element of v

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


<
Previous Post
Mushoku Tensei Puzzle
>
Blog Archive
Archive of all previous blog posts