Skip to content

Commit b4acb93

Browse files
committed
added sort measurement
1 parent b45e931 commit b4acb93

File tree

8 files changed

+156
-12
lines changed

8 files changed

+156
-12
lines changed

src/kotlin/sequential/sorting/_measurement/BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library")
33
package(default_visibility = ["//sequential/sorting:__subpackages__"])
44

55
kt_jvm_library(
6-
name = "_measurement",
6+
name = "measurement",
77
srcs = glob(["*.kt"]),
88
)

src/kotlin/sequential/sorting/_measurement/MeasuredElements.kt

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package sequential.sorting._measurement
2+
3+
4+
abstract class MeasuredCollection<T : Comparable<T>> {
5+
6+
private var comparisons: Int = 0
7+
private var exchanges: Int = 0
8+
private var halfExchanges: Int = 0
9+
10+
11+
fun beginMeasurement() {
12+
comparisons = 0
13+
exchanges = 0
14+
halfExchanges = 0
15+
}
16+
17+
fun <R> endMeasurement(algorithmResult: R) =
18+
MeasurementResult(algorithmResult, comparisons, exchanges, halfExchanges)
19+
20+
fun exch(i: Int, j: Int) {
21+
exchanges++
22+
this[i] = this[j].also { this[j] = this[i] }
23+
}
24+
25+
fun onCompare() {
26+
comparisons++
27+
}
28+
29+
operator fun set(index: Int, value: MeasuredElement<T>) {
30+
halfExchanges++
31+
setAt(index, value)
32+
}
33+
34+
operator fun get(index: Int) = getAt(index)
35+
36+
37+
abstract fun setAt(index: Int, value: MeasuredElement<T>)
38+
39+
abstract fun getAt(index: Int): MeasuredElement<T>
40+
}
41+
42+
class MeasuredElement<T : Comparable<T>>(
43+
private val measurer: MeasuredCollection<T>,
44+
val value: T
45+
) {
46+
47+
operator fun compareTo(other: MeasuredElement<T>): Int {
48+
measurer.onCompare()
49+
return value.compareTo(other.value)
50+
}
51+
52+
operator fun compareTo(other: T): Int {
53+
measurer.onCompare()
54+
return value.compareTo(other)
55+
}
56+
}
57+
58+
data class MeasurementResult<R>(
59+
val algorithmOutput: R,
60+
val comparisons: Int,
61+
val exchanges: Int,
62+
val halfExchanges: Int
63+
) {
64+
val totalExchanges = exchanges + halfExchanges / 2.0
65+
66+
@Suppress("IMPLICIT_CAST_TO_ANY")
67+
override fun toString() = """
68+
Algorithm output: ${if (algorithmOutput !is Unit) algorithmOutput else "N/A"}
69+
Number of comparisons: $comparisons
70+
Number of exchanges: $exchanges
71+
Number of half-exchanges: $halfExchanges
72+
Total number of exchanges: $totalExchanges
73+
""".trimIndent()
74+
}
75+
76+
class MeasuredIntArray(private val array: IntArray) : MeasuredCollection<Int>() {
77+
78+
override fun getAt(index: Int) = MeasuredElement(this, array[index])
79+
80+
override fun setAt(index: Int, value: MeasuredElement<Int>) {
81+
array[index] = value.value
82+
}
83+
}
84+
85+
86+
fun <R> IntArray.measured(algorithm: MeasuredIntArray.() -> R): MeasurementResult<R> {
87+
val measuredArray = MeasuredIntArray(array = this)
88+
return measuredArray
89+
.apply { beginMeasurement() }
90+
.run(algorithm)
91+
.let { measuredArray.endMeasurement(algorithmResult = it) }
92+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library")
2+
3+
package(default_visibility = ["//sequential/sorting:__subpackages__"])
4+
5+
kt_jvm_library(
6+
name = "test_base",
7+
srcs = glob(["*.kt"]),
8+
)

src/kotlin/sequential/sorting/insertionsort/BUILD

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ kt_jvm_library(
55
srcs = [
66
"InsertionSort.kt",
77
"RangedInsertionSort.kt",
8+
"_measurement/MeasuredInsertionSort.kt"
89
],
910
deps = [
10-
"//sequential/sorting/_measurement",
11+
"//sequential/sorting/_measurement:measurement",
1112
"//:utils",
1213
],
1314
visibility = ["//visibility:public"],
@@ -23,4 +24,10 @@ java_binary(
2324
name = "insertion_sort_ranged",
2425
main_class = "sequential.sorting.insertionsort.RangedInsertionSortKt",
2526
runtime_deps = [":insertion_sort_lib"],
27+
)
28+
29+
java_binary(
30+
name = "insertion_sort_measured",
31+
main_class = "sequential.sorting.insertionsort._measurement.MeasuredInsertionSortKt",
32+
runtime_deps = [":insertion_sort_lib"],
2633
)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package sequential.sorting.insertionsort._measurement
2+
3+
import sequential.sorting._measurement.*
4+
import _util.*
5+
6+
7+
fun IntArray.insertionSort() = measured {
8+
9+
// Setting sentinel
10+
var exchanges = 0
11+
for (i in lastIndex downTo 1) {
12+
if (this[i] < this[i - 1]) {
13+
exch(i, i - 1)
14+
exchanges++
15+
}
16+
}
17+
if (exchanges == 0) return@measured
18+
19+
// Actual insertion sort
20+
for (i in 2..lastIndex) {
21+
var j = i
22+
val arri = this[i]
23+
while (arri < this[j - 1]) {
24+
this[j] = this[j - 1]
25+
j--
26+
}
27+
this[j] = arri
28+
}
29+
}
30+
31+
32+
fun main() {
33+
val array = randomIntArray(size = 20)
34+
array.print()
35+
36+
val measurement = array.insertionSort()
37+
38+
println("Sorting is successful: ${array.isSorted()}")
39+
array.print()
40+
41+
println("$measurement")
42+
}

src/kotlin/sequential/sorting/quicksort/BUILD

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ kt_jvm_library(
88
] + glob(["partition/*.kt"]),
99
deps = [
1010
"//sequential/sorting/insertionsort:insertion_sort_lib",
11-
"//sequential/sorting/_measurement",
12-
"//:utils"
11+
"//sequential/sorting/_measurement:measurement",
12+
"//:utils",
1313
]
1414
)
1515

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package sequential.sorting.quicksort._measurement
2+
3+

0 commit comments

Comments
 (0)