diff --git a/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt b/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt
new file mode 100644
index 00000000..caad0311
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/Solution.kt
@@ -0,0 +1,39 @@
+package g3601_3700.s3602_hexadecimal_and_hexatrigesimal_conversion
+
+// #Easy #String #Math #2025_07_07_Time_2_ms_(100.00%)_Space_41.91_MB_(100.00%)
+
+class Solution {
+ fun concatHex36(n: Int): String {
+ var t = n * n
+ var k: Int
+ val st = StringBuilder()
+ var tmp = StringBuilder()
+ while (t > 0) {
+ k = t % 16
+ t = t / 16
+ if (k <= 9) {
+ tmp.append(('0'.code + k).toChar())
+ } else {
+ tmp.append(('A'.code + (k - 10)).toChar())
+ }
+ }
+ for (i in tmp.length - 1 downTo 0) {
+ st.append(tmp[i])
+ }
+ tmp = StringBuilder()
+ t = n * n * n
+ while (t > 0) {
+ k = t % 36
+ t = t / 36
+ if (k <= 9) {
+ tmp.append(('0'.code + k).toChar())
+ } else {
+ tmp.append(('A'.code + (k - 10)).toChar())
+ }
+ }
+ for (i in tmp.length - 1 downTo 0) {
+ st.append(tmp[i])
+ }
+ return st.toString()
+ }
+}
diff --git a/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/readme.md b/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/readme.md
new file mode 100644
index 00000000..c08a5c4c
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/readme.md
@@ -0,0 +1,39 @@
+3602\. Hexadecimal and Hexatrigesimal Conversion
+
+Easy
+
+You are given an integer `n`.
+
+Return the concatenation of the **hexadecimal** representation of n2
and the **hexatrigesimal** representation of n3
.
+
+A **hexadecimal** number is defined as a base-16 numeral system that uses the digits `0 – 9` and the uppercase letters `A - F` to represent values from 0 to 15.
+
+A **hexatrigesimal** number is defined as a base-36 numeral system that uses the digits `0 – 9` and the uppercase letters `A - Z` to represent values from 0 to 35.
+
+**Example 1:**
+
+**Input:** n = 13
+
+**Output:** "A91P1"
+
+**Explanation:**
+
+* n2 = 13 * 13 = 169
. In hexadecimal, it converts to `(10 * 16) + 9 = 169`, which corresponds to `"A9"`.
+* n3 = 13 * 13 * 13 = 2197
. In hexatrigesimal, it converts to (1 * 362) + (25 * 36) + 1 = 2197
, which corresponds to `"1P1"`.
+* Concatenating both results gives `"A9" + "1P1" = "A91P1"`.
+
+**Example 2:**
+
+**Input:** n = 36
+
+**Output:** "5101000"
+
+**Explanation:**
+
+* n2 = 36 * 36 = 1296
. In hexadecimal, it converts to (5 * 162) + (1 * 16) + 0 = 1296
, which corresponds to `"510"`.
+* n3 = 36 * 36 * 36 = 46656
. In hexatrigesimal, it converts to (1 * 363) + (0 * 362) + (0 * 36) + 0 = 46656
, which corresponds to `"1000"`.
+* Concatenating both results gives `"510" + "1000" = "5101000"`.
+
+**Constraints:**
+
+* `1 <= n <= 1000`
\ No newline at end of file
diff --git a/src/main/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/Solution.kt b/src/main/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/Solution.kt
new file mode 100644
index 00000000..83482658
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/Solution.kt
@@ -0,0 +1,31 @@
+package g3601_3700.s3603_minimum_cost_path_with_alternating_directions_ii
+
+// #Medium #Array #Dynamic_Programming #Matrix
+// #2025_07_07_Time_12_ms_(100.00%)_Space_84.57_MB_(100.00%)
+
+import kotlin.math.min
+
+class Solution {
+ fun minCost(m: Int, n: Int, waitCost: Array): Long {
+ val dp = LongArray(n)
+ dp[0] = 1L
+ for (j in 1..1 <= m, n <= 105
+* 2 <= m * n <= 105
+* `waitCost.length == m`
+* `waitCost[0].length == n`
+* 0 <= waitCost[i][j] <= 105
\ No newline at end of file
diff --git a/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/Solution.kt b/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/Solution.kt
new file mode 100644
index 00000000..9ecd986b
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/Solution.kt
@@ -0,0 +1,113 @@
+package g3601_3700.s3604_minimum_time_to_reach_destination_in_directed_graph
+
+// #Medium #Heap_Priority_Queue #Graph #Shortest_Path
+// #2025_07_07_Time_18_ms_(100.00%)_Space_132.61_MB_(100.00%)
+
+import kotlin.math.max
+
+class Solution {
+ fun minTime(n: Int, edges: Array): Int {
+ val head = IntArray(n)
+ val to = IntArray(edges.size)
+ val start = IntArray(edges.size)
+ val end = IntArray(edges.size)
+ val next = IntArray(edges.size)
+ head.fill(-1)
+ for (i in edges.indices) {
+ val u = edges[i][0]
+ to[i] = edges[i][1]
+ start[i] = edges[i][2]
+ end[i] = edges[i][3]
+ next[i] = head[u]
+ head[u] = i
+ }
+ val heap = IntArray(n)
+ val time = IntArray(n)
+ val pos = IntArray(n)
+ val visited = BooleanArray(n)
+ var size = 0
+ for (i in 0.. 0) {
+ val u = heap[0]
+ heap[0] = heap[--size]
+ pos[heap[0]] = 0
+ heapifyDown(heap, time, pos, size, 0)
+ if (visited[u]) {
+ continue
+ }
+ visited[u] = true
+ if (u == n - 1) {
+ return time[u]
+ }
+ var e = head[u]
+ while (e != -1) {
+ val v = to[e]
+ val t0 = time[u]
+ if (t0 > end[e]) {
+ e = next[e]
+ continue
+ }
+ val arrival = max(t0, start[e]) + 1
+ if (arrival < time[v]) {
+ time[v] = arrival
+ if (pos[v] == -1) {
+ heap[size] = v
+ pos[v] = size
+ heapifyUp(heap, time, pos, size)
+ size++
+ } else {
+ heapifyUp(heap, time, pos, pos[v])
+ }
+ }
+ e = next[e]
+ }
+ }
+ return -1
+ }
+
+ private fun heapifyUp(heap: IntArray, time: IntArray, pos: IntArray, i: Int) {
+ var i = i
+ while (i > 0) {
+ val p = (i - 1) / 2
+ if (time[heap[p]] <= time[heap[i]]) {
+ break
+ }
+ swap(heap, pos, i, p)
+ i = p
+ }
+ }
+
+ private fun heapifyDown(heap: IntArray, time: IntArray, pos: IntArray, size: Int, i: Int) {
+ var i = i
+ while (2 * i + 1 < size) {
+ var j = 2 * i + 1
+ if (j + 1 < size && time[heap[j + 1]] < time[heap[j]]) {
+ j++
+ }
+ if (time[heap[i]] <= time[heap[j]]) {
+ break
+ }
+ swap(heap, pos, i, j)
+ i = j
+ }
+ }
+
+ private fun swap(heap: IntArray, pos: IntArray, i: Int, j: Int) {
+ val tmp = heap[i]
+ heap[i] = heap[j]
+ heap[j] = tmp
+ pos[heap[i]] = i
+ pos[heap[j]] = j
+ }
+
+ companion object {
+ private const val INF = Int.Companion.MAX_VALUE
+ }
+}
diff --git a/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/readme.md b/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/readme.md
new file mode 100644
index 00000000..d947dade
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/readme.md
@@ -0,0 +1,69 @@
+3604\. Minimum Time to Reach Destination in Directed Graph
+
+Medium
+
+You are given an integer `n` and a **directed** graph with `n` nodes labeled from 0 to `n - 1`. This is represented by a 2D array `edges`, where edges[i] = [ui, vi, starti, endi]
indicates an edge from node ui
to vi
that can **only** be used at any integer time `t` such that starti <= t <= endi
.
+
+You start at node 0 at time 0.
+
+In one unit of time, you can either:
+
+* Wait at your current node without moving, or
+* Travel along an outgoing edge from your current node if the current time `t` satisfies starti <= t <= endi
.
+
+Return the **minimum** time required to reach node `n - 1`. If it is impossible, return `-1`.
+
+**Example 1:**
+
+**Input:** n = 3, edges = [[0,1,0,1],[1,2,2,5]]
+
+**Output:** 3
+
+**Explanation:**
+
+
+
+The optimal path is:
+
+* At time `t = 0`, take the edge `(0 → 1)` which is available from 0 to 1. You arrive at node 1 at time `t = 1`, then wait until `t = 2`.
+* At time ```t = `2` ```, take the edge `(1 → 2)` which is available from 2 to 5. You arrive at node 2 at time 3.
+
+Hence, the minimum time to reach node 2 is 3.
+
+**Example 2:**
+
+**Input:** n = 4, edges = [[0,1,0,3],[1,3,7,8],[0,2,1,5],[2,3,4,7]]
+
+**Output:** 5
+
+**Explanation:**
+
+
+
+The optimal path is:
+
+* Wait at node 0 until time `t = 1`, then take the edge `(0 → 2)` which is available from 1 to 5. You arrive at node 2 at `t = 2`.
+* Wait at node 2 until time `t = 4`, then take the edge `(2 → 3)` which is available from 4 to 7. You arrive at node 3 at `t = 5`.
+
+Hence, the minimum time to reach node 3 is 5.
+
+**Example 3:**
+
+**Input:** n = 3, edges = [[1,0,1,3],[1,2,3,5]]
+
+**Output:** \-1
+
+**Explanation:**
+
+
+
+* Since there is no outgoing edge from node 0, it is impossible to reach node 2. Hence, the output is -1.
+
+**Constraints:**
+
+* 1 <= n <= 105
+* 0 <= edges.length <= 105
+* edges[i] == [ui, vi, starti, endi]
+* 0 <= ui, vi <= n - 1
+* ui != vi
+* 0 <= starti <= endi <= 109
\ No newline at end of file
diff --git a/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/Solution.kt b/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/Solution.kt
new file mode 100644
index 00000000..7d573f63
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/Solution.kt
@@ -0,0 +1,95 @@
+package g3601_3700.s3605_minimum_stability_factor_of_array
+
+// #Hard #Array #Math #Greedy #Binary_Search #Segment_Tree #Number_Theory
+// #2025_07_07_Time_95_ms_(100.00%)_Space_77.89_MB_(100.00%)
+
+class Solution {
+ fun minStable(nums: IntArray, maxC: Int): Int {
+ val n = nums.size
+ var cnt = 0
+ var idx = 0
+ while (idx < n) {
+ cnt += if (nums[idx] >= 2) 1 else 0
+ idx++
+ }
+ if (cnt <= maxC) {
+ return 0
+ }
+ val logs = IntArray(n + 1)
+ var maxLog = 0
+ var temp = n
+ while (temp > 0) {
+ maxLog++
+ temp = temp shr 1
+ }
+ val table = Array(maxLog + 1) { IntArray(n) }
+ buildLogs(logs, n)
+ buildTable(table, nums, n, maxLog)
+ return binarySearch(nums, maxC, n, logs, table)
+ }
+
+ private fun buildLogs(logs: IntArray, n: Int) {
+ var i = 2
+ while (i <= n) {
+ logs[i] = logs[i shr 1] + 1
+ i++
+ }
+ }
+
+ private fun buildTable(table: Array, nums: IntArray, n: Int, maxLog: Int) {
+ System.arraycopy(nums, 0, table[0], 0, n)
+ var level = 1
+ while (level <= maxLog) {
+ var start = 0
+ while (start + (1 shl level) <= n) {
+ table[level][start] =
+ gcd(table[level - 1][start], table[level - 1][start + (1 shl (level - 1))])
+ start++
+ }
+ level++
+ }
+ }
+
+ private fun binarySearch(nums: IntArray, maxC: Int, n: Int, logs: IntArray, table: Array): Int {
+ var left = 1
+ var right = n
+ var result = n
+ while (left <= right) {
+ val mid = left + ((right - left) shr 1)
+ val valid = isValid(nums, maxC, mid, logs, table)
+ result = if (valid) mid else result
+ val newLeft = if (valid) left else mid + 1
+ val newRight = if (valid) mid - 1 else right
+ left = newLeft
+ right = newRight
+ }
+ return result
+ }
+
+ private fun isValid(arr: IntArray, limit: Int, segLen: Int, logs: IntArray, table: Array): Boolean {
+ val n = arr.size
+ val window = segLen + 1
+ var cuts = 0
+ var prevCut = -1
+ var pos = 0
+ while (pos + window - 1 < n && cuts <= limit) {
+ val rangeGcd = getRangeGcd(pos, pos + window - 1, logs, table)
+ if (rangeGcd >= 2) {
+ val shouldCut = prevCut < pos
+ cuts += if (shouldCut) 1 else 0
+ prevCut = if (shouldCut) pos + window - 1 else prevCut
+ }
+ pos++
+ }
+ return cuts <= limit
+ }
+
+ private fun getRangeGcd(left: Int, right: Int, logs: IntArray, table: Array): Int {
+ val k = logs[right - left + 1]
+ return gcd(table[k][left], table[k][right - (1 shl k) + 1])
+ }
+
+ private fun gcd(a: Int, b: Int): Int {
+ return if (b == 0) a else gcd(b, a % b)
+ }
+}
diff --git a/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/readme.md b/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/readme.md
new file mode 100644
index 00000000..e3d7712e
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/readme.md
@@ -0,0 +1,61 @@
+3605\. Minimum Stability Factor of Array
+
+Hard
+
+You are given an integer array `nums` and an integer `maxC`.
+
+A **subarray** is called **stable** if the _highest common factor (HCF)_ of all its elements is **greater than or equal to** 2.
+
+The **stability factor** of an array is defined as the length of its **longest** stable subarray.
+
+You may modify **at most** `maxC` elements of the array to any integer.
+
+Return the **minimum** possible stability factor of the array after at most `maxC` modifications. If no stable subarray remains, return 0.
+
+**Note:**
+
+* The **highest common factor (HCF)** of an array is the largest integer that evenly divides all the array elements.
+* A **subarray** of length 1 is stable if its only element is greater than or equal to 2, since `HCF([x]) = x`.
+
+**Example 1:**
+
+**Input:** nums = [3,5,10], maxC = 1
+
+**Output:** 1
+
+**Explanation:**
+
+* The stable subarray `[5, 10]` has `HCF = 5`, which has a stability factor of 2.
+* Since `maxC = 1`, one optimal strategy is to change `nums[1]` to `7`, resulting in `nums = [3, 7, 10]`.
+* Now, no subarray of length greater than 1 has `HCF >= 2`. Thus, the minimum possible stability factor is 1.
+
+**Example 2:**
+
+**Input:** nums = [2,6,8], maxC = 2
+
+**Output:** 1
+
+**Explanation:**
+
+* The subarray `[2, 6, 8]` has `HCF = 2`, which has a stability factor of 3.
+* Since `maxC = 2`, one optimal strategy is to change `nums[1]` to 3 and `nums[2]` to 5, resulting in `nums = [2, 3, 5]`.
+* Now, no subarray of length greater than 1 has `HCF >= 2`. Thus, the minimum possible stability factor is 1.
+
+**Example 3:**
+
+**Input:** nums = [2,4,9,6], maxC = 1
+
+**Output:** 2
+
+**Explanation:**
+
+* The stable subarrays are:
+ * `[2, 4]` with `HCF = 2` and stability factor of 2.
+ * `[9, 6]` with `HCF = 3` and stability factor of 2.
+* Since `maxC = 1`, the stability factor of 2 cannot be reduced due to two separate stable subarrays. Thus, the minimum possible stability factor is 2.
+
+**Constraints:**
+
+* 1 <= n == nums.length <= 105
+* 1 <= nums[i] <= 109
+* `0 <= maxC <= n`
\ No newline at end of file
diff --git a/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/Solution.kt b/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/Solution.kt
new file mode 100644
index 00000000..d39e3804
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/Solution.kt
@@ -0,0 +1,38 @@
+package g3601_3700.s3606_coupon_code_validator
+
+// #Easy #Array #String #Hash_Table #Sorting
+// #2025_07_07_Time_32_ms_(100.00%)_Space_60.79_MB_(100.00%)
+
+class Solution {
+ fun validateCoupons(code: Array, businessLine: Array, isActive: BooleanArray): List {
+ val validBusinessLines = hashSetOf("electronics", "grocery", "pharmacy", "restaurant")
+ val filteredCoupons = mutableListOf>()
+ for (i in code.indices) {
+ if (!isActive[i]) {
+ continue
+ }
+ val currentBusinessLine = businessLine[i]
+ if (currentBusinessLine !in validBusinessLines) {
+ continue
+ }
+ val currentCode = code[i]
+ if (currentCode.isEmpty()) {
+ continue
+ }
+
+ var isValidCodeChar = true
+ for (char in currentCode) {
+ if (!(char == '_' || char.isLetterOrDigit())) {
+ isValidCodeChar = false
+ break
+ }
+ }
+
+ if (isValidCodeChar) {
+ filteredCoupons.add(Pair(currentCode, currentBusinessLine))
+ }
+ }
+ filteredCoupons.sortWith(compareBy> { it.second }.thenBy { it.first })
+ return filteredCoupons.map { it.first }
+ }
+}
diff --git a/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/readme.md b/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/readme.md
new file mode 100644
index 00000000..7b346d64
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3606_coupon_code_validator/readme.md
@@ -0,0 +1,50 @@
+3606\. Coupon Code Validator
+
+Easy
+
+You are given three arrays of length `n` that describe the properties of `n` coupons: `code`, `businessLine`, and `isActive`. The ith
coupon has:
+
+* `code[i]`: a **string** representing the coupon identifier.
+* `businessLine[i]`: a **string** denoting the business category of the coupon.
+* `isActive[i]`: a **boolean** indicating whether the coupon is currently active.
+
+A coupon is considered **valid** if all of the following conditions hold:
+
+1. `code[i]` is non-empty and consists only of alphanumeric characters (a-z, A-Z, 0-9) and underscores (`_`).
+2. `businessLine[i]` is one of the following four categories: `"electronics"`, `"grocery"`, `"pharmacy"`, `"restaurant"`.
+3. `isActive[i]` is **true**.
+
+Return an array of the **codes** of all valid coupons, **sorted** first by their **businessLine** in the order: `"electronics"`, `"grocery"`, `"pharmacy", "restaurant"`, and then by **code** in lexicographical (ascending) order within each category.
+
+**Example 1:**
+
+**Input:** code = ["SAVE20","","PHARMA5","SAVE@20"], businessLine = ["restaurant","grocery","pharmacy","restaurant"], isActive = [true,true,true,true]
+
+**Output:** ["PHARMA5","SAVE20"]
+
+**Explanation:**
+
+* First coupon is valid.
+* Second coupon has empty code (invalid).
+* Third coupon is valid.
+* Fourth coupon has special character `@` (invalid).
+
+**Example 2:**
+
+**Input:** code = ["GROCERY15","ELECTRONICS\_50","DISCOUNT10"], businessLine = ["grocery","electronics","invalid"], isActive = [false,true,true]
+
+**Output:** ["ELECTRONICS\_50"]
+
+**Explanation:**
+
+* First coupon is inactive (invalid).
+* Second coupon is valid.
+* Third coupon has invalid business line (invalid).
+
+**Constraints:**
+
+* `n == code.length == businessLine.length == isActive.length`
+* `1 <= n <= 100`
+* `0 <= code[i].length, businessLine[i].length <= 100`
+* `code[i]` and `businessLine[i]` consist of printable ASCII characters.
+* `isActive[i]` is either `true` or `false`.
\ No newline at end of file
diff --git a/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/Solution.kt b/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/Solution.kt
new file mode 100644
index 00000000..b031c74f
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/Solution.kt
@@ -0,0 +1,82 @@
+package g3601_3700.s3607_power_grid_maintenance
+
+// #Medium #Array #Hash_Table #Depth_First_Search #Breadth_First_Search #Heap_Priority_Queue #Graph
+// #Union_Find #Ordered_Set #2025_07_07_Time_91_ms_(100.00%)_Space_165.69_MB_(93.75%)
+
+import java.util.PriorityQueue
+
+class Solution {
+ private class UF(n: Int) {
+ val par: IntArray = IntArray(n)
+ val pq: Array> = Array(n) { PriorityQueue() }
+ val active: BooleanArray = BooleanArray(n)
+
+ init {
+ for (i in 0 until n) {
+ active[i] = true
+ par[i] = i
+ pq[i].add(i)
+ }
+ }
+
+ fun find(u: Int): Int {
+ if (par[u] == u) {
+ return u
+ }
+ par[u] = find(par[u])
+ return par[u]
+ }
+
+ fun union(u: Int, v: Int) {
+ val pu = find(u)
+ val pv = find(v)
+ if (pu == pv) {
+ return
+ }
+ if (pq[pu].size > pq[pv].size) {
+ while (pq[pv].isNotEmpty()) {
+ pq[pu].add(pq[pv].poll())
+ }
+ par[pv] = pu // Should be pu, not par[pu]
+ } else {
+ while (pq[pu].isNotEmpty()) {
+ pq[pv].add(pq[pu].poll())
+ }
+ par[pu] = pv // Should be pv, not par[pv]
+ }
+ }
+
+ fun inactive(u: Int) {
+ active[u] = false
+ }
+
+ fun check(u: Int): Int {
+ if (active[u]) {
+ return u
+ }
+ val pu = find(u)
+ while (pq[pu].isNotEmpty() && !active[pq[pu].peek()]) {
+ pq[pu].poll()
+ }
+ return if (pq[pu].isNotEmpty()) pq[pu].peek() else -2
+ }
+ }
+
+ fun processQueries(c: Int, connections: Array, queries: Array): IntArray {
+ val uf = UF(c)
+ for (con in connections) {
+ val u = con[0]
+ val v = con[1]
+ uf.union(u - 1, v - 1)
+ }
+ val res = mutableListOf()
+ for (q in queries) {
+ if (q[0] == 1) {
+ res.add(uf.check(q[1] - 1) + 1)
+ } else {
+ uf.inactive(q[1] - 1)
+ }
+ }
+ return res.toIntArray()
+ }
+}
diff --git a/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/readme.md b/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/readme.md
new file mode 100644
index 00000000..f801ef4d
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3607_power_grid_maintenance/readme.md
@@ -0,0 +1,62 @@
+3607\. Power Grid Maintenance
+
+Medium
+
+You are given an integer `c` representing `c` power stations, each with a unique identifier `id` from 1 to `c` (1‑based indexing).
+
+These stations are interconnected via `n` **bidirectional** cables, represented by a 2D array `connections`, where each element connections[i] = [ui, vi]
indicates a connection between station ui
and station vi
. Stations that are directly or indirectly connected form a **power grid**.
+
+Initially, **all** stations are online (operational).
+
+You are also given a 2D array `queries`, where each query is one of the following _two_ types:
+
+* `[1, x]`: A maintenance check is requested for station `x`. If station `x` is online, it resolves the check by itself. If station `x` is offline, the check is resolved by the operational station with the smallest `id` in the same **power grid** as `x`. If **no** **operational** station _exists_ in that grid, return -1.
+
+* `[2, x]`: Station `x` goes offline (i.e., it becomes non-operational).
+
+
+Return an array of integers representing the results of each query of type `[1, x]` in the **order** they appear.
+
+**Note:** The power grid preserves its structure; an offline (non‑operational) node remains part of its grid and taking it offline does not alter connectivity.
+
+**Example 1:**
+
+**Input:** c = 5, connections = [[1,2],[2,3],[3,4],[4,5]], queries = [[1,3],[2,1],[1,1],[2,2],[1,2]]
+
+**Output:** [3,2,3]
+
+**Explanation:**
+
+
+
+* Initially, all stations `{1, 2, 3, 4, 5}` are online and form a single power grid.
+* Query `[1,3]`: Station 3 is online, so the maintenance check is resolved by station 3.
+* Query `[2,1]`: Station 1 goes offline. The remaining online stations are `{2, 3, 4, 5}`.
+* Query `[1,1]`: Station 1 is offline, so the check is resolved by the operational station with the smallest `id` among `{2, 3, 4, 5}`, which is station 2.
+* Query `[2,2]`: Station 2 goes offline. The remaining online stations are `{3, 4, 5}`.
+* Query `[1,2]`: Station 2 is offline, so the check is resolved by the operational station with the smallest `id` among `{3, 4, 5}`, which is station 3.
+
+**Example 2:**
+
+**Input:** c = 3, connections = [], queries = [[1,1],[2,1],[1,1]]
+
+**Output:** [1,-1]
+
+**Explanation:**
+
+* There are no connections, so each station is its own isolated grid.
+* Query `[1,1]`: Station 1 is online in its isolated grid, so the maintenance check is resolved by station 1.
+* Query `[2,1]`: Station 1 goes offline.
+* Query `[1,1]`: Station 1 is offline and there are no other stations in its grid, so the result is -1.
+
+**Constraints:**
+
+* 1 <= c <= 105
+* 0 <= n == connections.length <= min(105, c * (c - 1) / 2)
+* `connections[i].length == 2`
+* 1 <= ui, vi <= c
+* ui != vi
+* 1 <= queries.length <= 2 * 105
+* `queries[i].length == 2`
+* `queries[i][0]` is either 1 or 2.
+* `1 <= queries[i][1] <= c`
\ No newline at end of file
diff --git a/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt b/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt
new file mode 100644
index 00000000..7fa82175
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/Solution.kt
@@ -0,0 +1,56 @@
+package g3601_3700.s3608_minimum_time_for_k_connected_components
+
+// #Medium #Sorting #Binary_Search #Graph #Union_Find
+// #2025_07_07_Time_31_ms_(100.00%)_Space_114.78_MB_(100.00%)
+
+class Solution {
+ fun minTime(n: Int, edges: Array, k: Int): Int {
+ var maxTime = 0
+ for (e in edges) {
+ if (e[2] > maxTime) {
+ maxTime = e[2]
+ }
+ }
+ var lo = 0
+ var hi = maxTime
+ var ans = maxTime
+ while (lo <= hi) {
+ val mid = lo + (hi - lo) / 2
+ if (countComponents(n, edges, mid) >= k) {
+ ans = mid
+ hi = mid - 1
+ } else {
+ lo = mid + 1
+ }
+ }
+ return ans
+ }
+
+ private fun countComponents(n: Int, edges: Array, t: Int): Int {
+ val parent = IntArray(n)
+ for (i in 0.. t) {
+ val u = find(parent, e[0])
+ val v = find(parent, e[1])
+ if (u != v) {
+ parent[v] = u
+ comps--
+ }
+ }
+ }
+ return comps
+ }
+
+ private fun find(parent: IntArray, x: Int): Int {
+ var x = x
+ while (parent[x] != x) {
+ parent[x] = parent[parent[x]]
+ x = parent[x]
+ }
+ return x
+ }
+}
diff --git a/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/readme.md b/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/readme.md
new file mode 100644
index 00000000..bee4301f
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/readme.md
@@ -0,0 +1,64 @@
+3608\. Minimum Time for K Connected Components
+
+Medium
+
+You are given an integer `n` and an undirected graph with `n` nodes labeled from 0 to `n - 1`. This is represented by a 2D array `edges`, where edges[i] = [ui, vi, timei]
indicates an undirected edge between nodes ui
and vi
that can be removed at timei
.
+
+You are also given an integer `k`.
+
+Initially, the graph may be connected or disconnected. Your task is to find the **minimum** time `t` such that after removing all edges with `time <= t`, the graph contains **at least** `k` connected components.
+
+Return the **minimum** time `t`.
+
+A **connected component** is a subgraph of a graph in which there exists a path between any two vertices, and no vertex of the subgraph shares an edge with a vertex outside of the subgraph.
+
+**Example 1:**
+
+**Input:** n = 2, edges = [[0,1,3]], k = 2
+
+**Output:** 3
+
+**Explanation:**
+
+
+
+* Initially, there is one connected component `{0, 1}`.
+* At `time = 1` or `2`, the graph remains unchanged.
+* At `time = 3`, edge `[0, 1]` is removed, resulting in `k = 2` connected components `{0}`, `{1}`. Thus, the answer is 3.
+
+**Example 2:**
+
+**Input:** n = 3, edges = [[0,1,2],[1,2,4]], k = 3
+
+**Output:** 4
+
+**Explanation:**
+
+
+
+* Initially, there is one connected component `{0, 1, 2}`.
+* At `time = 2`, edge `[0, 1]` is removed, resulting in two connected components `{0}`, `{1, 2}`.
+* At `time = 4`, edge `[1, 2]` is removed, resulting in `k = 3` connected components `{0}`, `{1}`, `{2}`. Thus, the answer is 4.
+
+**Example 3:**
+
+**Input:** n = 3, edges = [[0,2,5]], k = 2
+
+**Output:** 0
+
+**Explanation:**
+
+
+
+* Since there are already `k = 2` disconnected components `{1}`, `{0, 2}`, no edge removal is needed. Thus, the answer is 0.
+
+**Constraints:**
+
+* 1 <= n <= 105
+* 0 <= edges.length <= 105
+* edges[i] = [ui, vi, timei]
+* 0 <= ui, vi < n
+* ui != vi
+* 1 <= timei <= 109
+* `1 <= k <= n`
+* There are no duplicate edges.
\ No newline at end of file
diff --git a/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.kt b/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.kt
new file mode 100644
index 00000000..8bf8f113
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/Solution.kt
@@ -0,0 +1,49 @@
+package g3601_3700.s3609_minimum_moves_to_reach_target_in_grid
+
+// #Hard #Math #2025_07_07_Time_1_ms_(100.00%)_Space_40.67_MB_(100.00%)
+
+class Solution {
+ fun minMoves(sx: Int, sy: Int, tx: Int, ty: Int): Int {
+ var tx = tx
+ var ty = ty
+ if (sx == 0 && sy == 0) {
+ return if (tx == 0 && ty == 0) 0 else -1
+ }
+
+ var res = 0
+ while (sx != tx || sy != ty) {
+ if (sx > tx || sy > ty) {
+ return -1
+ }
+ res++
+ if (tx > ty) {
+ if (tx > ty * 2) {
+ if (tx % 2 != 0) {
+ return -1
+ }
+ tx /= 2
+ } else {
+ tx -= ty
+ }
+ } else if (tx < ty) {
+ if (ty > tx * 2) {
+ if (ty % 2 != 0) {
+ return -1
+ }
+ ty /= 2
+ } else {
+ ty -= tx
+ }
+ } else {
+ if (sx == 0) {
+ tx = 0
+ } else if (sy == 0) {
+ ty = 0
+ } else {
+ return -1
+ }
+ }
+ }
+ return res
+ }
+}
diff --git a/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/readme.md b/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/readme.md
new file mode 100644
index 00000000..1f662239
--- /dev/null
+++ b/src/main/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/readme.md
@@ -0,0 +1,60 @@
+3609\. Minimum Moves to Reach Target in Grid
+
+Hard
+
+You are given four integers `sx`, `sy`, `tx`, and `ty`, representing two points `(sx, sy)` and `(tx, ty)` on an infinitely large 2D grid.
+
+You start at `(sx, sy)`.
+
+At any point `(x, y)`, define `m = max(x, y)`. You can either:
+
+* Move to `(x + m, y)`, or
+* Move to `(x, y + m)`.
+
+Return the **minimum** number of moves required to reach `(tx, ty)`. If it is impossible to reach the target, return -1.
+
+**Example 1:**
+
+**Input:** sx = 1, sy = 2, tx = 5, ty = 4
+
+**Output:** 2
+
+**Explanation:**
+
+The optimal path is:
+
+* Move 1: `max(1, 2) = 2`. Increase the y-coordinate by 2, moving from `(1, 2)` to `(1, 2 + 2) = (1, 4)`.
+* Move 2: `max(1, 4) = 4`. Increase the x-coordinate by 4, moving from `(1, 4)` to `(1 + 4, 4) = (5, 4)`.
+
+Thus, the minimum number of moves to reach `(5, 4)` is 2.
+
+**Example 2:**
+
+**Input:** sx = 0, sy = 1, tx = 2, ty = 3
+
+**Output:** 3
+
+**Explanation:**
+
+The optimal path is:
+
+* Move 1: `max(0, 1) = 1`. Increase the x-coordinate by 1, moving from `(0, 1)` to `(0 + 1, 1) = (1, 1)`.
+* Move 2: `max(1, 1) = 1`. Increase the x-coordinate by 1, moving from `(1, 1)` to `(1 + 1, 1) = (2, 1)`.
+* Move 3: `max(2, 1) = 2`. Increase the y-coordinate by 2, moving from `(2, 1)` to `(2, 1 + 2) = (2, 3)`.
+
+Thus, the minimum number of moves to reach `(2, 3)` is 3.
+
+**Example 3:**
+
+**Input:** sx = 1, sy = 1, tx = 2, ty = 2
+
+**Output:** \-1
+
+**Explanation:**
+
+* It is impossible to reach `(2, 2)` from `(1, 1)` using the allowed moves. Thus, the answer is -1.
+
+**Constraints:**
+
+* 0 <= sx <= tx <= 109
+* 0 <= sy <= ty <= 109
\ No newline at end of file
diff --git a/src/test/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/SolutionTest.kt
new file mode 100644
index 00000000..6acf8382
--- /dev/null
+++ b/src/test/kotlin/g3601_3700/s3602_hexadecimal_and_hexatrigesimal_conversion/SolutionTest.kt
@@ -0,0 +1,17 @@
+package g3601_3700.s3602_hexadecimal_and_hexatrigesimal_conversion
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun concatHex36() {
+ assertThat(Solution().concatHex36(13), equalTo("A91P1"))
+ }
+
+ @Test
+ fun concatHex362() {
+ assertThat(Solution().concatHex36(36), equalTo("5101000"))
+ }
+}
diff --git a/src/test/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/SolutionTest.kt
new file mode 100644
index 00000000..aa936b64
--- /dev/null
+++ b/src/test/kotlin/g3601_3700/s3603_minimum_cost_path_with_alternating_directions_ii/SolutionTest.kt
@@ -0,0 +1,39 @@
+package g3601_3700.s3603_minimum_cost_path_with_alternating_directions_ii
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun minCost() {
+ assertThat(
+ Solution().minCost(1, 2, arrayOf(intArrayOf(1, 2))),
+ equalTo(3L),
+ )
+ }
+
+ @Test
+ fun minCost2() {
+ assertThat(
+ Solution().minCost(
+ 2,
+ 2,
+ arrayOf(intArrayOf(3, 5), intArrayOf(2, 4)),
+ ),
+ equalTo(9L),
+ )
+ }
+
+ @Test
+ fun minCost3() {
+ assertThat(
+ Solution().minCost(
+ 2,
+ 3,
+ arrayOf(intArrayOf(6, 1, 4), intArrayOf(3, 2, 5)),
+ ),
+ equalTo(16L),
+ )
+ }
+}
diff --git a/src/test/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/SolutionTest.kt
new file mode 100644
index 00000000..e2be01b3
--- /dev/null
+++ b/src/test/kotlin/g3601_3700/s3604_minimum_time_to_reach_destination_in_directed_graph/SolutionTest.kt
@@ -0,0 +1,65 @@
+package g3601_3700.s3604_minimum_time_to_reach_destination_in_directed_graph
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun minTime() {
+ assertThat(
+ Solution().minTime(
+ 3,
+ arrayOf(intArrayOf(0, 1, 0, 1), intArrayOf(1, 2, 2, 5)),
+ ),
+ equalTo(3),
+ )
+ }
+
+ @Test
+ fun minTime2() {
+ assertThat(
+ Solution()
+ .minTime(
+ 4,
+ arrayOf(
+ intArrayOf(0, 1, 0, 3),
+ intArrayOf(1, 3, 7, 8),
+ intArrayOf(0, 2, 1, 5),
+ intArrayOf(2, 3, 4, 7),
+ ),
+ ),
+ equalTo(5),
+ )
+ }
+
+ @Test
+ fun minTime3() {
+ assertThat(
+ Solution().minTime(3, arrayOf(intArrayOf(1, 0, 1, 3), intArrayOf(1, 2, 3, 5))),
+ equalTo(-1),
+ )
+ }
+
+ @Test
+ fun minTest4() {
+ assertThat(
+ Solution()
+ .minTime(
+ 5,
+ arrayOf(
+ intArrayOf(1, 3, 17, 18),
+ intArrayOf(1, 3, 0, 7),
+ intArrayOf(0, 1, 0, 3),
+ intArrayOf(3, 2, 1, 20),
+ intArrayOf(1, 2, 25, 25),
+ intArrayOf(0, 3, 13, 14),
+ intArrayOf(1, 0, 11, 15),
+ intArrayOf(0, 4, 19, 21),
+ intArrayOf(2, 0, 4, 20),
+ ),
+ ),
+ equalTo(20),
+ )
+ }
+}
diff --git a/src/test/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/SolutionTest.kt
new file mode 100644
index 00000000..706dfcbe
--- /dev/null
+++ b/src/test/kotlin/g3601_3700/s3605_minimum_stability_factor_of_array/SolutionTest.kt
@@ -0,0 +1,22 @@
+package g3601_3700.s3605_minimum_stability_factor_of_array
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun minStable() {
+ assertThat(Solution().minStable(intArrayOf(3, 5, 10), 1), equalTo(1))
+ }
+
+ @Test
+ fun minStable2() {
+ assertThat(Solution().minStable(intArrayOf(2, 6, 8), 2), equalTo(1))
+ }
+
+ @Test
+ fun minStable3() {
+ assertThat(Solution().minStable(intArrayOf(2, 4, 9, 6), 1), equalTo(2))
+ }
+}
diff --git a/src/test/kotlin/g3601_3700/s3606_coupon_code_validator/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3606_coupon_code_validator/SolutionTest.kt
new file mode 100644
index 00000000..7ce8fb99
--- /dev/null
+++ b/src/test/kotlin/g3601_3700/s3606_coupon_code_validator/SolutionTest.kt
@@ -0,0 +1,33 @@
+package g3601_3700.s3606_coupon_code_validator
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun validateCoupons() {
+ assertThat>(
+ Solution()
+ .validateCoupons(
+ arrayOf("SAVE20", "", "PHARMA5", "SAVE@20"),
+ arrayOf("restaurant", "grocery", "pharmacy", "restaurant"),
+ booleanArrayOf(true, true, true, true),
+ ),
+ equalTo>(mutableListOf("PHARMA5", "SAVE20")),
+ )
+ }
+
+ @Test
+ fun validateCoupons2() {
+ assertThat>(
+ Solution()
+ .validateCoupons(
+ arrayOf("GROCERY15", "ELECTRONICS_50", "DISCOUNT10"),
+ arrayOf("grocery", "electronics", "invalid"),
+ booleanArrayOf(false, true, true),
+ ),
+ equalTo>(mutableListOf("ELECTRONICS_50")),
+ )
+ }
+}
diff --git a/src/test/kotlin/g3601_3700/s3607_power_grid_maintenance/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3607_power_grid_maintenance/SolutionTest.kt
new file mode 100644
index 00000000..9eb5185a
--- /dev/null
+++ b/src/test/kotlin/g3601_3700/s3607_power_grid_maintenance/SolutionTest.kt
@@ -0,0 +1,39 @@
+package g3601_3700.s3607_power_grid_maintenance
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun processQueries() {
+ assertThat(
+ Solution()
+ .processQueries(
+ 5,
+ arrayOf(intArrayOf(1, 2), intArrayOf(2, 3), intArrayOf(3, 4), intArrayOf(4, 5)),
+ arrayOf(
+ intArrayOf(1, 3),
+ intArrayOf(2, 1),
+ intArrayOf(1, 1),
+ intArrayOf(2, 2),
+ intArrayOf(1, 2),
+ ),
+ ),
+ equalTo(intArrayOf(3, 2, 3)),
+ )
+ }
+
+ @Test
+ fun processQueries2() {
+ assertThat(
+ Solution()
+ .processQueries(
+ 3,
+ arrayOf(),
+ arrayOf(intArrayOf(1, 1), intArrayOf(2, 1), intArrayOf(1, 1)),
+ ),
+ equalTo(intArrayOf(1, -1)),
+ )
+ }
+}
diff --git a/src/test/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/SolutionTest.kt
new file mode 100644
index 00000000..953f1189
--- /dev/null
+++ b/src/test/kotlin/g3601_3700/s3608_minimum_time_for_k_connected_components/SolutionTest.kt
@@ -0,0 +1,43 @@
+package g3601_3700.s3608_minimum_time_for_k_connected_components
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun minTime() {
+ assertThat(
+ Solution().minTime(2, arrayOf(intArrayOf(0, 1, 3)), 2),
+ equalTo(3),
+ )
+ }
+
+ @Test
+ fun minTime2() {
+ assertThat(
+ Solution().minTime(
+ 3,
+ arrayOf(intArrayOf(0, 1, 2), intArrayOf(1, 2, 4)),
+ 3,
+ ),
+ equalTo(4),
+ )
+ }
+
+ @Test
+ fun minTime3() {
+ assertThat(
+ Solution().minTime(3, arrayOf(intArrayOf(0, 2, 5)), 2),
+ equalTo(0),
+ )
+ }
+
+ @Test
+ fun minTime4() {
+ assertThat(
+ Solution().minTime(3, arrayOf(intArrayOf(2, 1, 1469), intArrayOf(1, 0, 5701)), 2),
+ equalTo(1469),
+ )
+ }
+}
diff --git a/src/test/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/SolutionTest.kt
new file mode 100644
index 00000000..7785172a
--- /dev/null
+++ b/src/test/kotlin/g3601_3700/s3609_minimum_moves_to_reach_target_in_grid/SolutionTest.kt
@@ -0,0 +1,100 @@
+package g3601_3700.s3609_minimum_moves_to_reach_target_in_grid
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun minMoves() {
+ assertThat(Solution().minMoves(1, 2, 5, 4), equalTo(2))
+ }
+
+ @Test
+ fun minMoves2() {
+ assertThat(Solution().minMoves(0, 1, 2, 3), equalTo(3))
+ }
+
+ @Test
+ fun minMoves3() {
+ assertThat(Solution().minMoves(1, 1, 2, 2), equalTo(-1))
+ }
+
+ @Test
+ fun minMoves4() {
+ assertThat(Solution().minMoves(0, 0, 0, 0), equalTo(0))
+ }
+
+ @Test
+ fun minMoves5() {
+ assertThat(Solution().minMoves(0, 0, 1, 0), equalTo(-1))
+ assertThat(Solution().minMoves(0, 0, 0, 1), equalTo(-1))
+ }
+
+ @Test
+ fun minMoves6() {
+ assertThat(Solution().minMoves(2, 0, 1, 0), equalTo(-1))
+ }
+
+ @Test
+ fun minMoves7() {
+ assertThat(Solution().minMoves(0, 2, 0, 1), equalTo(-1))
+ }
+
+ @Test
+ fun minMoves8() {
+ assertThat(Solution().minMoves(1, 1, 9, 4), equalTo(-1))
+ }
+
+ @Test
+ fun minMoves9() {
+ val result = Solution().minMoves(1, 1, 8, 3)
+ assertThat(result, equalTo(-1))
+ }
+
+ @Test
+ fun minMoves10() {
+ val result = Solution().minMoves(1, 1, 6, 4)
+ assertThat(result, equalTo(-1))
+ }
+
+ @Test
+ fun minMoves11() {
+ assertThat(Solution().minMoves(1, 1, 4, 9), equalTo(-1))
+ }
+
+ @Test
+ fun minMoves12() {
+ val result = Solution().minMoves(1, 1, 3, 8)
+ assertThat(result, equalTo(-1))
+ }
+
+ @Test
+ fun minMoves13() {
+ val result = Solution().minMoves(1, 1, 4, 6)
+ assertThat(result, equalTo(-1))
+ }
+
+ @Test
+ fun minMoves14() {
+ val result = Solution().minMoves(0, 2, 5, 5)
+ assertThat(result, equalTo(-1))
+ }
+
+ @Test
+ fun minMoves15() {
+ val result = Solution().minMoves(2, 0, 5, 5)
+ assertThat(result, equalTo(-1))
+ }
+
+ @Test
+ fun minMoves16() {
+ assertThat(Solution().minMoves(2, 2, 5, 5), equalTo(-1))
+ }
+
+ @Test
+ fun minMoves17() {
+ val result = Solution().minMoves(1, 1, 5, 2)
+ assertThat(result, equalTo(-1))
+ }
+}