From 75772cc9c4c607d07fba3e6194d2509fed6f270a Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 7 Sep 2025 20:02:53 +0300 Subject: [PATCH 1/4] Added tasks 3673-3677 --- .../s3673_find_zombie_sessions/readme.md | 105 ++++++++++++++++++ .../s3673_find_zombie_sessions/script.sql | 23 ++++ .../Solution.kt | 14 +++ .../readme.md | 36 ++++++ .../Solution.kt | 22 ++++ .../readme.md | 41 +++++++ .../s3676_count_bowl_subarrays/Solution.kt | 26 +++++ .../s3676_count_bowl_subarrays/readme.md | 51 +++++++++ .../Solution.kt | 38 +++++++ .../readme.md | 44 ++++++++ .../s3673_find_zombie_sessions/MysqlTest.kt | 91 +++++++++++++++ .../SolutionTest.kt | 17 +++ .../SolutionTest.kt | 17 +++ .../SolutionTest.kt | 31 ++++++ .../SolutionTest.kt | 58 ++++++++++ 15 files changed, 614 insertions(+) create mode 100644 src/main/kotlin/g3601_3700/s3673_find_zombie_sessions/readme.md create mode 100644 src/main/kotlin/g3601_3700/s3673_find_zombie_sessions/script.sql create mode 100644 src/main/kotlin/g3601_3700/s3674_minimum_operations_to_equalize_array/Solution.kt create mode 100644 src/main/kotlin/g3601_3700/s3674_minimum_operations_to_equalize_array/readme.md create mode 100644 src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/Solution.kt create mode 100644 src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/readme.md create mode 100644 src/main/kotlin/g3601_3700/s3676_count_bowl_subarrays/Solution.kt create mode 100644 src/main/kotlin/g3601_3700/s3676_count_bowl_subarrays/readme.md create mode 100644 src/main/kotlin/g3601_3700/s3677_count_binary_palindromic_numbers/Solution.kt create mode 100644 src/main/kotlin/g3601_3700/s3677_count_binary_palindromic_numbers/readme.md create mode 100644 src/test/kotlin/g3601_3700/s3673_find_zombie_sessions/MysqlTest.kt create mode 100644 src/test/kotlin/g3601_3700/s3674_minimum_operations_to_equalize_array/SolutionTest.kt create mode 100644 src/test/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/SolutionTest.kt create mode 100644 src/test/kotlin/g3601_3700/s3676_count_bowl_subarrays/SolutionTest.kt create mode 100644 src/test/kotlin/g3601_3700/s3677_count_binary_palindromic_numbers/SolutionTest.kt diff --git a/src/main/kotlin/g3601_3700/s3673_find_zombie_sessions/readme.md b/src/main/kotlin/g3601_3700/s3673_find_zombie_sessions/readme.md new file mode 100644 index 00000000..fabadfdb --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3673_find_zombie_sessions/readme.md @@ -0,0 +1,105 @@ +3673\. Find Zombie Sessions + +Hard + +Table: `app_events` + + +------------------+----------+ + | Column Name | Type | + +------------------+----------+ + | event_id | int | + | user_id | int | + | event_timestamp | datetime | + | event_type | varchar | + | session_id | varchar | + | event_value | int | + +------------------+----------+ + event_id is the unique identifier for this table. + event_type can be app_open, click, scroll, purchase, or app_close. + session_id groups events within the same user session. + event_value represents: for purchase - amount in dollars, for scroll - pixels scrolled, for others - NULL. + +Write a solution to identify **zombie sessions, **sessions where users appear active but show abnormal behavior patterns. A session is considered a **zombie session** if it meets ALL the following criteria: + +* The session duration is **more than** `30` minutes. +* Has **at least** `5` scroll events. +* The **click-to-scroll ratio** is less than `0.20` . +* **No purchases** were made during the session. + +Return _the result table ordered by_ `scroll_count` _in **descending** order, then by_ `session_id` _in **ascending** order_. + +The result format is in the following example. + +**Example:** + +**Input:** + +app\_events table: + + +----------+---------+---------------------+------------+------------+-------------+ + | event_id | user_id | event_timestamp | event_type | session_id | event_value | + +----------+---------+---------------------+------------+------------+-------------+ + | 1 | 201 | 2024-03-01 10:00:00 | app_open | S001 | NULL | + | 2 | 201 | 2024-03-01 10:05:00 | scroll | S001 | 500 | + | 3 | 201 | 2024-03-01 10:10:00 | scroll | S001 | 750 | + | 4 | 201 | 2024-03-01 10:15:00 | scroll | S001 | 600 | + | 5 | 201 | 2024-03-01 10:20:00 | scroll | S001 | 800 | + | 6 | 201 | 2024-03-01 10:25:00 | scroll | S001 | 550 | + | 7 | 201 | 2024-03-01 10:30:00 | scroll | S001 | 900 | + | 8 | 201 | 2024-03-01 10:35:00 | app_close | S001 | NULL | + | 9 | 202 | 2024-03-01 11:00:00 | app_open | S002 | NULL | + | 10 | 202 | 2024-03-01 11:02:00 | click | S002 | NULL | + | 11 | 202 | 2024-03-01 11:05:00 | scroll | S002 | 400 | + | 12 | 202 | 2024-03-01 11:08:00 | click | S002 | NULL | + | 13 | 202 | 2024-03-01 11:10:00 | scroll | S002 | 350 | + | 14 | 202 | 2024-03-01 11:15:00 | purchase | S002 | 50 | + | 15 | 202 | 2024-03-01 11:20:00 | app_close | S002 | NULL | + | 16 | 203 | 2024-03-01 12:00:00 | app_open | S003 | NULL | + | 17 | 203 | 2024-03-01 12:10:00 | scroll | S003 | 1000 | + | 18 | 203 | 2024-03-01 12:20:00 | scroll | S003 | 1200 | + | 19 | 203 | 2024-03-01 12:25:00 | click | S003 | NULL | + | 20 | 203 | 2024-03-01 12:30:00 | scroll | S003 | 800 | + | 21 | 203 | 2024-03-01 12:40:00 | scroll | S003 | 900 | + | 22 | 203 | 2024-03-01 12:50:00 | scroll | S003 | 1100 | + | 23 | 203 | 2024-03-01 13:00:00 | app_close | S003 | NULL | + | 24 | 204 | 2024-03-01 14:00:00 | app_open | S004 | NULL | + | 25 | 204 | 2024-03-01 14:05:00 | scroll | S004 | 600 | + | 26 | 204 | 2024-03-01 14:08:00 | scroll | S004 | 700 | + | 27 | 204 | 2024-03-01 14:10:00 | click | S004 | NULL | + | 28 | 204 | 2024-03-01 14:12:00 | app_close | S004 | NULL | + +----------+---------+---------------------+------------+------------+-------------+ + +**Output:** + + +------------+---------+--------------------------+--------------+ + | session_id | user_id | session_duration_minutes | scroll_count | + +------------+---------+--------------------------+--------------+ + | S001 | 201 | 35 | 6 | + +------------+---------+--------------------------+--------------+ + +**Explanation:** + +* **Session S001 (User 201)**: + * Duration: 10:00:00 to 10:35:00 = 35 minutes (more than 30) + * Scroll events: 6 (at least 5) + * Click events: 0 + * Click-to-scroll ratio: 0/6 = 0.00 (less than 0.20) + * Purchases: 0 (no purchases) + * S001 is a zombie session (meets all criteria) +* **Session S002 (User 202)**: + * Duration: 11:00:00 to 11:20:00 = 20 minutes (less than 30) + * Has a purchase event + * S002 is not a zombie session +* **Session S003 (User 203)**: + * Duration: 12:00:00 to 13:00:00 = 60 minutes (more than 30) + * Scroll events: 5 (at least 5) + * Click events: 1 + * Click-to-scroll ratio: 1/5 = 0.20 (not less than 0.20) + * Purchases: 0 (no purchases) + * S003 is not a zombie session (click-to-scroll ratio equals 0.20, needs to be less) +* **Session S004 (User 204)**: + * Duration: 14:00:00 to 14:12:00 = 12 minutes (less than 30) + * Scroll events: 2 (less than 5) + * S004 is not a zombie session + +The result table is ordered by scroll\_count in descending order, then by session\_id in ascending order. \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3673_find_zombie_sessions/script.sql b/src/main/kotlin/g3601_3700/s3673_find_zombie_sessions/script.sql new file mode 100644 index 00000000..87f37171 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3673_find_zombie_sessions/script.sql @@ -0,0 +1,23 @@ +# Write your MySQL query statement below +# #Hard #Database #2025_09_07_Time_278_ms_(100.00%)_Space_0.0_MB_(100.00%) +SELECT + session_id, + user_id, + TIMESTAMPDIFF(MINUTE, MIN(event_timestamp), MAX(event_timestamp)) AS session_duration_minutes, + SUM(CASE WHEN event_type = 'scroll' THEN 1 ELSE 0 END) AS scroll_count -- NOSONAR +FROM + app_events +GROUP BY + session_id, + user_id +HAVING + TIMESTAMPDIFF(MINUTE, MIN(event_timestamp), MAX(event_timestamp)) > 30 + AND SUM(CASE WHEN event_type = 'scroll' THEN 1 ELSE 0 END) > 4 -- NOSONAR + AND ( + CAST(SUM(CASE WHEN event_type = 'click' THEN 1 ELSE 0 END) AS DOUBLE) / + NULLIF(SUM(CASE WHEN event_type = 'scroll' THEN 1 ELSE 0 END), 0) -- NOSONAR + ) < 0.2 + AND SUM(CASE WHEN event_type = 'purchase' THEN 1 ELSE 0 END) = 0 +ORDER BY + scroll_count DESC, + session_id ASC; diff --git a/src/main/kotlin/g3601_3700/s3674_minimum_operations_to_equalize_array/Solution.kt b/src/main/kotlin/g3601_3700/s3674_minimum_operations_to_equalize_array/Solution.kt new file mode 100644 index 00000000..8e39e311 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3674_minimum_operations_to_equalize_array/Solution.kt @@ -0,0 +1,14 @@ +package g3601_3700.s3674_minimum_operations_to_equalize_array + +// #Easy #Weekly_Contest_466 #2025_09_07_Time_1_ms_(100.00%)_Space_43.60_MB_(100.00%) + +class Solution { + fun minOperations(nums: IntArray): Int { + for (num in nums) { + if (num != nums[0]) { + return 1 + } + } + return 0 + } +} diff --git a/src/main/kotlin/g3601_3700/s3674_minimum_operations_to_equalize_array/readme.md b/src/main/kotlin/g3601_3700/s3674_minimum_operations_to_equalize_array/readme.md new file mode 100644 index 00000000..ccdd1973 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3674_minimum_operations_to_equalize_array/readme.md @@ -0,0 +1,36 @@ +3674\. Minimum Operations to Equalize Array + +Easy + +You are given an integer array `nums` of length `n`. + +In one operation, choose any subarray `nums[l...r]` (`0 <= l <= r < n`) and **replace** each element in that subarray with the **bitwise AND** of all elements. + +Return the **minimum** number of operations required to make all elements of `nums` equal. + +A **subarray** is a contiguous **non-empty** sequence of elements within an array. + +**Example 1:** + +**Input:** nums = [1,2] + +**Output:** 1 + +**Explanation:** + +Choose `nums[0...1]`: `(1 AND 2) = 0`, so the array becomes `[0, 0]` and all elements are equal in 1 operation. + +**Example 2:** + +**Input:** nums = [5,5,5] + +**Output:** 0 + +**Explanation:** + +`nums` is `[5, 5, 5]` which already has all elements equal, so 0 operations are required. + +**Constraints:** + +* `1 <= n == nums.length <= 100` +* 1 <= nums[i] <= 105 \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/Solution.kt b/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/Solution.kt new file mode 100644 index 00000000..4f1d82f1 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/Solution.kt @@ -0,0 +1,22 @@ +package g3601_3700.s3675_minimum_operations_to_transform_string + +// #Medium #Weekly_Contest_466 #2025_09_07_Time_84_ms_(100.00%)_Space_56.99_MB_(100.00%) + +class Solution { + fun minOperations(s: String): Int { + val set: MutableSet = HashSet() + for (ch in s.toCharArray()) { + set.add(ch) + } + if (set.size == 1 && set.contains('a')) { + return 0 + } + var minCh = 'z' + for (ch in s.toCharArray()) { + if (ch != 'a' && ch < minCh) { + minCh = ch + } + } + return ('z'.code - minCh.code) + 1 + } +} diff --git a/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/readme.md b/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/readme.md new file mode 100644 index 00000000..7ce2dabe --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/readme.md @@ -0,0 +1,41 @@ +3675\. Minimum Operations to Transform String + +Medium + +You are given a string `s` consisting only of lowercase English letters. + +You can perform the following operation any number of times (including zero): + +* Choose any character `c` in the string and replace **every** occurrence of `c` with the **next** lowercase letter in the English alphabet. + + +Return the **minimum** number of operations required to transform `s` into a string consisting of **only** `'a'` characters. + +**Note:** Consider the alphabet as circular, thus `'a'` comes after `'z'`. + +**Example 1:** + +**Input:** s = "yz" + +**Output:** 2 + +**Explanation:** + +* Change `'y'` to `'z'` to get `"zz"`. +* Change `'z'` to `'a'` to get `"aa"`. +* Thus, the answer is 2. + +**Example 2:** + +**Input:** s = "a" + +**Output:** 0 + +**Explanation:** + +* The string `"a"` only consists of `'a'` characters. Thus, the answer is 0. + +**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/g3601_3700/s3676_count_bowl_subarrays/Solution.kt b/src/main/kotlin/g3601_3700/s3676_count_bowl_subarrays/Solution.kt new file mode 100644 index 00000000..4df2010e --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3676_count_bowl_subarrays/Solution.kt @@ -0,0 +1,26 @@ +package g3601_3700.s3676_count_bowl_subarrays + +// #Medium #Weekly_Contest_466 #2025_09_07_Time_26_ms_(100.00%)_Space_84.36_MB_(100.00%) + +import kotlin.math.min + +class Solution { + fun bowlSubarrays(nums: IntArray): Long { + val l = nums.size + var ans = 0 + val stack: java.util.Deque = java.util.ArrayDeque() + for (i in 0.. nums[mid]) { + ++ans + } + } + } + stack.push(i) + } + return ans.toLong() + } +} diff --git a/src/main/kotlin/g3601_3700/s3676_count_bowl_subarrays/readme.md b/src/main/kotlin/g3601_3700/s3676_count_bowl_subarrays/readme.md new file mode 100644 index 00000000..99488aa3 --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3676_count_bowl_subarrays/readme.md @@ -0,0 +1,51 @@ +3676\. Count Bowl Subarrays + +Medium + +You are given an integer array `nums` with **distinct** elements. + +A subarray `nums[l...r]` of `nums` is called a **bowl** if: + +* The subarray has length at least 3. That is, `r - l + 1 >= 3`. +* The **minimum** of its two ends is **strictly greater** than the **maximum** of all elements in between. That is, `min(nums[l], nums[r]) > max(nums[l + 1], ..., nums[r - 1])`. + +Return the number of **bowl** subarrays in `nums`. + +**Example 1:** + +**Input:** nums = [2,5,3,1,4] + +**Output:** 2 + +**Explanation:** + +The bowl subarrays are `[3, 1, 4]` and `[5, 3, 1, 4]`. + +* `[3, 1, 4]` is a bowl because `min(3, 4) = 3 > max(1) = 1`. +* `[5, 3, 1, 4]` is a bowl because `min(5, 4) = 4 > max(3, 1) = 3`. + +**Example 2:** + +**Input:** nums = [5,1,2,3,4] + +**Output:** 3 + +**Explanation:** + +The bowl subarrays are `[5, 1, 2]`, `[5, 1, 2, 3]` and `[5, 1, 2, 3, 4]`. + +**Example 3:** + +**Input:** nums = [1000000000,999999999,999999998] + +**Output:** 0 + +**Explanation:** + +No subarray is a bowl. + +**Constraints:** + +* 3 <= nums.length <= 105 +* 1 <= nums[i] <= 109 +* `nums` consists of distinct elements. \ No newline at end of file diff --git a/src/main/kotlin/g3601_3700/s3677_count_binary_palindromic_numbers/Solution.kt b/src/main/kotlin/g3601_3700/s3677_count_binary_palindromic_numbers/Solution.kt new file mode 100644 index 00000000..394d2bee --- /dev/null +++ b/src/main/kotlin/g3601_3700/s3677_count_binary_palindromic_numbers/Solution.kt @@ -0,0 +1,38 @@ +package g3601_3700.s3677_count_binary_palindromic_numbers + +// #Hard #Weekly_Contest_466 #2025_09_07_Time_1_ms_(100.00%)_Space_41.19_MB_(100.00%) + +class Solution { + private fun makePalin(left: Long, odd: Boolean): Long { + var left = left + var ans = left + if (odd) { + left = left shr 1 + } + while (left > 0) { + ans = (ans shl 1) or (left and 1L) + left = left shr 1 + } + return ans + } + + fun countBinaryPalindromes(n: Long): Int { + if (n == 0L) { + return 1 + } + val len = 64 - java.lang.Long.numberOfLeadingZeros(n) + var count: Long = 1 + for (i in 1..0 <= n <= 1015 \ No newline at end of file diff --git a/src/test/kotlin/g3601_3700/s3673_find_zombie_sessions/MysqlTest.kt b/src/test/kotlin/g3601_3700/s3673_find_zombie_sessions/MysqlTest.kt new file mode 100644 index 00000000..a357494f --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3673_find_zombie_sessions/MysqlTest.kt @@ -0,0 +1,91 @@ +package g3601_3700.s3673_find_zombie_sessions + +import org.hamcrest.CoreMatchers +import org.hamcrest.MatcherAssert +import org.junit.jupiter.api.Test +import org.zapodot.junit.db.annotations.EmbeddedDatabase +import org.zapodot.junit.db.annotations.EmbeddedDatabaseTest +import org.zapodot.junit.db.common.CompatibilityMode +import java.io.BufferedReader +import java.io.FileNotFoundException +import java.io.FileReader +import java.sql.SQLException +import java.util.stream.Collectors +import javax.sql.DataSource + +@EmbeddedDatabaseTest( + compatibilityMode = CompatibilityMode.MySQL, + initialSqls = [ + ( + "CREATE TABLE app_events (" + + " event_id INT PRIMARY KEY," + + " user_id INT NOT NULL," + + " event_timestamp TIMESTAMP NOT NULL," + + " event_type VARCHAR(50) NOT NULL," + + " session_id VARCHAR(50) NOT NULL," + + " event_value INT" + + ");" + + "INSERT INTO app_events (event_id, user_id, event_timestamp, " + + "event_type, session_id, event_value) VALUES" + + "(1, 201, '2024-03-01 10:00:00', 'app_open', 'S001', NULL)," + + "(2, 201, '2024-03-01 10:05:00', 'scroll', 'S001', 500)," + + "(3, 201, '2024-03-01 10:10:00', 'scroll', 'S001', 750)," + + "(4, 201, '2024-03-01 10:15:00', 'scroll', 'S001', 600)," + + "(5, 201, '2024-03-01 10:20:00', 'scroll', 'S001', 800)," + + "(6, 201, '2024-03-01 10:25:00', 'scroll', 'S001', 550)," + + "(7, 201, '2024-03-01 10:30:00', 'scroll', 'S001', 900)," + + "(8, 201, '2024-03-01 10:35:00', 'app_close', 'S001', NULL)," + + "(9, 202, '2024-03-01 11:00:00', 'app_open', 'S002', NULL)," + + "(10, 202, '2024-03-01 11:02:00', 'click', 'S002', NULL)," + + "(11, 202, '2024-03-01 11:05:00', 'scroll', 'S002', 400)," + + "(12, 202, '2024-03-01 11:08:00', 'click', 'S002', NULL)," + + "(13, 202, '2024-03-01 11:10:00', 'scroll', 'S002', 350)," + + "(14, 202, '2024-03-01 11:15:00', 'purchase', 'S002', 50)," + + "(15, 202, '2024-03-01 11:20:00', 'app_close','S002', NULL)," + + "(16, 203, '2024-03-01 12:00:00', 'app_open', 'S003', NULL)," + + "(17, 203, '2024-03-01 12:10:00', 'scroll', 'S003', 1000)," + + "(18, 203, '2024-03-01 12:20:00', 'scroll', 'S003', 1200)," + + "(19, 203, '2024-03-01 12:25:00', 'click', 'S003', NULL)," + + "(20, 203, '2024-03-01 12:30:00', 'scroll', 'S003', 800)," + + "(21, 203, '2024-03-01 12:40:00', 'scroll', 'S003', 900)," + + "(22, 203, '2024-03-01 12:50:00', 'scroll', 'S003', 1100)," + + "(23, 203, '2024-03-01 13:00:00', 'app_close','S003', NULL)," + + "(24, 204, '2024-03-01 14:00:00', 'app_open', 'S004', NULL)," + + "(25, 204, '2024-03-01 14:05:00', 'scroll', 'S004', 600)," + + "(26, 204, '2024-03-01 14:08:00', 'scroll', 'S004', 700)," + + "(27, 204, '2024-03-01 14:10:00', 'click', 'S004', NULL)," + + "(28, 204, '2024-03-01 14:12:00', 'app_close','S004', NULL);" + ), + ], +) +internal class MysqlTest { + @Test + @Throws(SQLException::class, FileNotFoundException::class) + fun testScript(@EmbeddedDatabase dataSource: DataSource) { + dataSource.connection.use { connection -> + connection.createStatement().use { statement -> + statement.executeQuery( + BufferedReader( + FileReader( + ( + "src/main/kotlin/g3601_3700/" + + "s3673_find_zombie_sessions/" + + "script.sql" + ), + ), + ) + .lines() + .collect(Collectors.joining("\n")) + .replace("#.*?\\r?\\n".toRegex(), ""), + ).use { resultSet -> + MatcherAssert.assertThat(resultSet.next(), CoreMatchers.equalTo(true)) + MatcherAssert.assertThat(resultSet.getNString(1), CoreMatchers.equalTo("S001")) + MatcherAssert.assertThat(resultSet.getNString(2), CoreMatchers.equalTo("201")) + MatcherAssert.assertThat(resultSet.getNString(3), CoreMatchers.equalTo("35")) + MatcherAssert.assertThat(resultSet.getNString(4), CoreMatchers.equalTo("6")) + MatcherAssert.assertThat(resultSet.next(), CoreMatchers.equalTo(false)) + } + } + } + } +} diff --git a/src/test/kotlin/g3601_3700/s3674_minimum_operations_to_equalize_array/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3674_minimum_operations_to_equalize_array/SolutionTest.kt new file mode 100644 index 00000000..15e53a37 --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3674_minimum_operations_to_equalize_array/SolutionTest.kt @@ -0,0 +1,17 @@ +package g3601_3700.s3674_minimum_operations_to_equalize_array + +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(1, 2)), equalTo(1)) + } + + @Test + fun minOperations2() { + assertThat(Solution().minOperations(intArrayOf(5, 5, 5)), equalTo(0)) + } +} diff --git a/src/test/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/SolutionTest.kt new file mode 100644 index 00000000..ecbe4eb3 --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/SolutionTest.kt @@ -0,0 +1,17 @@ +package g3601_3700.s3675_minimum_operations_to_transform_string + +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("yz"), equalTo(2)) + } + + @Test + fun minOperations2() { + assertThat(Solution().minOperations("a"), equalTo(0)) + } +} diff --git a/src/test/kotlin/g3601_3700/s3676_count_bowl_subarrays/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3676_count_bowl_subarrays/SolutionTest.kt new file mode 100644 index 00000000..8cd38488 --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3676_count_bowl_subarrays/SolutionTest.kt @@ -0,0 +1,31 @@ +package g3601_3700.s3676_count_bowl_subarrays + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun bowlSubarrays() { + assertThat( + Solution().bowlSubarrays(intArrayOf(2, 5, 3, 1, 4)), + equalTo(2L), + ) + } + + @Test + fun bowlSubarrays2() { + assertThat( + Solution().bowlSubarrays(intArrayOf(5, 1, 2, 3, 4)), + equalTo(3L), + ) + } + + @Test + fun bowlSubarrays3() { + assertThat( + Solution().bowlSubarrays(intArrayOf(1000000000, 999999999, 999999998)), + equalTo(0L), + ) + } +} diff --git a/src/test/kotlin/g3601_3700/s3677_count_binary_palindromic_numbers/SolutionTest.kt b/src/test/kotlin/g3601_3700/s3677_count_binary_palindromic_numbers/SolutionTest.kt new file mode 100644 index 00000000..ac5d7d4e --- /dev/null +++ b/src/test/kotlin/g3601_3700/s3677_count_binary_palindromic_numbers/SolutionTest.kt @@ -0,0 +1,58 @@ +package g3601_3700.s3677_count_binary_palindromic_numbers + +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat +import org.junit.jupiter.api.Test + +internal class SolutionTest { + @Test + fun countBinaryPalindromes() { + assertThat(Solution().countBinaryPalindromes(9L), equalTo(6)) + } + + @Test + fun countBinaryPalindromes2() { + assertThat(Solution().countBinaryPalindromes(9L), equalTo(6)) + } + + @Test + fun countBinaryPalindromes3() { + // Branch: n == 0 → returns 1 immediately + assertThat(Solution().countBinaryPalindromes(0), equalTo(1)) + } + + @Test + fun countBinaryPalindromes4() { + // n = 1 ("1") → palindrome + // Expected palindromes: 1 (0) + 1 (1) = 2 + assertThat(Solution().countBinaryPalindromes(1), equalTo(2)) + } + + @Test + fun countBinaryPalindromes5() { + // n = 6 ("110"), length = 3 (odd) + // Palindromes up to 6: 0,1,3,5 + assertThat(Solution().countBinaryPalindromes(6), equalTo(4)) + } + + @Test + fun countBinaryPalindromes6() { + // n = 9 ("1001"), palindrome itself + // Palindromes up to 9: 0,1,3,5,7,9 + assertThat(Solution().countBinaryPalindromes(9), equalTo(6)) + } + + @Test + fun countBinaryPalindromes7() { + // n = 10 ("1010") → next palindrome = 9 (smaller) → branch where palin <= n + // Palindromes up to 10: 0,1,3,5,7,9 + assertThat(Solution().countBinaryPalindromes(10), equalTo(6)) + } + + @Test + fun countBinaryPalindromes8() { + // 1023 = "1111111111" + val n = (1L shl 10) - 1 + assertThat(Solution().countBinaryPalindromes(n), equalTo(63)) + } +} From 9519776225b6b4e6f18b19523aa1dc6ccbc7ebf2 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 7 Sep 2025 20:05:36 +0300 Subject: [PATCH 2/4] Fixed test --- .../s3673_find_zombie_sessions/MysqlTest.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/kotlin/g3601_3700/s3673_find_zombie_sessions/MysqlTest.kt b/src/test/kotlin/g3601_3700/s3673_find_zombie_sessions/MysqlTest.kt index a357494f..a72e25c2 100644 --- a/src/test/kotlin/g3601_3700/s3673_find_zombie_sessions/MysqlTest.kt +++ b/src/test/kotlin/g3601_3700/s3673_find_zombie_sessions/MysqlTest.kt @@ -1,7 +1,7 @@ package g3601_3700.s3673_find_zombie_sessions -import org.hamcrest.CoreMatchers -import org.hamcrest.MatcherAssert +import org.hamcrest.CoreMatchers.equalTo +import org.hamcrest.MatcherAssert.assertThat import org.junit.jupiter.api.Test import org.zapodot.junit.db.annotations.EmbeddedDatabase import org.zapodot.junit.db.annotations.EmbeddedDatabaseTest @@ -78,12 +78,12 @@ internal class MysqlTest { .collect(Collectors.joining("\n")) .replace("#.*?\\r?\\n".toRegex(), ""), ).use { resultSet -> - MatcherAssert.assertThat(resultSet.next(), CoreMatchers.equalTo(true)) - MatcherAssert.assertThat(resultSet.getNString(1), CoreMatchers.equalTo("S001")) - MatcherAssert.assertThat(resultSet.getNString(2), CoreMatchers.equalTo("201")) - MatcherAssert.assertThat(resultSet.getNString(3), CoreMatchers.equalTo("35")) - MatcherAssert.assertThat(resultSet.getNString(4), CoreMatchers.equalTo("6")) - MatcherAssert.assertThat(resultSet.next(), CoreMatchers.equalTo(false)) + assertThat(resultSet.next(), equalTo(true)) + assertThat(resultSet.getNString(1), equalTo("S001")) + assertThat(resultSet.getNString(2), equalTo("201")) + assertThat(resultSet.getNString(3), equalTo("35")) + assertThat(resultSet.getNString(4), equalTo("6")) + assertThat(resultSet.next(), equalTo(false)) } } } From 748c192d866bf040e573e93eed8fa4afe61ae2c1 Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 14 Sep 2025 09:58:08 +0300 Subject: [PATCH 3/4] Updated tasks --- .../Solution.kt | 27 +++++++-------- .../s3676_count_bowl_subarrays/Solution.kt | 33 +++++++++---------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/Solution.kt b/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/Solution.kt index 4f1d82f1..4cf6ef77 100644 --- a/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/Solution.kt @@ -1,22 +1,23 @@ package g3601_3700.s3675_minimum_operations_to_transform_string -// #Medium #Weekly_Contest_466 #2025_09_07_Time_84_ms_(100.00%)_Space_56.99_MB_(100.00%) +// #Medium #Weekly_Contest_466 #2025_09_14_Time_6_ms_(97.92%)_Space_57.75_MB_(43.75%) class Solution { fun minOperations(s: String): Int { - val set: MutableSet = HashSet() - for (ch in s.toCharArray()) { - set.add(ch) - } - if (set.size == 1 && set.contains('a')) { - return 0 - } - var minCh = 'z' - for (ch in s.toCharArray()) { - if (ch != 'a' && ch < minCh) { - minCh = ch + val n = s.length + var ans = 0 + for (i in 0.. ans) { + ans = ops + } + if (ops == 25) { + break + } } } - return ('z'.code - minCh.code) + 1 + return ans } } diff --git a/src/main/kotlin/g3601_3700/s3676_count_bowl_subarrays/Solution.kt b/src/main/kotlin/g3601_3700/s3676_count_bowl_subarrays/Solution.kt index 4df2010e..5debc1bc 100644 --- a/src/main/kotlin/g3601_3700/s3676_count_bowl_subarrays/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3676_count_bowl_subarrays/Solution.kt @@ -1,26 +1,25 @@ package g3601_3700.s3676_count_bowl_subarrays -// #Medium #Weekly_Contest_466 #2025_09_07_Time_26_ms_(100.00%)_Space_84.36_MB_(100.00%) - -import kotlin.math.min +// #Medium #Weekly_Contest_466 #2025_09_14_Time_3_ms_(100.00%)_Space_79.40_MB_(50.00%) class Solution { fun bowlSubarrays(nums: IntArray): Long { - val l = nums.size - var ans = 0 - val stack: java.util.Deque = java.util.ArrayDeque() - for (i in 0.. nums[mid]) { - ++ans - } - } + val n = nums.size + var res = n + var pre = 0 + for (a in nums) { + if (a > pre) { + res-- + pre = a + } + } + pre = 0 + for (i in n - 1 downTo 0) { + if (nums[i] > pre) { + res-- + pre = nums[i] } - stack.push(i) } - return ans.toLong() + return res + 1L } } From ad646a8a96e34e5bb5abcda1351ad1842aea408f Mon Sep 17 00:00:00 2001 From: Valentyn Kolesnikov Date: Sun, 14 Sep 2025 12:23:09 +0300 Subject: [PATCH 4/4] Update Solution.kt --- .../s3675_minimum_operations_to_transform_string/Solution.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/Solution.kt b/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/Solution.kt index 4cf6ef77..b5415b58 100644 --- a/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/Solution.kt +++ b/src/main/kotlin/g3601_3700/s3675_minimum_operations_to_transform_string/Solution.kt @@ -7,7 +7,7 @@ class Solution { val n = s.length var ans = 0 for (i in 0.. ans) {