Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ language: crystal
before_install:
- sudo apt-get -qq update
- sudo apt-get install -y ruby default-jdk haskell-platform python3
- curl -s "https://get.sdkman.io" | bash
- source "$HOME/.sdkman/bin/sdkman-init.sh"
- sdk install kotlin

install: make clean build

Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ build:
g++ -O2 main.cpp -o $(BIN_DIR)/cpp
javac -d $(BIN_DIR) Main.java
ghc -O2 main.hs -outputdir=$(BUILD_DIR) -o $(BIN_DIR)/haskell
kotlinc main.kt -include-runtime -d $(BIN_DIR)/kotlin.jar

test:
mkdir $(TMP_DIR)
Expand All @@ -32,4 +33,6 @@ test:
@cmp $(TMP_DIR)/crystal.out $(TMP_DIR)/haskell.out || (echo "Failed: Haskell" && exit 1)
python3 main.py < $(TMP_DIR)/test_data.in > $(TMP_DIR)/python3.out
@cmp $(TMP_DIR)/crystal.out $(TMP_DIR)/python3.out || (echo "Failed: Python3" && exit 1)
java -jar $(BIN_DIR)/kotlin.jar < $(TMP_DIR)/test_data.in > $(TMP_DIR)/kotlin.out
@cmp $(TMP_DIR)/crystal.out $(TMP_DIR)/kotlin.out || (echo "Failed: Kotlin" && exit 1)
@echo "Passed"
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,4 @@ Your output should consist of a single line for each test case containing n numb
- [scps940707](https://github.com/scps940707) YyWang - Java
- [sifmelcara](https://github.com/sifmelcara) mingchuan - Haskell
- [chuanchan1116](https://github.com/chuanchan1116) William Tsai - Python 3
- [david50407](https://github.com/david50407) David Kuo - Kotlin
89 changes: 89 additions & 0 deletions main.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import java.util.Scanner

const val THRESHOLD = 60

fun main(args: Array<String>) {
val reader = Scanner(System.`in`)

while (true) {
val n: Int = reader.nextInt()
if (n == 0) break

var ranks = IntArray(n)
var points = ArrayList<Point>()
repeat(n) { i ->
points.add(Point(i, reader.nextInt(), reader.nextInt()))
}

points.sort()

findRank(ranks, points)

println(ranks.joinToString(separator = " "))
}

reader.close()
}

fun <T> MutableList<T>.insertFrom(index: Int, to: Int) {
if (index == to) return
val tmp = this[index]
this.removeAt(index)
this.add(if (index > to) to else to - 1, tmp)
}

fun findRank(ranks: IntArray, points: MutableList<Point>) : List<Point> {
if (points.size <= 1) return points
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this is necessary for avoiding re-layout a ArrayList below (Line 55), this can be more efficiently in Kotlin.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it never get into this since points.size <= THRESHOLD cover this condition.

if (points.size <= THRESHOLD) {
repeat(points.size) {
if (it == 0) return@repeat

val currentPoint = points[it]
if (currentPoint.y < points[0].y) {
points.insertFrom(it, to = 0)
return@repeat
}

var i = it
while (true) {
if (currentPoint.y >= points[i - 1].y) break;
--i
}
points.insertFrom(it, to = i)
ranks[currentPoint.i] += i
}
return ArrayList<Point>(points)
}

val leftPoints = findRank(ranks, points.subList(0, points.size / 2))
val rightPoints = findRank(ranks, points.subList(points.size / 2, points.size))
var resultPoints = ArrayList<Point>()

var l: Int = 0
var r: Int = 0
while (true) {
if (leftPoints[l].y <= rightPoints[r].y) {
resultPoints.add(leftPoints[l++])
if (l == leftPoints.size) {
rightPoints.listIterator(r).forEach {
ranks[it.i] += l
resultPoints.add(it)
}
break
}
} else {
resultPoints.add(rightPoints[r])
ranks[rightPoints[r++].i] += l
if (r == rightPoints.size) {
resultPoints.addAll(leftPoints.subList(l, leftPoints.size))
break
}
}
}

return resultPoints
}

data class Point(val i: Int, val x: Int = 0, val y: Int = 0) : Comparable<Point> {
override fun compareTo(other: Point) : Int = if (this.x == other.x) this.y.compareTo(other.y) else this.x.compareTo(other.x)
}