diff --git a/build.gradle.kts b/build.gradle.kts index 22857c166..ce149b68e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,10 +15,10 @@ repositories { dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib:2.1.20") - testImplementation("org.junit.jupiter:junit-jupiter:[5.11.3,)") + testImplementation("org.junit.jupiter:junit-jupiter:[5.12.0,)") testImplementation("org.hamcrest:hamcrest-core:[3.0,)") - testImplementation("org.zapodot:embedded-db-junit-jupiter:[2.2.0,)") - testRuntimeOnly("org.junit.platform:junit-platform-launcher:[1.11.3,)") + testImplementation("org.zapodot:embedded-db-junit-jupiter:2.2.0") + testRuntimeOnly("org.junit.platform:junit-platform-launcher:[1.12.0,)") } tasks.test { diff --git a/src/main/kotlin/g3401_3500/s3498_reverse_degree_of_a_string/Solution.kt b/src/main/kotlin/g3401_3500/s3498_reverse_degree_of_a_string/Solution.kt new file mode 100644 index 000000000..002ed1525 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3498_reverse_degree_of_a_string/Solution.kt @@ -0,0 +1,13 @@ +package g3401_3500.s3498_reverse_degree_of_a_string + +// #Easy #String #Simulation #2025_04_01_Time_2_ms_(87.18%)_Space_42.65_MB_(89.74%) + +class Solution { + fun reverseDegree(s: String): Int { + var ans = 0 + for (i in 0.."10**1**001" → "1**0000**1""1**1111**1". +* The final string without augmentation is `"1111"`. The maximum number of active sections is 4. + +**Example 3:** + +**Input:** s = "1000100" + +**Output:** 7 + +**Explanation:** + +* String `"1000100"` → Augmented to `"110001001"`. +* Choose `"000100"`, convert "11000**1**001""11**000000**1""11**111111**1". +* The final string without augmentation is `"1111111"`. The maximum number of active sections is 7. + +**Example 4:** + +**Input:** s = "01010" + +**Output:** 4 + +**Explanation:** + +* String `"01010"` → Augmented to `"1010101"`. +* Choose `"010"`, convert "10**1**0101""1**000**101""1**111**101". +* The final string without augmentation is `"11110"`. The maximum number of active sections is 4. + +**Constraints:** + +* 1 <= n == s.length <= 105 +* `s[i]` is either `'0'` or `'1'` \ No newline at end of file diff --git a/src/main/kotlin/g3401_3500/s3500_minimum_cost_to_divide_array_into_subarrays/Solution.kt b/src/main/kotlin/g3401_3500/s3500_minimum_cost_to_divide_array_into_subarrays/Solution.kt new file mode 100644 index 000000000..02dd6ce86 --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3500_minimum_cost_to_divide_array_into_subarrays/Solution.kt @@ -0,0 +1,26 @@ +package g3401_3500.s3500_minimum_cost_to_divide_array_into_subarrays + +// #Hard #Array #Dynamic_Programming #Prefix_Sum +// #2025_04_01_Time_28_ms_(92.31%)_Space_49.69_MB_(69.23%) + +class Solution { + fun minimumCost(nums: IntArray, cost: IntArray, k: Int): Long { + val n = nums.size + val k = k.toLong() + val preNums = LongArray(n + 1) + val preCost = LongArray(n + 1) + for (i in 0..n - 1) { + preNums[i + 1] = preNums[i] + nums[i] + preCost[i + 1] = preCost[i] + cost[i] + } + val dp = LongArray(n + 1) { + Long.MAX_VALUE / 2 + }.also { it[0] = 0L } + for (r in 1..n) for (l in 0..r - 1) { + val sumNums = preNums[r] * (preCost[r] - preCost[l]) + val sumCost = k * (preCost[n] - preCost[l]) + dp[r] = minOf(dp[r], dp[l] + sumNums + sumCost) + } + return dp[n] + } +} diff --git a/src/main/kotlin/g3401_3500/s3500_minimum_cost_to_divide_array_into_subarrays/readme.md b/src/main/kotlin/g3401_3500/s3500_minimum_cost_to_divide_array_into_subarrays/readme.md new file mode 100644 index 000000000..0c94b088f --- /dev/null +++ b/src/main/kotlin/g3401_3500/s3500_minimum_cost_to_divide_array_into_subarrays/readme.md @@ -0,0 +1,47 @@ +3500\. Minimum Cost to Divide Array Into Subarrays + +Hard + +You are given two integer arrays, `nums` and `cost`, of the same size, and an integer `k`. + +You can divide `nums` into **non-empty subarrays**. The cost of the ith subarray consisting of elements `nums[l..r]` is: + +* `(nums[0] + nums[1] + ... + nums[r] + k * i) * (cost[l] + cost[l + 1] + ... + cost[r])`. + +**Note** that `i` represents the order of the subarray: 1 for the first subarray, 2 for the second, and so on. + +Return the **minimum** total cost possible from any valid division. + +**Example 1:** + +**Input:** nums = [3,1,4], cost = [4,6,6], k = 1 + +**Output:** 110 + +**Explanation:** + +The minimum total cost possible can be achieved by dividing `nums` into subarrays `[3, 1]` and `[4]`. + +* The cost of the first subarray `[3,1]` is `(3 + 1 + 1 * 1) * (4 + 6) = 50`. +* The cost of the second subarray `[4]` is `(3 + 1 + 4 + 1 * 2) * 6 = 60`. + +**Example 2:** + +**Input:** nums = [4,8,5,1,14,2,2,12,1], cost = [7,2,8,4,2,2,1,1,2], k = 7 + +**Output:** 985 + +**Explanation:** + +The minimum total cost possible can be achieved by dividing `nums` into subarrays `[4, 8, 5, 1]`, `[14, 2, 2]`, and `[12, 1]`. + +* The cost of the first subarray `[4, 8, 5, 1]` is `(4 + 8 + 5 + 1 + 7 * 1) * (7 + 2 + 8 + 4) = 525`. +* The cost of the second subarray `[14, 2, 2]` is `(4 + 8 + 5 + 1 + 14 + 2 + 2 + 7 * 2) * (2 + 2 + 1) = 250`. +* The cost of the third subarray `[12, 1]` is `(4 + 8 + 5 + 1 + 14 + 2 + 2 + 12 + 1 + 7 * 3) * (1 + 2) = 210`. + +**Constraints:** + +* `1 <= nums.length <= 1000` +* `cost.length == nums.length` +* `1 <= nums[i], cost[i] <= 1000` +* `1 <= k <= 1000` \ No newline at end of file diff --git a/src/main/kotlin/g3501_3600/s3501_maximize_active_section_with_trade_ii/Solution.kt b/src/main/kotlin/g3501_3600/s3501_maximize_active_section_with_trade_ii/Solution.kt new file mode 100644 index 000000000..87b47494c --- /dev/null +++ b/src/main/kotlin/g3501_3600/s3501_maximize_active_section_with_trade_ii/Solution.kt @@ -0,0 +1,144 @@ +package g3501_3600.s3501_maximize_active_section_with_trade_ii + +// #Hard #Array #String #Binary_Search #Segment_Tree +// #2025_04_01_Time_259_ms_(100.00%)_Space_140.14_MB_(_%) + +import kotlin.math.max + +class Solution { + fun maxActiveSectionsAfterTrade(s: String, queries: Array): List { + val n = s.length + var activeCount = 0 + for (ch in s.toCharArray()) { + if (ch == '1') { + activeCount++ + } + } + val segments: MutableList = ArrayList() + var start = 0 + for (i in 0..(maxPower) { IntArray(segmentCount) } + for (i in 0.. = ArrayList() + for (query in queries) { + val left = query[0] + val right = query[1] + val leftIndex = binarySearch(segments, left) - 1 + val rightIndex = binarySearch(segments, right) - 1 + if (rightIndex - leftIndex + 1 <= 2) { + result.add(activeCount) + continue + } + var bestIncrease = max(getMaxInRange(rmq, leftIndex + 1, rightIndex - 3), 0) + bestIncrease = max( + bestIncrease, + calculateNewSections( + s, segments, left, right, leftIndex, rightIndex, leftIndex, + ), + ) + bestIncrease = max( + bestIncrease, + calculateNewSections( + s, + segments, + left, + right, + leftIndex, + rightIndex, + rightIndex - 2, + ), + ) + result.add(activeCount + bestIncrease) + } + return result + } + + private fun binarySearch(segments: MutableList, key: Int): Int { + var lo = 0 + var hi = segments.size + while (lo < hi) { + val mid = lo + (hi - lo) / 2 + if (segments[mid]!![0] > key) { + hi = mid + } else { + lo = mid + 1 + } + } + return lo + } + + private fun getMaxInRange(rmq: Array, left: Int, right: Int): Int { + if (left > right) { + return NEG_INF + } + val power = 31 - Integer.numberOfLeadingZeros(right - left + 1) + return max(rmq[power][left], rmq[power][right - (1 shl power) + 1]) + } + + private fun getSegmentSize( + segments: MutableList, + left: Int, + right: Int, + leftIndex: Int, + rightIndex: Int, + i: Int, + ): Int { + if (i == leftIndex) { + return segments[leftIndex]!![1] - (left - segments[leftIndex]!![0]) + } + if (i == rightIndex) { + return right - segments[rightIndex]!![0] + 1 + } + return segments[i]!![1] + } + + private fun calculateNewSections( + s: String, + segments: MutableList, + left: Int, + right: Int, + leftIndex: Int, + rightIndex: Int, + i: Int, + ): Int { + if (i < 0 || i + 2 >= segments.size || s[segments[i]!![0]] == '1') { + return NEG_INF + } + val size1 = getSegmentSize(segments, left, right, leftIndex, rightIndex, i) + val size2 = getSegmentSize(segments, left, right, leftIndex, rightIndex, i + 2) + return size1 + size2 + } + + companion object { + private const val INF = 1e9 + private const val NEG_INF: Int = -INF.toInt() + } +} diff --git a/src/main/kotlin/g3501_3600/s3501_maximize_active_section_with_trade_ii/readme.md b/src/main/kotlin/g3501_3600/s3501_maximize_active_section_with_trade_ii/readme.md new file mode 100644 index 000000000..740d75a33 --- /dev/null +++ b/src/main/kotlin/g3501_3600/s3501_maximize_active_section_with_trade_ii/readme.md @@ -0,0 +1,105 @@ +3501\. Maximize Active Section with Trade II + +Hard + +You are given a binary string `s` of length `n`, where: + +* `'1'` represents an **active** section. +* `'0'` represents an **inactive** section. + +You can perform **at most one trade** to maximize the number of active sections in `s`. In a trade, you: + +* Convert a contiguous block of `'1'`s that is surrounded by `'0'`s to all `'0'`s. +* Afterward, convert a contiguous block of `'0'`s that is surrounded by `'1'`s to all `'1'`s. + +Additionally, you are given a **2D array** `queries`, where queries[i] = [li, ri] represents a **substring** s[li...ri]. + +For each query, determine the **maximum** possible number of active sections in `s` after making the optimal trade on the substring s[li...ri]. + +Return an array `answer`, where `answer[i]` is the result for `queries[i]`. + +**Note** + +* For each query, treat s[li...ri] as if it is **augmented** with a `'1'` at both ends, forming t = '1' + s[li...ri] + '1'. The augmented `'1'`s **do not** contribute to the final count. +* The queries are independent of each other. + +**Example 1:** + +**Input:** s = "01", queries = [[0,1]] + +**Output:** [1] + +**Explanation:** + +Because there is no block of `'1'`s surrounded by `'0'`s, no valid trade is possible. The maximum number of active sections is 1. + +**Example 2:** + +**Input:** s = "0100", queries = [[0,3],[0,2],[1,3],[2,3]] + +**Output:** [4,3,1,1] + +**Explanation:** + +* Query `[0, 3]` → Substring `"0100"` → Augmented to `"101001"` + Choose `"0100"`, convert `"0100"` → `"0000"` → `"1111"`. + The final string without augmentation is `"1111"`. The maximum number of active sections is 4. + +* Query `[0, 2]` → Substring `"010"` → Augmented to `"10101"` + Choose `"010"`, convert `"010"` → `"000"` → `"111"`. + The final string without augmentation is `"1110"`. The maximum number of active sections is 3. + +* Query `[1, 3]` → Substring `"100"` → Augmented to `"11001"` + Because there is no block of `'1'`s surrounded by `'0'`s, no valid trade is possible. The maximum number of active sections is 1. + +* Query `[2, 3]` → Substring `"00"` → Augmented to `"1001"` + Because there is no block of `'1'`s surrounded by `'0'`s, no valid trade is possible. The maximum number of active sections is 1. + + +**Example 3:** + +**Input:** s = "1000100", queries = [[1,5],[0,6],[0,4]] + +**Output:** [6,7,2] + +**Explanation:** + +* Query `[1, 5]` → Substring `"00010"` → Augmented to `"1000101"` + Choose `"00010"`, convert `"00010"` → `"00000"` → `"11111"`. + The final string without augmentation is `"1111110"`. The maximum number of active sections is 6. + +* Query `[0, 6]` → Substring `"1000100"` → Augmented to `"110001001"` + Choose `"000100"`, convert `"000100"` → `"000000"` → `"111111"`. + The final string without augmentation is `"1111111"`. The maximum number of active sections is 7. + +* Query `[0, 4]` → Substring `"10001"` → Augmented to `"1100011"` + Because there is no block of `'1'`s surrounded by `'0'`s, no valid trade is possible. The maximum number of active sections is 2. + + +**Example 4:** + +**Input:** s = "01010", queries = [[0,3],[1,4],[1,3]] + +**Output:** [4,4,2] + +**Explanation:** + +* Query `[0, 3]` → Substring `"0101"` → Augmented to `"101011"` + Choose `"010"`, convert `"010"` → `"000"` → `"111"`. + The final string without augmentation is `"11110"`. The maximum number of active sections is 4. + +* Query `[1, 4]` → Substring `"1010"` → Augmented to `"110101"` + Choose `"010"`, convert `"010"` → `"000"` → `"111"`. + The final string without augmentation is `"01111"`. The maximum number of active sections is 4. + +* Query `[1, 3]` → Substring `"101"` → Augmented to `"11011"` + Because there is no block of `'1'`s surrounded by `'0'`s, no valid trade is possible. The maximum number of active sections is 2. + + +**Constraints:** + +* 1 <= n == s.length <= 105 +* 1 <= queries.length <= 105 +* `s[i]` is either `'0'` or `'1'`. +* queries[i] = [li, ri] +* 0 <= li <= ri < n \ No newline at end of file diff --git a/src/main/kotlin/g3501_3600/s3502_minimum_cost_to_reach_every_position/Solution.kt b/src/main/kotlin/g3501_3600/s3502_minimum_cost_to_reach_every_position/Solution.kt new file mode 100644 index 000000000..837dc0cb7 --- /dev/null +++ b/src/main/kotlin/g3501_3600/s3502_minimum_cost_to_reach_every_position/Solution.kt @@ -0,0 +1,18 @@ +package g3501_3600.s3502_minimum_cost_to_reach_every_position + +// #Easy #Array #2025_04_01_Time_1_ms_(100.00%)_Space_46.62_MB_(96.30%) + +import kotlin.math.min + +class Solution { + fun minCosts(cost: IntArray): IntArray { + var min = cost[0] + val ans = IntArray(cost.size) + ans[0] = min + for (i in 1..(sLen) { IntArray(tLen + 1) } + sPa = IntArray(sLen) + tPa = IntArray(tLen) + var maxLen = 1 + for (j in 0..= 0 && right < ss.size && ss[left] == ss[right]) { + len += 2 + left-- + right++ + } + if (left >= 0) { + len += sPa[left] + } + return len + } + + private fun maxT(left: Int, right: Int): Int { + var left = left + var right = right + var len = 0 + while (left >= 0 && right < tt.size && tt[left] == tt[right]) { + len += 2 + left-- + right++ + } + if (right < tt.size) { + len += tPa[right] + } + return len + } +} diff --git a/src/main/kotlin/g3501_3600/s3504_longest_palindrome_after_substring_concatenation_ii/readme.md b/src/main/kotlin/g3501_3600/s3504_longest_palindrome_after_substring_concatenation_ii/readme.md new file mode 100644 index 000000000..8760ac849 --- /dev/null +++ b/src/main/kotlin/g3501_3600/s3504_longest_palindrome_after_substring_concatenation_ii/readme.md @@ -0,0 +1,54 @@ +3504\. Longest Palindrome After Substring Concatenation II + +Hard + +You are given two strings, `s` and `t`. + +You can create a new string by selecting a **substring** from `s` (possibly empty) and a substring from `t` (possibly empty), then concatenating them **in order**. + +Return the length of the **longest** palindrome that can be formed this way. + +**Example 1:** + +**Input:** s = "a", t = "a" + +**Output:** 2 + +**Explanation:** + +Concatenating `"a"` from `s` and `"a"` from `t` results in `"aa"`, which is a palindrome of length 2. + +**Example 2:** + +**Input:** s = "abc", t = "def" + +**Output:** 1 + +**Explanation:** + +Since all characters are different, the longest palindrome is any single character, so the answer is 1. + +**Example 3:** + +**Input:** s = "b", t = "aaaa" + +**Output:** 4 + +**Explanation:** + +Selecting "`aaaa`" from `t` is the longest palindrome, so the answer is 4. + +**Example 4:** + +**Input:** s = "abcde", t = "ecdba" + +**Output:** 5 + +**Explanation:** + +Concatenating `"abc"` from `s` and `"ba"` from `t` results in `"abcba"`, which is a palindrome of length 5. + +**Constraints:** + +* `1 <= s.length, t.length <= 1000` +* `s` and `t` consist of lowercase English letters. \ No newline at end of file diff --git a/src/main/kotlin/g3501_3600/s3505_minimum_operations_to_make_elements_within_k_subarrays_equal/Solution.kt b/src/main/kotlin/g3501_3600/s3505_minimum_operations_to_make_elements_within_k_subarrays_equal/Solution.kt new file mode 100644 index 000000000..68da36dcf --- /dev/null +++ b/src/main/kotlin/g3501_3600/s3505_minimum_operations_to_make_elements_within_k_subarrays_equal/Solution.kt @@ -0,0 +1,137 @@ +package g3501_3600.s3505_minimum_operations_to_make_elements_within_k_subarrays_equal + +// #Hard #Array #Hash_Table #Dynamic_Programming #Math #Heap_Priority_Queue #Sliding_Window +// #2025_04_01_Time_537_ms_(100.00%)_Space_115.99_MB_(20.00%) + +import java.util.Collections +import java.util.PriorityQueue +import kotlin.math.min + +class Solution { + private class SlidingMedian { + // max-heap for smaller half + var leftHeap: PriorityQueue + + // min-heap for larger half + var rightHeap: PriorityQueue + var delayedRemovals: MutableMap + var sumLeft: Long + var sumRight: Long = 0 + var sizeLeft: Int + var sizeRight: Int + + init { + leftHeap = PriorityQueue(Collections.reverseOrder()) + rightHeap = PriorityQueue() + delayedRemovals = HashMap() + sumLeft = sumRight + sizeRight = 0 + sizeLeft = sizeRight + } + + fun add(num: Int) { + if (leftHeap.isEmpty() || num <= leftHeap.peek()!!) { + leftHeap.offer(num) + sumLeft += num + sizeLeft++ + } else { + rightHeap.offer(num) + sumRight += num + sizeRight++ + } + balanceHeaps() + } + + fun remove(num: Int) { + delayedRemovals.put(num, delayedRemovals.getOrDefault(num, 0) + 1) + if (leftHeap.isNotEmpty() && num <= leftHeap.peek()!!) { + sumLeft -= num + sizeLeft-- + } else { + sumRight -= num + sizeRight-- + } + balanceHeaps() + pruneHeap(leftHeap) + pruneHeap(rightHeap) + } + + fun balanceHeaps() { + if (sizeLeft > sizeRight + 1) { + val num = leftHeap.poll()!! + sumLeft -= num + sizeLeft-- + rightHeap.offer(num) + sumRight += num + sizeRight++ + } else if (sizeRight > sizeLeft) { + val num = rightHeap.poll()!! + sumRight -= num + sizeRight-- + leftHeap.offer(num) + sumLeft += num + sizeLeft++ + } + } + + fun pruneHeap(heap: PriorityQueue) { + while (heap.isNotEmpty() && delayedRemovals.containsKey(heap.peek())) { + val num: Int = heap.peek()!! + if (delayedRemovals[num]!! > 0) { + heap.poll() + delayedRemovals.put(num, delayedRemovals[num]!! - 1) + if (delayedRemovals[num] == 0) { + delayedRemovals.remove(num) + } + } else { + break + } + } + } + + val median: Int + get() = leftHeap.peek()!! + + val cost: Long + get() { + val median = this.median + return median * sizeLeft - sumLeft + sumRight - median * sizeRight + } + } + + fun minOperations(nums: IntArray, x: Int, k: Int): Long { + val n = nums.size + val windowCount = n - x + 1 + val costs = LongArray(windowCount) + val sm = SlidingMedian() + // Compute costs for all windows + for (i in 0.. = Array(windowCount) { LongArray(k + 1) } + for (row in dp) { + row.fill(Long.Companion.MAX_VALUE / 2) + } + dp[0][0] = 0 + for (i in 0.. 0) { + dp[i][j] = min(dp[i][j], dp[i - 1][j]) + } + if (j > 0 && i >= x) { + dp[i][j] = min(dp[i][j], (dp[i - x][j - 1] + costs[i])) + } else if (j == 1) { + dp[i][j] = min(dp[i][j], costs[i]) + } + } + } + return dp[windowCount - 1][k] + } +} diff --git a/src/main/kotlin/g3501_3600/s3505_minimum_operations_to_make_elements_within_k_subarrays_equal/readme.md b/src/main/kotlin/g3501_3600/s3505_minimum_operations_to_make_elements_within_k_subarrays_equal/readme.md new file mode 100644 index 000000000..439402d64 --- /dev/null +++ b/src/main/kotlin/g3501_3600/s3505_minimum_operations_to_make_elements_within_k_subarrays_equal/readme.md @@ -0,0 +1,40 @@ +3505\. Minimum Operations to Make Elements Within K Subarrays Equal + +Hard + +You are given an integer array `nums` and two integers, `x` and `k`. You can perform the following operation any number of times (**including zero**): + +* Increase or decrease any element of `nums` by 1. + +Return the **minimum** number of operations needed to have **at least** `k` _non-overlapping **non-empty subarrays**_ of size **exactly** `x` in `nums`, where all elements within each subarray are equal. + +**Example 1:** + +**Input:** nums = [5,-2,1,3,7,3,6,4,-1], x = 3, k = 2 + +**Output:** 8 + +**Explanation:** + +* Use 3 operations to add 3 to `nums[1]` and use 2 operations to subtract 2 from `nums[3]`. The resulting array is `[5, 1, 1, 1, 7, 3, 6, 4, -1]`. +* Use 1 operation to add 1 to `nums[5]` and use 2 operations to subtract 2 from `nums[6]`. The resulting array is `[5, 1, 1, 1, 7, 4, 4, 4, -1]`. +* Now, all elements within each subarray `[1, 1, 1]` (from indices 1 to 3) and `[4, 4, 4]` (from indices 5 to 7) are equal. Since 8 total operations were used, 8 is the output. + +**Example 2:** + +**Input:** nums = [9,-2,-2,-2,1,5], x = 2, k = 2 + +**Output:** 3 + +**Explanation:** + +* Use 3 operations to subtract 3 from `nums[4]`. The resulting array is `[9, -2, -2, -2, -2, 5]`. +* Now, all elements within each subarray `[-2, -2]` (from indices 1 to 2) and `[-2, -2]` (from indices 3 to 4) are equal. Since 3 operations were used, 3 is the output. + +**Constraints:** + +* 2 <= nums.length <= 105 +* -106 <= nums[i] <= 106 +* `2 <= x <= nums.length` +* `1 <= k <= 15` +* `2 <= k * x <= nums.length` \ No newline at end of file diff --git a/src/test/kotlin/g3401_3500/s3498_reverse_degree_of_a_string/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3498_reverse_degree_of_a_string/SolutionTest.kt new file mode 100644 index 000000000..a6678ee17 --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3498_reverse_degree_of_a_string/SolutionTest.kt @@ -0,0 +1,17 @@ +package g3401_3500.s3498_reverse_degree_of_a_string + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun reverseDegree() { + assertThat(Solution().reverseDegree("abc"), equalTo(148)) + } + + @Test + fun reverseDegree2() { + assertThat(Solution().reverseDegree("zaza"), equalTo(160)) + } +} diff --git a/src/test/kotlin/g3401_3500/s3499_maximize_active_section_with_trade_i/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3499_maximize_active_section_with_trade_i/SolutionTest.kt new file mode 100644 index 000000000..72928f250 --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3499_maximize_active_section_with_trade_i/SolutionTest.kt @@ -0,0 +1,27 @@ +package g3401_3500.s3499_maximize_active_section_with_trade_i + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maxActiveSectionsAfterTrade() { + assertThat(Solution().maxActiveSectionsAfterTrade("01"), equalTo(1)) + } + + @Test + fun maxActiveSectionsAfterTrade2() { + assertThat(Solution().maxActiveSectionsAfterTrade("0100"), equalTo(4)) + } + + @Test + fun maxActiveSectionsAfterTrade3() { + assertThat(Solution().maxActiveSectionsAfterTrade("1000100"), equalTo(7)) + } + + @Test + fun maxActiveSectionsAfterTrade4() { + assertThat(Solution().maxActiveSectionsAfterTrade("01010"), equalTo(4)) + } +} diff --git a/src/test/kotlin/g3401_3500/s3500_minimum_cost_to_divide_array_into_subarrays/SolutionTest.kt b/src/test/kotlin/g3401_3500/s3500_minimum_cost_to_divide_array_into_subarrays/SolutionTest.kt new file mode 100644 index 000000000..a932bebfc --- /dev/null +++ b/src/test/kotlin/g3401_3500/s3500_minimum_cost_to_divide_array_into_subarrays/SolutionTest.kt @@ -0,0 +1,28 @@ +package g3401_3500.s3500_minimum_cost_to_divide_array_into_subarrays + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun minimumCost() { + assertThat( + Solution().minimumCost(intArrayOf(3, 1, 4), intArrayOf(4, 6, 6), 1), + equalTo(110L), + ) + } + + @Test + fun minimumCost2() { + assertThat( + Solution() + .minimumCost( + intArrayOf(4, 8, 5, 1, 14, 2, 2, 12, 1), + intArrayOf(7, 2, 8, 4, 2, 2, 1, 1, 2), + 7, + ), + equalTo(985L), + ) + } +} diff --git a/src/test/kotlin/g3501_3600/s3501_maximize_active_section_with_trade_ii/SolutionTest.kt b/src/test/kotlin/g3501_3600/s3501_maximize_active_section_with_trade_ii/SolutionTest.kt new file mode 100644 index 000000000..ed3e2da32 --- /dev/null +++ b/src/test/kotlin/g3501_3600/s3501_maximize_active_section_with_trade_ii/SolutionTest.kt @@ -0,0 +1,63 @@ +package g3501_3600.s3501_maximize_active_section_with_trade_ii + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun maxActiveSectionsAfterTrade() { + assertThat>( + Solution().maxActiveSectionsAfterTrade("01", arrayOf(intArrayOf(0, 1))), + equalTo>(listOf(1)), + ) + } + + @Test + fun maxActiveSectionsAfterTrade2() { + assertThat>( + Solution() + .maxActiveSectionsAfterTrade( + "0100", + arrayOf(intArrayOf(0, 3), intArrayOf(0, 2), intArrayOf(1, 3), intArrayOf(2, 3)), + ), + equalTo>(listOf(4, 3, 1, 1)), + ) + } + + @Test + fun maxActiveSectionsAfterTrade3() { + assertThat>( + Solution() + .maxActiveSectionsAfterTrade( + "1000100", + arrayOf(intArrayOf(1, 5), intArrayOf(0, 6), intArrayOf(0, 4)), + ), + equalTo>(listOf(6, 7, 2)), + ) + } + + @Test + fun maxActiveSectionsAfterTrade4() { + assertThat>( + Solution() + .maxActiveSectionsAfterTrade( + "01010", + arrayOf(intArrayOf(0, 3), intArrayOf(1, 4), intArrayOf(1, 3)), + ), + equalTo>(listOf(4, 4, 2)), + ) + } + + @Test + fun maxActiveSectionsAfterTrade5() { + assertThat>( + Solution() + .maxActiveSectionsAfterTrade( + "10110111", + arrayOf(intArrayOf(3, 7), intArrayOf(4, 6), intArrayOf(0, 6)), + ), + equalTo>(listOf(6, 6, 8)), + ) + } +} diff --git a/src/test/kotlin/g3501_3600/s3502_minimum_cost_to_reach_every_position/SolutionTest.kt b/src/test/kotlin/g3501_3600/s3502_minimum_cost_to_reach_every_position/SolutionTest.kt new file mode 100644 index 000000000..bc2b41248 --- /dev/null +++ b/src/test/kotlin/g3501_3600/s3502_minimum_cost_to_reach_every_position/SolutionTest.kt @@ -0,0 +1,23 @@ +package g3501_3600.s3502_minimum_cost_to_reach_every_position + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun minCosts() { + assertThat( + Solution().minCosts(intArrayOf(5, 3, 4, 1, 3, 2)), + equalTo(intArrayOf(5, 3, 3, 1, 1, 1)), + ) + } + + @Test + fun minCosts2() { + assertThat( + Solution().minCosts(intArrayOf(1, 2, 4, 6, 7)), + equalTo(intArrayOf(1, 1, 1, 1, 1)), + ) + } +} diff --git a/src/test/kotlin/g3501_3600/s3503_longest_palindrome_after_substring_concatenation_i/SolutionTest.kt b/src/test/kotlin/g3501_3600/s3503_longest_palindrome_after_substring_concatenation_i/SolutionTest.kt new file mode 100644 index 000000000..ff6f93ed3 --- /dev/null +++ b/src/test/kotlin/g3501_3600/s3503_longest_palindrome_after_substring_concatenation_i/SolutionTest.kt @@ -0,0 +1,27 @@ +package g3501_3600.s3503_longest_palindrome_after_substring_concatenation_i + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun longestPalindrome() { + assertThat(Solution().longestPalindrome("a", "a"), equalTo(2)) + } + + @Test + fun longestPalindrome2() { + assertThat(Solution().longestPalindrome("abc", "def"), equalTo(1)) + } + + @Test + fun longestPalindrome3() { + assertThat(Solution().longestPalindrome("b", "aaaa"), equalTo(4)) + } + + @Test + fun longestPalindrome4() { + assertThat(Solution().longestPalindrome("abcde", "ecdba"), equalTo(5)) + } +} diff --git a/src/test/kotlin/g3501_3600/s3504_longest_palindrome_after_substring_concatenation_ii/SolutionTest.kt b/src/test/kotlin/g3501_3600/s3504_longest_palindrome_after_substring_concatenation_ii/SolutionTest.kt new file mode 100644 index 000000000..f10be9fe2 --- /dev/null +++ b/src/test/kotlin/g3501_3600/s3504_longest_palindrome_after_substring_concatenation_ii/SolutionTest.kt @@ -0,0 +1,32 @@ +package g3501_3600.s3504_longest_palindrome_after_substring_concatenation_ii + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun longestPalindrome() { + assertThat(Solution().longestPalindrome("a", "a"), equalTo(2)) + } + + @Test + fun longestPalindrome2() { + assertThat(Solution().longestPalindrome("abc", "def"), equalTo(1)) + } + + @Test + fun longestPalindrome3() { + assertThat(Solution().longestPalindrome("b", "aaaa"), equalTo(4)) + } + + @Test + fun longestPalindrome4() { + assertThat(Solution().longestPalindrome("abcde", "ecdba"), equalTo(5)) + } + + @Test + fun longestPalindrome5() { + assertThat(Solution().longestPalindrome("xxz", "z"), equalTo(2)) + } +} diff --git a/src/test/kotlin/g3501_3600/s3505_minimum_operations_to_make_elements_within_k_subarrays_equal/SolutionTest.kt b/src/test/kotlin/g3501_3600/s3505_minimum_operations_to_make_elements_within_k_subarrays_equal/SolutionTest.kt new file mode 100644 index 000000000..4d42adac4 --- /dev/null +++ b/src/test/kotlin/g3501_3600/s3505_minimum_operations_to_make_elements_within_k_subarrays_equal/SolutionTest.kt @@ -0,0 +1,23 @@ +package g3501_3600.s3505_minimum_operations_to_make_elements_within_k_subarrays_equal + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun minOperations() { + assertThat( + Solution().minOperations(intArrayOf(5, -2, 1, 3, 7, 3, 6, 4, -1), 3, 2), + equalTo(8L), + ) + } + + @Test + fun minOperations2() { + assertThat( + Solution().minOperations(intArrayOf(9, -2, -2, -2, 1, 5), 2, 2), + equalTo(3L), + ) + } +}