diff --git a/src/main/kotlin/g3001_3100/s3038_maximum_number_of_operations_with_the_same_score_i/Solution.kt b/src/main/kotlin/g3001_3100/s3038_maximum_number_of_operations_with_the_same_score_i/Solution.kt
new file mode 100644
index 00000000..873f2e56
--- /dev/null
+++ b/src/main/kotlin/g3001_3100/s3038_maximum_number_of_operations_with_the_same_score_i/Solution.kt
@@ -0,0 +1,21 @@
+package g3001_3100.s3038_maximum_number_of_operations_with_the_same_score_i
+
+// #Easy #Array #Simulation #2024_03_06_Time_142_ms_(100.00%)_Space_34.9_MB_(57.78%)
+
+class Solution {
+ fun maxOperations(nums: IntArray): Int {
+ var c = 1
+ var i = 2
+ val s = nums[0] + nums[1]
+ val l = nums.size - (if (nums.size % 2 == 0) 0 else 1)
+ while (i < l) {
+ if (nums[i] + nums[i + 1] == s) {
+ c++
+ } else {
+ break
+ }
+ i += 2
+ }
+ return c
+ }
+}
diff --git a/src/main/kotlin/g3001_3100/s3038_maximum_number_of_operations_with_the_same_score_i/readme.md b/src/main/kotlin/g3001_3100/s3038_maximum_number_of_operations_with_the_same_score_i/readme.md
new file mode 100644
index 00000000..11b175c8
--- /dev/null
+++ b/src/main/kotlin/g3001_3100/s3038_maximum_number_of_operations_with_the_same_score_i/readme.md
@@ -0,0 +1,41 @@
+3038\. Maximum Number of Operations With the Same Score I
+
+Easy
+
+Given an array of integers called `nums`, you can perform the following operation while `nums` contains **at least** `2` elements:
+
+* Choose the first two elements of `nums` and delete them.
+
+The **score** of the operation is the sum of the deleted elements.
+
+Your task is to find the **maximum** number of operations that can be performed, such that **all operations have the same score**.
+
+Return _the **maximum** number of operations possible that satisfy the condition mentioned above_.
+
+**Example 1:**
+
+**Input:** nums = [3,2,1,4,5]
+
+**Output:** 2
+
+**Explanation:** We perform the following operations:
+- Delete the first two elements, with score 3 + 2 = 5, nums = [1,4,5].
+- Delete the first two elements, with score 1 + 4 = 5, nums = [5].
+
+We are unable to perform any more operations as nums contain only 1 element.
+
+**Example 2:**
+
+**Input:** nums = [3,2,6,1,4]
+
+**Output:** 1
+
+**Explanation:** We perform the following operations:
+- Delete the first two elements, with score 3 + 2 = 5, nums = [6,1,4].
+
+We are unable to perform any more operations as the score of the next operation isn't the same as the previous one.
+
+**Constraints:**
+
+* `2 <= nums.length <= 100`
+* `1 <= nums[i] <= 1000`
\ No newline at end of file
diff --git a/src/main/kotlin/g3001_3100/s3039_apply_operations_to_make_string_empty/Solution.kt b/src/main/kotlin/g3001_3100/s3039_apply_operations_to_make_string_empty/Solution.kt
new file mode 100644
index 00000000..ff31c177
--- /dev/null
+++ b/src/main/kotlin/g3001_3100/s3039_apply_operations_to_make_string_empty/Solution.kt
@@ -0,0 +1,27 @@
+package g3001_3100.s3039_apply_operations_to_make_string_empty
+
+// #Medium #Array #Hash_Table #Sorting #Counting
+// #2024_03_06_Time_335_ms_(97.73%)_Space_49.8_MB_(81.82%)
+
+import kotlin.math.max
+
+class Solution {
+ fun lastNonEmptyString(s: String): String {
+ val freq = IntArray(26)
+ val ar = s.toCharArray()
+ val n = ar.size
+ var max = 1
+ val sb = StringBuilder()
+ for (c in ar) {
+ freq[c.code - 'a'.code]++
+ max = max(freq[c.code - 'a'.code].toDouble(), max.toDouble()).toInt()
+ }
+ for (i in n - 1 downTo 0) {
+ if (freq[ar[i].code - 'a'.code] == max) {
+ sb.append(ar[i])
+ freq[ar[i].code - 'a'.code] = 0
+ }
+ }
+ return sb.reverse().toString()
+ }
+}
diff --git a/src/main/kotlin/g3001_3100/s3039_apply_operations_to_make_string_empty/readme.md b/src/main/kotlin/g3001_3100/s3039_apply_operations_to_make_string_empty/readme.md
new file mode 100644
index 00000000..9d757a62
--- /dev/null
+++ b/src/main/kotlin/g3001_3100/s3039_apply_operations_to_make_string_empty/readme.md
@@ -0,0 +1,41 @@
+3039\. Apply Operations to Make String Empty
+
+Medium
+
+You are given a string `s`.
+
+Consider performing the following operation until `s` becomes **empty**:
+
+* For **every** alphabet character from `'a'` to `'z'`, remove the **first** occurrence of that character in `s` (if it exists).
+
+For example, let initially `s = "aabcbbca"`. We do the following operations:
+
+* Remove the underlined characters s = "**a**a**bc**bbca"
. The resulting string is `s = "abbca"`.
+* Remove the underlined characters s = "**ab**b**c**a"
. The resulting string is `s = "ba"`.
+* Remove the underlined characters s = "**ba**"
. The resulting string is `s = ""`.
+
+Return _the value of the string_ `s` _right **before** applying the **last** operation_. In the example above, answer is `"ba"`.
+
+**Example 1:**
+
+**Input:** s = "aabcbbca"
+
+**Output:** "ba"
+
+**Explanation:** Explained in the statement.
+
+**Example 2:**
+
+**Input:** s = "abcd"
+
+**Output:** "abcd"
+
+**Explanation:** We do the following operation:
+- Remove the underlined characters s = "**abcd**". The resulting string is s = "".
+
+The string just before the last operation is "abcd".
+
+**Constraints:**
+
+* 1 <= s.length <= 5 * 105
+* `s` consists only of lowercase English letters.
\ No newline at end of file
diff --git a/src/main/kotlin/g3001_3100/s3040_maximum_number_of_operations_with_the_same_score_ii/Solution.kt b/src/main/kotlin/g3001_3100/s3040_maximum_number_of_operations_with_the_same_score_ii/Solution.kt
new file mode 100644
index 00000000..c283bd0e
--- /dev/null
+++ b/src/main/kotlin/g3001_3100/s3040_maximum_number_of_operations_with_the_same_score_ii/Solution.kt
@@ -0,0 +1,71 @@
+package g3001_3100.s3040_maximum_number_of_operations_with_the_same_score_ii
+
+// #Medium #Array #Dynamic_Programming #Memoization
+// #2024_03_06_Time_179_ms_(100.00%)_Space_38.4_MB_(100.00%)
+
+import java.util.Objects
+import kotlin.math.max
+
+class Solution {
+ private lateinit var nums: IntArray
+
+ private var maxOps = 1
+
+ private val dp: MutableMap = HashMap()
+
+ private class Pos(var start: Int, var end: Int, var sum: Int) {
+ override fun equals(other: Any?): Boolean {
+ if (other == null) {
+ return false
+ }
+ if (other !is Pos) {
+ return false
+ }
+ return start == other.start && end == other.end && sum == other.sum
+ }
+
+ override fun hashCode(): Int {
+ return Objects.hash(start, end, sum)
+ }
+ }
+
+ fun maxOperations(nums: IntArray): Int {
+ this.nums = nums
+ val length = nums.size
+
+ maxOperations(2, length - 1, nums[0] + nums[1], 1)
+ maxOperations(0, length - 3, nums[length - 2] + nums[length - 1], 1)
+ maxOperations(1, length - 2, nums[0] + nums[length - 1], 1)
+
+ return maxOps
+ }
+
+ private fun maxOperations(start: Int, end: Int, sum: Int, nOps: Int) {
+ if (start >= end) {
+ return
+ }
+
+ if ((((end - start) / 2) + nOps) < maxOps) {
+ return
+ }
+
+ val pos = Pos(start, end, sum)
+ val posNops = dp[pos]
+ if (posNops != null && posNops >= nOps) {
+ return
+ }
+ dp[pos] = nOps
+ if (nums[start] + nums[start + 1] == sum) {
+ maxOps = max(maxOps, (nOps + 1))
+ maxOperations(start + 2, end, sum, nOps + 1)
+ }
+ if (nums[end - 1] + nums[end] == sum) {
+ maxOps = max(maxOps, (nOps + 1))
+ maxOperations(start, end - 2, sum, nOps + 1)
+ }
+ if (nums[start] + nums[end] == sum) {
+ maxOps = max(maxOps, (nOps + 1))
+ maxOperations(start + 1, end - 1, sum, nOps + 1)
+ }
+ }
+}
diff --git a/src/main/kotlin/g3001_3100/s3040_maximum_number_of_operations_with_the_same_score_ii/readme.md b/src/main/kotlin/g3001_3100/s3040_maximum_number_of_operations_with_the_same_score_ii/readme.md
new file mode 100644
index 00000000..9efe7c93
--- /dev/null
+++ b/src/main/kotlin/g3001_3100/s3040_maximum_number_of_operations_with_the_same_score_ii/readme.md
@@ -0,0 +1,45 @@
+3040\. Maximum Number of Operations With the Same Score II
+
+Medium
+
+Given an array of integers called `nums`, you can perform **any** of the following operation while `nums` contains **at least** `2` elements:
+
+* Choose the first two elements of `nums` and delete them.
+* Choose the last two elements of `nums` and delete them.
+* Choose the first and the last elements of `nums` and delete them.
+
+The **score** of the operation is the sum of the deleted elements.
+
+Your task is to find the **maximum** number of operations that can be performed, such that **all operations have the same score**.
+
+Return _the **maximum** number of operations possible that satisfy the condition mentioned above_.
+
+**Example 1:**
+
+**Input:** nums = [3,2,1,2,3,4]
+
+**Output:** 3
+
+**Explanation:** We perform the following operations:
+- Delete the first two elements, with score 3 + 2 = 5, nums = [1,2,3,4].
+- Delete the first and the last elements, with score 1 + 4 = 5, nums = [2,3].
+- Delete the first and the last elements, with score 2 + 3 = 5, nums = [].
+
+We are unable to perform any more operations as nums is empty.
+
+**Example 2:**
+
+**Input:** nums = [3,2,6,1,4]
+
+**Output:** 2
+
+**Explanation:** We perform the following operations:
+- Delete the first two elements, with score 3 + 2 = 5, nums = [6,1,4].
+- Delete the last two elements, with score 1 + 4 = 5, nums = [6].
+
+It can be proven that we can perform at most 2 operations.
+
+**Constraints:**
+
+* `2 <= nums.length <= 2000`
+* `1 <= nums[i] <= 1000`
\ No newline at end of file
diff --git a/src/main/kotlin/g3001_3100/s3047_find_the_largest_area_of_square_inside_two_rectangles/Solution.kt b/src/main/kotlin/g3001_3100/s3047_find_the_largest_area_of_square_inside_two_rectangles/Solution.kt
new file mode 100644
index 00000000..a26869fe
--- /dev/null
+++ b/src/main/kotlin/g3001_3100/s3047_find_the_largest_area_of_square_inside_two_rectangles/Solution.kt
@@ -0,0 +1,34 @@
+package g3001_3100.s3047_find_the_largest_area_of_square_inside_two_rectangles
+
+// #Medium #Array #Math #Geometry #2024_03_06_Time_753_ms_(40.42%)_Space_57.7_MB_(72.34%)
+
+import kotlin.math.max
+import kotlin.math.min
+import kotlin.math.pow
+
+class Solution {
+ fun largestSquareArea(bottomLeft: Array, topRight: Array): Long {
+ val n = bottomLeft.size
+ var maxArea: Long = 0
+ for (i in 0 until n) {
+ val ax = bottomLeft[i][0]
+ val ay = bottomLeft[i][1]
+ val bx = topRight[i][0]
+ val by = topRight[i][1]
+ for (j in i + 1 until n) {
+ val cx = bottomLeft[j][0]
+ val cy = bottomLeft[j][1]
+ val dx = topRight[j][0]
+ val dy = topRight[j][1]
+ val x1 = max(ax, cx)
+ val y1 = max(ay, cy)
+ val x2 = min(bx, dx)
+ val y2 = min(by, dy)
+ val minSide = min((x2 - x1), (y2 - y1))
+ val area = max(minSide.toDouble(), 0.0).pow(2.0).toLong()
+ maxArea = max(maxArea, area)
+ }
+ }
+ return maxArea
+ }
+}
diff --git a/src/main/kotlin/g3001_3100/s3047_find_the_largest_area_of_square_inside_two_rectangles/readme.md b/src/main/kotlin/g3001_3100/s3047_find_the_largest_area_of_square_inside_two_rectangles/readme.md
new file mode 100644
index 00000000..b37d2a4a
--- /dev/null
+++ b/src/main/kotlin/g3001_3100/s3047_find_the_largest_area_of_square_inside_two_rectangles/readme.md
@@ -0,0 +1,53 @@
+3047\. Find the Largest Area of Square Inside Two Rectangles
+
+Medium
+
+There exist `n` rectangles in a 2D plane. You are given two **0-indexed** 2D integer arrays `bottomLeft` and `topRight`, both of size `n x 2`, where `bottomLeft[i]` and `topRight[i]` represent the **bottom-left** and **top-right** coordinates of the ith
rectangle respectively.
+
+You can select a region formed from the **intersection** of two of the given rectangles. You need to find the **largest** area of a **square** that can fit **inside** this region if you select the region optimally.
+
+Return _the **largest** possible area of a square, or_ `0` _if there **do not** exist any intersecting regions between the rectangles_.
+
+**Example 1:**
+
+
+
+**Input:** bottomLeft = [[1,1],[2,2],[3,1]], topRight = [[3,3],[4,4],[6,6]]
+
+**Output:** 1
+
+**Explanation:** A square with side length 1 can fit inside either the intersecting region of rectangle 0 and rectangle 1, or the intersecting region of rectangle 1 and rectangle 2. Hence the largest area is side \* side which is 1 \* 1 == 1.
+
+It can be shown that a square with a greater side length can not fit inside any intersecting region.
+
+**Example 2:**
+
+
+
+**Input:** bottomLeft = [[1,1],[2,2],[1,2]], topRight = [[3,3],[4,4],[3,4]]
+
+**Output:** 1
+
+**Explanation:** A square with side length 1 can fit inside either the intersecting region of rectangle 0 and rectangle 1, the intersecting region of rectangle 1 and rectangle 2, or the intersection region of all 3 rectangles. Hence the largest area is side \* side which is 1 \* 1 == 1.
+
+It can be shown that a square with a greater side length can not fit inside any intersecting region. Note that the region can be formed by the intersection of more than 2 rectangles.
+
+**Example 3:**
+
+
+
+**Input:** bottomLeft = [[1,1],[3,3],[3,1]], topRight = [[2,2],[4,4],[4,2]]
+
+**Output:** 0
+
+**Explanation:** No pair of rectangles intersect, hence, we return 0.
+
+**Constraints:**
+
+* `n == bottomLeft.length == topRight.length`
+* 2 <= n <= 103
+* `bottomLeft[i].length == topRight[i].length == 2`
+* 1 <= bottomLeft[i][0], bottomLeft[i][1] <= 107
+* 1 <= topRight[i][0], topRight[i][1] <= 107
+* `bottomLeft[i][0] < topRight[i][0]`
+* `bottomLeft[i][1] < topRight[i][1]`
diff --git a/src/main/kotlin/g3001_3100/s3048_earliest_second_to_mark_indices_i/Solution.kt b/src/main/kotlin/g3001_3100/s3048_earliest_second_to_mark_indices_i/Solution.kt
new file mode 100644
index 00000000..a20cb8bf
--- /dev/null
+++ b/src/main/kotlin/g3001_3100/s3048_earliest_second_to_mark_indices_i/Solution.kt
@@ -0,0 +1,50 @@
+package g3001_3100.s3048_earliest_second_to_mark_indices_i
+
+// #Medium #Array #Binary_Search #2024_03_06_Time_223_ms_(75.00%)_Space_44.7_MB_(33.33%)
+
+class Solution {
+ fun earliestSecondToMarkIndices(nums: IntArray, changeIndices: IntArray): Int {
+ val n = nums.size
+ if (nums.isEmpty() || changeIndices.isEmpty()) {
+ return 0
+ }
+ val last = IntArray(n)
+ last.fill(-1)
+ for (i in changeIndices.indices) {
+ changeIndices[i] -= 1
+ }
+ var low = 0
+ var high = changeIndices.size - 1
+ while (low < high) {
+ val mid = low + (high - low) / 2
+ if (isPossible(mid, nums, changeIndices, last)) {
+ high = mid
+ } else {
+ low = mid + 1
+ }
+ }
+ return if (isPossible(low, nums, changeIndices, last)) low + 1 else -1
+ }
+
+ private fun isPossible(s: Int, nums: IntArray, changeIndices: IntArray, last: IntArray): Boolean {
+ val n = nums.size
+ last.fill(-1)
+ for (i in 0..s) {
+ last[changeIndices[i]] = i
+ }
+ var marked = 0
+ var operations = 0
+ for (i in 0..s) {
+ if (i == last[changeIndices[i]]) {
+ if (nums[changeIndices[i]] > operations) {
+ return false
+ }
+ operations -= nums[changeIndices[i]]
+ marked++
+ } else {
+ operations++
+ }
+ }
+ return marked == n
+ }
+}
diff --git a/src/main/kotlin/g3001_3100/s3048_earliest_second_to_mark_indices_i/readme.md b/src/main/kotlin/g3001_3100/s3048_earliest_second_to_mark_indices_i/readme.md
new file mode 100644
index 00000000..8727300b
--- /dev/null
+++ b/src/main/kotlin/g3001_3100/s3048_earliest_second_to_mark_indices_i/readme.md
@@ -0,0 +1,86 @@
+3048\. Earliest Second to Mark Indices I
+
+Medium
+
+You are given two **1-indexed** integer arrays, `nums` and, `changeIndices`, having lengths `n` and `m`, respectively.
+
+Initially, all indices in `nums` are unmarked. Your task is to mark **all** indices in `nums`.
+
+In each second, `s`, in order from `1` to `m` (**inclusive**), you can perform **one** of the following operations:
+
+* Choose an index `i` in the range `[1, n]` and **decrement** `nums[i]` by `1`.
+* If `nums[changeIndices[s]]` is **equal** to `0`, **mark** the index `changeIndices[s]`.
+* Do nothing.
+
+Return _an integer denoting the **earliest second** in the range_ `[1, m]` _when **all** indices in_ `nums` _can be marked by choosing operations optimally, or_ `-1` _if it is impossible._
+
+**Example 1:**
+
+**Input:** nums = [2,2,0], changeIndices = [2,2,2,2,3,2,2,1]
+
+**Output:** 8
+
+**Explanation:** In this example, we have 8 seconds. The following operations can be performed to mark all indices:
+
+Second 1: Choose index 1 and decrement nums[1] by one. nums becomes [1,2,0].
+
+Second 2: Choose index 1 and decrement nums[1] by one. nums becomes [0,2,0].
+
+Second 3: Choose index 2 and decrement nums[2] by one. nums becomes [0,1,0].
+
+Second 4: Choose index 2 and decrement nums[2] by one. nums becomes [0,0,0].
+
+Second 5: Mark the index changeIndices[5], which is marking index 3, since nums[3] is equal to 0.
+
+Second 6: Mark the index changeIndices[6], which is marking index 2, since nums[2] is equal to 0.
+
+Second 7: Do nothing.
+
+Second 8: Mark the index changeIndices[8], which is marking index 1, since nums[1] is equal to 0.
+
+Now all indices have been marked.
+
+It can be shown that it is not possible to mark all indices earlier than the 8th second.
+
+Hence, the answer is 8.
+
+**Example 2:**
+
+**Input:** nums = [1,3], changeIndices = [1,1,1,2,1,1,1]
+
+**Output:** 6
+
+**Explanation:** In this example, we have 7 seconds. The following operations can be performed to mark all indices:
+
+Second 1: Choose index 2 and decrement nums[2] by one. nums becomes [1,2].
+
+Second 2: Choose index 2 and decrement nums[2] by one. nums becomes [1,1].
+
+Second 3: Choose index 2 and decrement nums[2] by one. nums becomes [1,0].
+
+Second 4: Mark the index changeIndices[4], which is marking index 2, since nums[2] is equal to 0.
+
+Second 5: Choose index 1 and decrement nums[1] by one. nums becomes [0,0].
+
+Second 6: Mark the index changeIndices[6], which is marking index 1, since nums[1] is equal to 0.
+
+Now all indices have been marked.
+
+It can be shown that it is not possible to mark all indices earlier than the 6th second.
+
+Hence, the answer is 6.
+
+**Example 3:**
+
+**Input:** nums = [0,1], changeIndices = [2,2,2]
+
+**Output:** -1
+
+**Explanation:** In this example, it is impossible to mark all indices because index 1 isn't in changeIndices. Hence, the answer is -1.
+
+**Constraints:**
+
+* `1 <= n == nums.length <= 2000`
+* 0 <= nums[i] <= 109
+* `1 <= m == changeIndices.length <= 2000`
+* `1 <= changeIndices[i] <= n`
\ No newline at end of file
diff --git a/src/main/kotlin/g3001_3100/s3049_earliest_second_to_mark_indices_ii/Solution.kt b/src/main/kotlin/g3001_3100/s3049_earliest_second_to_mark_indices_ii/Solution.kt
new file mode 100644
index 00000000..550491cf
--- /dev/null
+++ b/src/main/kotlin/g3001_3100/s3049_earliest_second_to_mark_indices_ii/Solution.kt
@@ -0,0 +1,69 @@
+package g3001_3100.s3049_earliest_second_to_mark_indices_ii
+
+// #Hard #Array #Greedy #Binary_Search #Heap_Priority_Queue
+// #2024_03_06_Time_220_ms_(100.00%)_Space_44.1_MB_(66.67%)
+
+import java.util.PriorityQueue
+import java.util.Queue
+import kotlin.math.min
+
+class Solution {
+ private lateinit var nums: IntArray
+ private lateinit var changeIndices: IntArray
+ private lateinit var first: BooleanArray
+ private var sum: Long = 0
+
+ fun earliestSecondToMarkIndices(nums: IntArray, changeIndices: IntArray): Int {
+ val m = changeIndices.size
+ val n = nums.size
+ if (m < n) {
+ return -1
+ }
+ this.nums = nums
+ this.changeIndices = changeIndices
+ val set: MutableSet = HashSet()
+ first = BooleanArray(m)
+ for (i in 0 until m) {
+ if (nums[changeIndices[i] - 1] > 1 && set.add(changeIndices[i])) {
+ first[i] = true
+ }
+ }
+ for (num in nums) {
+ sum += num.toLong()
+ }
+ sum += n.toLong()
+ var l = n
+ var r = (min(sum.toInt(), m)) + 1
+ while (l < r) {
+ val mid = (l + r) / 2
+ if (check(mid)) {
+ r = mid
+ } else {
+ l = mid + 1
+ }
+ }
+ return if (l > min(sum.toInt(), m)) -1 else l
+ }
+
+ private fun check(idx: Int): Boolean {
+ val pq: Queue = PriorityQueue()
+ var need = sum
+ var count = 0
+ var i = idx - 1
+ while (i >= 0 && need > idx) {
+ if (!first[i]) {
+ count++
+ i--
+ continue
+ }
+ pq.add(nums[changeIndices[i] - 1])
+ need -= (nums[changeIndices[i] - 1] - 1).toLong()
+ if (pq.size > count) {
+ need += (pq.poll() - 1).toLong()
+ count++
+ }
+ i--
+ }
+ return need <= idx
+ }
+}
diff --git a/src/main/kotlin/g3001_3100/s3049_earliest_second_to_mark_indices_ii/readme.md b/src/main/kotlin/g3001_3100/s3049_earliest_second_to_mark_indices_ii/readme.md
new file mode 100644
index 00000000..e70bf248
--- /dev/null
+++ b/src/main/kotlin/g3001_3100/s3049_earliest_second_to_mark_indices_ii/readme.md
@@ -0,0 +1,85 @@
+3049\. Earliest Second to Mark Indices II
+
+Hard
+
+You are given two **1-indexed** integer arrays, `nums` and, `changeIndices`, having lengths `n` and `m`, respectively.
+
+Initially, all indices in `nums` are unmarked. Your task is to mark **all** indices in `nums`.
+
+In each second, `s`, in order from `1` to `m` (**inclusive**), you can perform **one** of the following operations:
+
+* Choose an index `i` in the range `[1, n]` and **decrement** `nums[i]` by `1`.
+* Set `nums[changeIndices[s]]` to any **non-negative** value.
+* Choose an index `i` in the range `[1, n]`, where `nums[i]` is **equal** to `0`, and **mark** index `i`.
+* Do nothing.
+
+Return _an integer denoting the **earliest second** in the range_ `[1, m]` _when **all** indices in_ `nums` _can be marked by choosing operations optimally, or_ `-1` _if it is impossible._
+
+**Example 1:**
+
+**Input:** nums = [3,2,3], changeIndices = [1,3,2,2,2,2,3]
+
+**Output:** 6
+
+**Explanation:** In this example, we have 7 seconds. The following operations can be performed to mark all indices:
+
+Second 1: Set nums[changeIndices[1]] to 0. nums becomes [0,2,3].
+
+Second 2: Set nums[changeIndices[2]] to 0. nums becomes [0,2,0].
+
+Second 3: Set nums[changeIndices[3]] to 0. nums becomes [0,0,0].
+
+Second 4: Mark index 1, since nums[1] is equal to 0.
+
+Second 5: Mark index 2, since nums[2] is equal to 0.
+
+Second 6: Mark index 3, since nums[3] is equal to 0.
+
+Now all indices have been marked.
+
+It can be shown that it is not possible to mark all indices earlier than the 6th second.
+
+Hence, the answer is 6.
+
+**Example 2:**
+
+**Input:** nums = [0,0,1,2], changeIndices = [1,2,1,2,1,2,1,2]
+
+**Output:** 7
+
+**Explanation:** In this example, we have 8 seconds. The following operations can be performed to mark all indices:
+
+Second 1: Mark index 1, since nums[1] is equal to 0.
+
+Second 2: Mark index 2, since nums[2] is equal to 0.
+
+Second 3: Decrement index 4 by one. nums becomes [0,0,1,1].
+
+Second 4: Decrement index 4 by one. nums becomes [0,0,1,0].
+
+Second 5: Decrement index 3 by one. nums becomes [0,0,0,0].
+
+Second 6: Mark index 3, since nums[3] is equal to 0.
+
+Second 7: Mark index 4, since nums[4] is equal to 0.
+
+Now all indices have been marked.
+
+It can be shown that it is not possible to mark all indices earlier than the 7th second.
+
+Hence, the answer is 7.
+
+**Example 3:**
+
+**Input:** nums = [1,2,3], changeIndices = [1,2,3]
+
+**Output:** -1
+
+**Explanation:** In this example, it can be shown that it is impossible to mark all indices, as we don't have enough seconds. Hence, the answer is -1.
+
+**Constraints:**
+
+* `1 <= n == nums.length <= 5000`
+* 0 <= nums[i] <= 109
+* `1 <= m == changeIndices.length <= 5000`
+* `1 <= changeIndices[i] <= n`
\ No newline at end of file
diff --git a/src/test/kotlin/g3001_3100/s3038_maximum_number_of_operations_with_the_same_score_i/SolutionTest.kt b/src/test/kotlin/g3001_3100/s3038_maximum_number_of_operations_with_the_same_score_i/SolutionTest.kt
new file mode 100644
index 00000000..b28c8fc4
--- /dev/null
+++ b/src/test/kotlin/g3001_3100/s3038_maximum_number_of_operations_with_the_same_score_i/SolutionTest.kt
@@ -0,0 +1,17 @@
+package g3001_3100.s3038_maximum_number_of_operations_with_the_same_score_i
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun maxOperations() {
+ assertThat(Solution().maxOperations(intArrayOf(3, 2, 1, 4, 5)), equalTo(2))
+ }
+
+ @Test
+ fun maxOperations2() {
+ assertThat(Solution().maxOperations(intArrayOf(3, 2, 6, 1, 4)), equalTo(1))
+ }
+}
diff --git a/src/test/kotlin/g3001_3100/s3039_apply_operations_to_make_string_empty/SolutionTest.kt b/src/test/kotlin/g3001_3100/s3039_apply_operations_to_make_string_empty/SolutionTest.kt
new file mode 100644
index 00000000..bccc4223
--- /dev/null
+++ b/src/test/kotlin/g3001_3100/s3039_apply_operations_to_make_string_empty/SolutionTest.kt
@@ -0,0 +1,17 @@
+package g3001_3100.s3039_apply_operations_to_make_string_empty
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun lastNonEmptyString() {
+ assertThat(Solution().lastNonEmptyString("aabcbbca"), equalTo("ba"))
+ }
+
+ @Test
+ fun lastNonEmptyString2() {
+ assertThat(Solution().lastNonEmptyString("abcd"), equalTo("abcd"))
+ }
+}
diff --git a/src/test/kotlin/g3001_3100/s3040_maximum_number_of_operations_with_the_same_score_ii/SolutionTest.kt b/src/test/kotlin/g3001_3100/s3040_maximum_number_of_operations_with_the_same_score_ii/SolutionTest.kt
new file mode 100644
index 00000000..8daa3e79
--- /dev/null
+++ b/src/test/kotlin/g3001_3100/s3040_maximum_number_of_operations_with_the_same_score_ii/SolutionTest.kt
@@ -0,0 +1,17 @@
+package g3001_3100.s3040_maximum_number_of_operations_with_the_same_score_ii
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun maxOperations() {
+ assertThat(Solution().maxOperations(intArrayOf(3, 2, 1, 2, 3, 4)), equalTo(3))
+ }
+
+ @Test
+ fun maxOperations2() {
+ assertThat(Solution().maxOperations(intArrayOf(3, 2, 6, 1, 4)), equalTo(2))
+ }
+}
diff --git a/src/test/kotlin/g3001_3100/s3047_find_the_largest_area_of_square_inside_two_rectangles/SolutionTest.kt b/src/test/kotlin/g3001_3100/s3047_find_the_largest_area_of_square_inside_two_rectangles/SolutionTest.kt
new file mode 100644
index 00000000..8532707f
--- /dev/null
+++ b/src/test/kotlin/g3001_3100/s3047_find_the_largest_area_of_square_inside_two_rectangles/SolutionTest.kt
@@ -0,0 +1,56 @@
+package g3001_3100.s3047_find_the_largest_area_of_square_inside_two_rectangles
+
+import com_github_leetcode.CommonUtils.convertLeetCodeIrregularLengths2DArrayInputIntoJavaArray
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun largestSquareArea() {
+ assertThat(
+ Solution()
+ .largestSquareArea(
+ convertLeetCodeIrregularLengths2DArrayInputIntoJavaArray(
+ "[1,1],[2,2],[3,1]"
+ ),
+ convertLeetCodeIrregularLengths2DArrayInputIntoJavaArray(
+ "[3,3],[4,4],[6,6]"
+ )
+ ),
+ equalTo(1L)
+ )
+ }
+
+ @Test
+ fun largestSquareArea2() {
+ assertThat(
+ Solution()
+ .largestSquareArea(
+ convertLeetCodeIrregularLengths2DArrayInputIntoJavaArray(
+ "[1,1],[2,2],[1,2]"
+ ),
+ convertLeetCodeIrregularLengths2DArrayInputIntoJavaArray(
+ "[3,3],[4,4],[3,4]"
+ )
+ ),
+ equalTo(1L)
+ )
+ }
+
+ @Test
+ fun largestSquareArea3() {
+ assertThat(
+ Solution()
+ .largestSquareArea(
+ convertLeetCodeIrregularLengths2DArrayInputIntoJavaArray(
+ "[1,1],[3,3],[3,1]"
+ ),
+ convertLeetCodeIrregularLengths2DArrayInputIntoJavaArray(
+ "[2,2],[4,4],[4,2]"
+ )
+ ),
+ equalTo(0L)
+ )
+ }
+}
diff --git a/src/test/kotlin/g3001_3100/s3048_earliest_second_to_mark_indices_i/SolutionTest.kt b/src/test/kotlin/g3001_3100/s3048_earliest_second_to_mark_indices_i/SolutionTest.kt
new file mode 100644
index 00000000..80689a50
--- /dev/null
+++ b/src/test/kotlin/g3001_3100/s3048_earliest_second_to_mark_indices_i/SolutionTest.kt
@@ -0,0 +1,37 @@
+package g3001_3100.s3048_earliest_second_to_mark_indices_i
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun earliestSecondToMarkIndices() {
+ assertThat(
+ Solution()
+ .earliestSecondToMarkIndices(
+ intArrayOf(2, 2, 0), intArrayOf(2, 2, 2, 2, 3, 2, 2, 1)
+ ),
+ equalTo(8)
+ )
+ }
+
+ @Test
+ fun earliestSecondToMarkIndices2() {
+ assertThat(
+ Solution()
+ .earliestSecondToMarkIndices(
+ intArrayOf(1, 3), intArrayOf(1, 1, 1, 2, 1, 1, 1)
+ ),
+ equalTo(6)
+ )
+ }
+
+ @Test
+ fun earliestSecondToMarkIndices3() {
+ assertThat(
+ Solution().earliestSecondToMarkIndices(intArrayOf(0, 1), intArrayOf(2, 2, 2)),
+ equalTo(-1)
+ )
+ }
+}
diff --git a/src/test/kotlin/g3001_3100/s3049_earliest_second_to_mark_indices_ii/SolutionTest.kt b/src/test/kotlin/g3001_3100/s3049_earliest_second_to_mark_indices_ii/SolutionTest.kt
new file mode 100644
index 00000000..a56c80e7
--- /dev/null
+++ b/src/test/kotlin/g3001_3100/s3049_earliest_second_to_mark_indices_ii/SolutionTest.kt
@@ -0,0 +1,38 @@
+package g3001_3100.s3049_earliest_second_to_mark_indices_ii
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Test
+
+internal class SolutionTest {
+ @Test
+ fun earliestSecondToMarkIndices() {
+ assertThat(
+ Solution()
+ .earliestSecondToMarkIndices(
+ intArrayOf(3, 2, 3), intArrayOf(1, 3, 2, 2, 2, 2, 3)
+ ),
+ equalTo(6)
+ )
+ }
+
+ @Test
+ fun earliestSecondToMarkIndices2() {
+ assertThat(
+ Solution()
+ .earliestSecondToMarkIndices(
+ intArrayOf(0, 0, 1, 2), intArrayOf(1, 2, 1, 2, 1, 2, 1, 2)
+ ),
+ equalTo(7)
+ )
+ }
+
+ @Test
+ fun earliestSecondToMarkIndices3() {
+ assertThat(
+ Solution()
+ .earliestSecondToMarkIndices(intArrayOf(1, 2, 3), intArrayOf(1, 2, 3)),
+ equalTo(-1)
+ )
+ }
+}