Skip to content

Commit

Permalink
Solve 'Best travel' kata
Browse files Browse the repository at this point in the history
  • Loading branch information
borisskert committed May 10, 2024
1 parent 79640cc commit facd21d
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/main/kotlin/besttravel/chooseBestSum.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package besttravel

/**
* https://www.codewars.com/kata/55e7280b40e1c4a06d0000aa/train/kotlin
*/
fun chooseBestSum(t: Int, k: Int, ls: List<Int>): Int {
return ls.combinations(k)
.map { it.sum() }
.filter { it <= t }
.maxOrNull() ?: -1
}

fun <T> List<T>.combinations(k: Int, acc: List<T> = emptyList()): List<List<T>> {
if (k == 0) return listOf(acc)
if (isEmpty()) return emptyList()

return drop(1)
.combinations(k - 1, acc + first()) + drop(1).combinations(k, acc)
}

// best practice (a lot of faster)

//fun chooseBestSum(t: Int, k: Int, ls: List<Int>): Int {
// return ls.findBestCombination(k, { it.sum() }, t)?.sum() ?: -1
//}
//
//fun <T, R : Comparable<R>> List<T>.findBestCombination(
// k: Int,
// f: (List<T>) -> R?,
// max: R,
// found: List<T> = emptyList(),
// n: Int = 0
//): (List<T>)? {
// val result = f(found)
// if (k == 0 && (result == null || result <= max)) return found
// if (result != null && result > max || n >= size) return null
//
// val a = findBestCombination(k - 1, f, max, found + get(n), n + 1)
// val b = findBestCombination(k, f, max, found, n + 1)
//
// return if (a == null) b else if (b == null) a else if (f(a)!! > f(b)!!) a else b
//}
91 changes: 91 additions & 0 deletions src/test/kotlin/besttravel/ChooseBestSumKtTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package besttravel

import org.junit.Assert.assertEquals
import org.junit.Ignore
import org.junit.Test

class SumOfKTest {

@Test
fun basicTests1() {
println("****** Basic Tests small numbers******")
var ts = listOf(50, 55, 56, 57, 58)
val n = chooseBestSum(163, 3, ts)
assertEquals(163, n.toLong())
ts = listOf(50)
val m = chooseBestSum(163, 3, ts)
assertEquals(-1, m)
}

@Test
@Ignore("Performance test (~ 4 seconds on M3 Pro)")
fun hardPerformanceTest() {
val ts: List<Int> = listOf(
931, 744, 763, 825, 713, 851, 867, 435, 726, 112, 847, 697, 547, 384, 897, 455, 242, 564, 873, 586, 336,
934, 208, 557, 876, 644, 934, 753, 664, 725, 941, 754, 563, 972, 683, 636, 428, 943, 653, 862, 929, 645,
251, 665, 120, 750, 420, 340, 931, 744, 763, 825, 713, 851, 867, 435, 726, 112, 847, 697, 547, 384, 897,
455, 242, 564, 873, 586, 336, 934, 208, 557, 876, 644
)

val start = System.currentTimeMillis()
val n: Int = chooseBestSum(3198, 5, ts)
val end = System.currentTimeMillis()
println("Time: " + (end - start) + " ms")
assertEquals(3198, n.toLong())
}

@Test
@Ignore("Performance test (~ 10 seconds on M3 Pro)")
fun harderPerformanceTest() {
val ts: List<Int> = listOf(
931, 744, 763, 825, 713, 851, 867, 435, 726, 112, 847, 697, 547, 384, 897, 455, 242, 564, 873, 586, 336,
934, 208, 557, 876, 644, 934, 753, 664, 725, 941, 754, 563, 972, 683, 636, 428, 943, 653, 862, 929, 645,
251, 665, 120, 750, 420, 340, 931, 744, 763, 825, 713, 851, 867, 435, 726, 112, 847, 697, 547, 384, 897,
455, 242, 564, 873, 586, 336, 934, 208, 557, 876, 644, 934, 753, 664, 725, 941, 754, 563, 972, 683, 636
)

val start = System.currentTimeMillis()
val n: Int = chooseBestSum(3198, 5, ts)
val end = System.currentTimeMillis()
println("Time: " + (end - start) + " ms")
assertEquals(3198, n.toLong())
}

@Test
@Ignore("Performance test (~ 20 seconds on M3 Pro)")
fun evenHarderPerformanceTest() {
val ts: List<Int> = listOf(
931, 744, 763, 825, 713, 851, 867, 435, 726, 112, 847, 697, 547, 384, 897, 455, 242, 564, 873, 586, 336,
934, 208, 557, 876, 644, 934, 753, 664, 725, 941, 754, 563, 972, 683, 636, 428, 943, 653, 862, 929, 645,
251, 665, 120, 750, 420, 340, 931, 744, 763, 825, 713, 851, 867, 435, 726, 112, 847, 697, 547, 384, 897,
455, 242, 564, 873, 586, 336, 934, 208, 557, 876, 644, 934, 753, 664, 725, 941, 754, 563, 972, 683, 636,
428, 943, 653, 862, 929, 645, 251, 665, 120, 750
)

val start = System.currentTimeMillis()
val n: Int = chooseBestSum(3198, 5, ts)
val end = System.currentTimeMillis()
println("Time: " + (end - start) + " ms")
assertEquals(3198, n.toLong())
}

@Test
@Ignore("Performance test")
fun evenHardestPerformanceTest() {
val ts: List<Int> = listOf(
931, 744, 763, 825, 713, 851, 867, 435, 726, 112, 847, 697, 547, 384, 897, 455, 242, 564, 873, 586, 336,
934, 208, 557, 876, 644, 934, 753, 664, 725, 941, 754, 563, 972, 683, 636, 428, 943, 653, 862, 929, 645,
251, 665, 120, 750, 420, 340, 931, 744, 763, 825, 713, 851, 867, 435, 726, 112, 847, 697, 547, 384, 897,
455, 242, 564, 873, 586, 336, 934, 208, 557, 876, 644, 934, 753, 664, 725, 941, 754, 563, 972, 683, 636,
428, 943, 653, 862, 929, 645, 251, 665, 120, 750, 420, 340, 931, 744, 763, 825, 713, 851, 867, 435, 726,
112, 847, 697, 547, 384, 897, 455, 242, 564, 873, 586, 336, 934, 208, 557, 876, 644, 934, 753, 664, 725,
941, 754, 563, 972, 683, 636, 428, 943, 653, 862, 929, 645, 251, 665, 120, 750, 420, 340, 931, 744, 763,
)

val start = System.currentTimeMillis()
val n: Int = chooseBestSum(3198, 5, ts)
val end = System.currentTimeMillis()
println("Time: " + (end - start) + " ms")
assertEquals(3198, n.toLong())
}
}

0 comments on commit facd21d

Please sign in to comment.