diff --git a/kt/maximum-number-of-moves-in-a-grid.kt b/kt/maximum-number-of-moves-in-a-grid.kt
new file mode 100644
index 0000000..fd74798
--- /dev/null
+++ b/kt/maximum-number-of-moves-in-a-grid.kt
@@ -0,0 +1,38 @@
+class Solution {
+ fun product(
+ xs: Sequence,
+ ys: Sequence,
+ ): Sequence> = xs.flatMap { x -> ys.map { y -> x to y } }
+
+ fun product(
+ xs: Sequence,
+ ys: Sequence,
+ zs: Sequence,
+ ): Sequence> = xs.flatMap { x -> ys.flatMap { y -> zs.map { z -> Triple(x, y, z) } } }
+
+ fun product(
+ xs: Iterable,
+ ys: Iterable,
+ ): Sequence> = product(xs.asSequence(), ys.asSequence())
+
+ fun product(
+ xs: Iterable,
+ ys: Iterable,
+ zs: Iterable,
+ ): Sequence> = product(xs.asSequence(), ys.asSequence(), zs.asSequence())
+
+ fun maxMoves(grid: Array): Int {
+ val dp = Array(grid.size) { IntArray(grid[0].size) }
+
+ product(grid[0].indices.reversed().drop(1), grid.indices, -1..1).filter {
+ (x, y, dy) ->
+ y + dy >= 0 && y + dy < dp.size && grid[y][x] < grid[y + dy][x + 1]
+ }.forEach { (x, y, dy) ->
+ dp[y][x] = listOf(dp[y][x], 1 + dp[y + dy][x + 1]).max()
+ }
+
+ return dp.indices.maxOf { y ->
+ dp[y][0]
+ }
+ }
+}