From 1f5b1aecb9affb822eed6396bd83f6dd79f42c22 Mon Sep 17 00:00:00 2001 From: iswat Date: Sat, 27 Jun 2026 20:55:00 +0100 Subject: [PATCH 01/10] refactor: combine sum and product into a single loop - Refactored logic to calculate both sum and product in one pass - Reduced iterations from 2n to n while maintaining O(n) time complexity - Maintained O(1) space complexity --- .../calculateSumAndProduct/calculateSumAndProduct.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js index ce738c33..1fdf3573 100644 --- a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js +++ b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js @@ -18,12 +18,9 @@ */ export function calculateSumAndProduct(numbers) { let sum = 0; - for (const num of numbers) { - sum += num; - } - let product = 1; for (const num of numbers) { + sum += num; product *= num; } From 783b681068f851d82f5abbcec6faf954fca10f93 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 29 Jun 2026 11:35:49 +0100 Subject: [PATCH 02/10] refactor: optimize findCommonItems to linear time complexity - Replaced Array.includes (O(m)) with Set.has (O(1)) inside the filter loop - Improved time complexity from O(n * m) to O(n + m) - Utilized a Set for precomputing lookups to avoid nested linear searches --- Sprint-1/JavaScript/findCommonItems/findCommonItems.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js index 5619ae5d..0b6b9f13 100644 --- a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js +++ b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js @@ -9,6 +9,8 @@ * @param {Array} secondArray - Second array to compare * @returns {Array} Array containing unique common items */ -export const findCommonItems = (firstArray, secondArray) => [ - ...new Set(firstArray.filter((item) => secondArray.includes(item))), -]; +export const findCommonItems = (firstArray, secondArray) => { + const secondArraySet = new Set(secondArray); + + return [...new Set(firstArray.filter((item) => secondArraySet.has(item)))]; +}; From c5a6a875e5942455bb03aac74f0fded3e3f69735 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 29 Jun 2026 12:17:49 +0100 Subject: [PATCH 03/10] refactor: optimize hasPairWithSum to O(n) time complexity - Replaced nested loops (O(n^2)) with a single-pass approach - Implemented a Set to store visited numbers for O(1) complement (remainingNumberNeeded) lookups - Improved performance for large datasets by trading space (O(n)) for time (O(n)) --- .../JavaScript/hasPairWithSum/hasPairWithSum.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js b/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js index dd2901f6..14b2ef35 100644 --- a/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js +++ b/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js @@ -10,11 +10,14 @@ * @returns {boolean} True if pair exists, false otherwise */ export function hasPairWithSum(numbers, target) { - for (let i = 0; i < numbers.length; i++) { - for (let j = i + 1; j < numbers.length; j++) { - if (numbers[i] + numbers[j] === target) { - return true; - } + const numbersSet = new Set(); + + for (let i=0; i Date: Mon, 29 Jun 2026 12:42:33 +0100 Subject: [PATCH 04/10] refactor: optimize removeDuplicates to O(n) time complexity - Replaced nested loops (O(n^2)) with a Set-based lookup approach - Achieved O(n) time complexity by utilizing O(1) Set.has() checks - Maintained the original order of elements while improving scalability - Increased space complexity to O(n) to store the Set of seen elements --- .../removeDuplicates/removeDuplicates.mjs | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs b/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs index dc5f7711..c00aedcf 100644 --- a/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs +++ b/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs @@ -9,28 +9,14 @@ * @returns {Array} New sequence with duplicates removed */ export function removeDuplicates(inputSequence) { - const uniqueItems = []; + const result = []; + const elementSeen = new Set(); - for ( - let currentIndex = 0; - currentIndex < inputSequence.length; - currentIndex++ - ) { - let isDuplicate = false; - for ( - let compareIndex = 0; - compareIndex < uniqueItems.length; - compareIndex++ - ) { - if (inputSequence[currentIndex] === uniqueItems[compareIndex]) { - isDuplicate = true; - break; - } - } - if (!isDuplicate) { - uniqueItems.push(inputSequence[currentIndex]); + for (let i=0; i Date: Mon, 29 Jun 2026 12:59:10 +0100 Subject: [PATCH 05/10] docs: add complexity analysis and refactoring summary for Sprint 1/JavaScript - Added CHANGES-MADE.md to document performance improvements - Summarized the transition from O(n^2) to O(n) across JavaScript tasks - Explained the Space-Time trade-offs involved in using Sets for optimization --- Sprint-1/JavaScript/CHANGES-MADE.md | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Sprint-1/JavaScript/CHANGES-MADE.md diff --git a/Sprint-1/JavaScript/CHANGES-MADE.md b/Sprint-1/JavaScript/CHANGES-MADE.md new file mode 100644 index 00000000..a709b734 --- /dev/null +++ b/Sprint-1/JavaScript/CHANGES-MADE.md @@ -0,0 +1,49 @@ +This is a great way to document your learning and show the impact of your refactoring. Below is the content for your `changes-made.md` file, formatted exactly like the comparison table you provided. + +--- + +# Sprint 1: Complexity Analysis & Refactoring + +## 1. calculateSumAndProduct.js +| Feature | Original Code | Refactored Code | +| :--- | :--- | :--- | +| **Time Complexity** | **Linear $O(n)$** | **Linear $O(n)$** | +| **Why?** | Two separate loops ($n + n$). | Combined into a single loop ($n$). | +| **Space Complexity** | **Constant $O(1)$** | **Constant $O(1)$** | +| **Why?** | Only two scalar variables used. | Only two scalar variables used. | + +--- + +## 2. findCommonItems.js +| Feature | Original Code | Refactored Code | +| :--- | :--- | :--- | +| **Time Complexity** | **Quadratic $O(n \times m)$** | **Linear $O(n + m)$** | +| **Why?** | Nested loop: `.includes()` inside `.filter()`. | Set lookup: `.has()` inside `.filter()`. | +| **Space Complexity** | **Constant $O(1)$** | **Linear $O(m)$** | +| **Why?** | No extra search structure created. | Created a `Set` to store the second array. | + +--- + +## 3. hasPairWithSum.js +| Feature | Original Code | Refactored Code | +| :--- | :--- | :--- | +| **Time Complexity** | **Quadratic $O(n^2)$** | **Linear $O(n)$** | +| **Why?** | Nested `for` loops comparing every pair. | One loop with instant "Complement" lookup. | +| **Space Complexity** | **Constant $O(1)$** | **Linear $O(n)$** | +| **Why?** | No extra storage used. | Created a `Set` to store visited numbers. | + +--- + +## 4. removeDuplicates.js +| Feature | Original Code | Refactored Code | +| :--- | :--- | :--- | +| **Time Complexity** | **Quadratic $O(n^2)$** | **Linear $O(n)$** | +| **Why?** | Nested loop searching the result array. | One loop using a Set for "Seen" items. | +| **Space Complexity** | **Linear $O(n)$** | **Linear $O(n)$** | +| **Why?** | Stored unique items in an array. | Stored unique items in both an array and a Set. | + +--- + +### Key Takeaway: The Space-Time Trade-off +In the `findCommonItems.js`, `hasPairWithSum.js` and `removeDuplicates.js` tasks, I successfully reduced the **Time Complexity** from Quadratic to Linear. I did this by choosing a **Set** instead of an **Array** for searching. This is a classic "Space-Time Trade-off": I used a bit more memory (Space) to make the program run significantly faster (Time). + From 22391c50c7317470b4fd9589502d4d3d6a92909c Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 29 Jun 2026 13:19:06 +0100 Subject: [PATCH 06/10] refactor: optimize calculate_sum_and_product to single pass (Python) - Combined sum and product calculations into a single for-loop - Renamed 'sum' variable to 'total_sum' to avoid shadowing Python's built-in sum() - Maintained O(n) time complexity while reducing operations from 2n to n - Maintained O(1) space complexity --- .../calculate_sum_and_product.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Sprint-1/Python/calculate_sum_and_product/calculate_sum_and_product.py b/Sprint-1/Python/calculate_sum_and_product/calculate_sum_and_product.py index cfd5cfdf..50a77795 100644 --- a/Sprint-1/Python/calculate_sum_and_product/calculate_sum_and_product.py +++ b/Sprint-1/Python/calculate_sum_and_product/calculate_sum_and_product.py @@ -20,12 +20,10 @@ def calculate_sum_and_product(input_numbers: List[int]) -> Dict[str, int]: if not input_numbers: return {"sum": 0, "product": 1} - sum = 0 - for current_number in input_numbers: - sum += current_number - + total_sum = 0 product = 1 for current_number in input_numbers: + total_sum += current_number product *= current_number - - return {"sum": sum, "product": product} + + return {"sum": total_sum, "product": product} From 4308c42ddf45c78d86c63fe3797905d734fbf44d Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 29 Jun 2026 13:40:12 +0100 Subject: [PATCH 07/10] refactor: optimize find_common_items using sets for O(n+m) complexity - Replaced nested loops (O(n * m)) with a Set for constant time lookups - Converted second_sequence to a set to enable O(1) membership checks - Utilized a result set to ensure uniqueness without linear searches in a list - Improved time complexity from quadratic to linear (O(n + m)) --- .../find_common_items/find_common_items.py | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Sprint-1/Python/find_common_items/find_common_items.py b/Sprint-1/Python/find_common_items/find_common_items.py index 478e2efc..a5bda6e9 100644 --- a/Sprint-1/Python/find_common_items/find_common_items.py +++ b/Sprint-1/Python/find_common_items/find_common_items.py @@ -13,9 +13,17 @@ def find_common_items( Space Complexity: Optimal time complexity: """ - common_items: List[ItemType] = [] - for i in first_sequence: - for j in second_sequence: - if i == j and i not in common_items: - common_items.append(i) - return common_items + # 1. Convert second_sequence into a Python set for O(1) lookups + second_set = set(second_sequence) + + # 2. Use a set to keep track of results (handles the "Unique Items" requirement) + common_items_set: Set[ItemType] = set() + + # 3. Use one loop to go through first_sequence + for item in first_sequence: + # 4. Check if the item is in the second_set + if item in second_set: + common_items_set.add(item) + + # 5. Convert final set back into a list + return list(common_items_set) \ No newline at end of file From ae0bae2533f8e75d20773d55ce9afb5affaa6be7 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 29 Jun 2026 14:02:59 +0100 Subject: [PATCH 08/10] refactor: optimize has_pair_with_sum to O(n) using a set (Python) - Replaced nested O(n^2) loops with a single-pass hash set approach - Implemented 'remaining_number_needed' logic for O(1) membership lookups - Improved time complexity from quadratic to linear - Accepted O(n) space complexity as a trade-off for significantly faster execution --- .../has_pair_with_sum/has_pair_with_sum.py | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Sprint-1/Python/has_pair_with_sum/has_pair_with_sum.py b/Sprint-1/Python/has_pair_with_sum/has_pair_with_sum.py index fe2da517..9d22fca9 100644 --- a/Sprint-1/Python/has_pair_with_sum/has_pair_with_sum.py +++ b/Sprint-1/Python/has_pair_with_sum/has_pair_with_sum.py @@ -1,4 +1,4 @@ -from typing import List, TypeVar +from typing import List, Set, TypeVar Number = TypeVar("Number", int, float) @@ -11,8 +11,20 @@ def has_pair_with_sum(numbers: List[Number], target_sum: Number) -> bool: Space Complexity: Optimal time complexity: """ - for i in range(len(numbers)): - for j in range(i + 1, len(numbers)): - if numbers[i] + numbers[j] == target_sum: - return True + # 1. Initialize an empty set called seen. + seen: Set[Number] = set() + + # 2. Loop through each num in the numbers list. + for num in numbers: + # 3. Calculate the remaining_number_needed (the missing piece). + remaining_number_needed = target_sum - num + + # 4. Check: if remaining_number_needed in seen. + if remaining_number_needed in seen: + return True + + # 5. If not, add the current num to the set. + seen.add(num) + + # 6. If the loop finishes, return False. return False From 549cd03a1229efbeb8fb6d6cd1c680e0156264b2 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 29 Jun 2026 14:10:50 +0100 Subject: [PATCH 09/10] refactor: optimize remove_duplicates to O(n) using a hash set (Python) - Replaced nested loops (O(n^2)) with a single-pass approach using a Set - Leveraged O(1) membership checks with 'element_seen' to identify duplicates - Utilized a result list to preserve the original order of first occurrences - Documented O(n) time and space complexity in the docstring --- .../remove_duplicates/remove_duplicates.py | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/Sprint-1/Python/remove_duplicates/remove_duplicates.py b/Sprint-1/Python/remove_duplicates/remove_duplicates.py index c9fdbe80..1b6da606 100644 --- a/Sprint-1/Python/remove_duplicates/remove_duplicates.py +++ b/Sprint-1/Python/remove_duplicates/remove_duplicates.py @@ -7,19 +7,20 @@ def remove_duplicates(values: Sequence[ItemType]) -> List[ItemType]: """ Remove duplicate values from a sequence, preserving the order of the first occurrence of each value. - Time complexity: - Space complexity: - Optimal time complexity: + Time complexity: O(n) + Space complexity: O(n) + Optimal time complexity: O(n) """ - unique_items = [] + # 1. Initialize your list and set + result: List[ItemType] = [] + element_seen: Set[ItemType] = set() + # 2. Start your loop for value in values: - is_duplicate = False - for existing in unique_items: - if value == existing: - is_duplicate = True - break - if not is_duplicate: - unique_items.append(value) - - return unique_items + # 3. Check if we have NOT seen this value yet + if value not in element_seen: + # 4. Remember it in the set and add it to the result + element_seen.add(value) + result.append(value) + + return result From 6af9b572584ea22b816218057c5bacc43084a718 Mon Sep 17 00:00:00 2001 From: iswat Date: Mon, 29 Jun 2026 14:17:35 +0100 Subject: [PATCH 10/10] docs: add Python-specific complexity analysis for Sprint 1 - Documented refactoring results for the 4 Python exercises - Explained the efficiency of Python sets vs lists for membership checks - Highlighted the transition from quadratic to linear time complexity --- Sprint-1/Python/CHANGES-MADE.md | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Sprint-1/Python/CHANGES-MADE.md diff --git a/Sprint-1/Python/CHANGES-MADE.md b/Sprint-1/Python/CHANGES-MADE.md new file mode 100644 index 00000000..99c4246a --- /dev/null +++ b/Sprint-1/Python/CHANGES-MADE.md @@ -0,0 +1,51 @@ +# Sprint 1: Complexity Analysis & Refactoring (Python) + +## 1. calculate_sum_and_product.py +| Feature | Original Code | Refactored Code | +| :--- | :--- | :--- | +| **Time Complexity** | **Linear $O(n)$** | **Linear $O(n)$** | +| **Why?** | Two separate `for` loops ($n + n$). | Combined into a single `for` loop ($n$). | +| **Space Complexity** | **Constant $O(1)$** | **Constant $O(1)$** | +| **Why?** | Used two scalar variables. | Used two scalar variables. | + +**Note:** Renamed the variable `sum` to `total_sum` to avoid shadowing Python's built-in `sum()` function. + +--- + +## 2. find_common_items.py +| Feature | Original Code | Refactored Code | +| :--- | :--- | :--- | +| **Time Complexity** | **Quadratic $O(n \times m)$** | **Linear $O(n + m)$** | +| **Why?** | Nested loops searching a **list** with the `in` keyword ($O(m)$). | Used a **set** for $O(1)$ membership lookups with the `in` keyword. | +| **Space Complexity** | **Constant $O(1)$** | **Linear $O(m)$** | +| **Why?** | No extra storage created. | Created a `set` to store the second sequence for fast lookups. | + +--- + +## 3. has_pair_with_sum.py +| Feature | Original Code | Refactored Code | +| :--- | :--- | :--- | +| **Time Complexity** | **Quadratic $O(n^2)$** | **Linear $O(n)$** | +| **Why?** | Nested loops comparing every index. | Single pass with a `set` to find the `remaining_number_needed`. | +| **Space Complexity** | **Constant $O(1)$** | **Linear $O(n)$** | +| **Why?** | No extra storage used. | Created a `seen` set to store visited numbers. | + +--- + +## 4. remove_duplicates.py +| Feature | Original Code | Refactored Code | +| :--- | :--- | :--- | +| **Time Complexity** | **Quadratic $O(n^2)$** | **Linear $O(n)$** | +| **Why?** | Nested loops checking if an item was `not in` the result **list**. | Used an `element_seen` **set** for $O(1)$ "already seen" checks. | +| **Space Complexity** | **Linear $O(n)$** | **Linear $O(n)$** | +| **Why?** | Stored unique items in a list. | Stored items in both a result list (for order) and a set (for speed). | + +--- + +### Key Python Takeaways + +1. **The `in` Keyword Efficiency:** In Python, the `in` operator is very readable, but its speed depends on the container. Checking `in` for a **list** is $O(n)$, while checking `in` for a **set** is $O(1)$. Leveraging this difference allowed me to optimize three of the four tasks. +2. **Space-Time Trade-off:** To improve the runtime of `find_common_items`, `has_pair_with_sum`, and `remove_duplicates` from $O(n^2)$ to $O(n)$, I utilized extra memory (Space) by creating Python **sets**. +3. **Built-in Shadowing:** I learned to be careful with variable naming (e.g., using `total_sum` instead of `sum`) to avoid overwriting Python’s built-in functions. +4. **Preserving Order:** In `remove_duplicates`, I learned that while sets are fast, they don't preserve order. Using a list for results and a set for tracking allowed for both $O(n)$ speed and correct ordering. +