diff --git a/.idea/A-December-Of-Algorithms-2023.iml b/.idea/A-December-Of-Algorithms-2023.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/A-December-Of-Algorithms-2023.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d56657a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..1dbeaa7 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..885c8b7 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1701448858654 + + + + \ No newline at end of file diff --git a/December 01/python3_lakshminarayanans_cricmetric.py b/December 01/python3_lakshminarayanans_cricmetric.py new file mode 100644 index 0000000..b033693 --- /dev/null +++ b/December 01/python3_lakshminarayanans_cricmetric.py @@ -0,0 +1,42 @@ +""" +Module documentation: count_runs + +This module defines a function count_runs to calculate the total runs scored by a given number of batsmen. +It also tracks the highest run scored and the corresponding batsman index. + +Usage: + total_n = int(input("Enter the total number of batsmen: ")) + count_runs(total_n) +""" + + +def count_runs(total_n): + """ + Calculate the total runs scored by a given number of batsmen and track the highest run scored. + + Parameters: + total_n (int): The total number of batsmen. + + Returns: + None + """ + + runs = 0 + highest = 0 + highest_index = 0 + + for i in range(total_n): + run = int(input(f"Enter the runs scored by batsman {i + 1}: ")) + runs += run + + if highest < run: + highest = run + highest_index = i + + print("Total Runs:", runs) + print("Batsman with the highest run:", highest_index) + + +if __name__ == "__main__": + total_n = int(input("Enter the total number of batsmen: ")) + count_runs(total_n) diff --git a/December 02/python3_lakshminarayanans_shopperschoice.py b/December 02/python3_lakshminarayanans_shopperschoice.py new file mode 100644 index 0000000..4c6fd72 --- /dev/null +++ b/December 02/python3_lakshminarayanans_shopperschoice.py @@ -0,0 +1,44 @@ +""" +Module documentation: shoppers_frequency + +This module defines a function shoppers_frequency to calculate the frequency of each unique product ID in a given list. + +Usage: + product_ids = [2, 2, 3, 4, 5, 6, 2, 4, 6, 7] + shoppers_frequency(product_ids) +""" + +def shoppers_frequency(product_ids): + """ + Calculate the frequency of each unique product ID in the given list. + + Parameters: + product_ids (list): A list of product IDs. + + Returns: + None + """ + + unique_ids = [] + final_frequency = [] + + for i in range(len(product_ids)): + counter = 0 + current_val = product_ids[i] + + if current_val not in unique_ids: + unique_ids.append(current_val) + + for j in range(i, len(product_ids)): + if product_ids[j] == product_ids[i]: + counter += 1 + + final_frequency.append(counter) + + print("Output") + print(final_frequency) + + +if __name__ == "__main__": + product_ids = [2, 2, 3, 4, 5, 6, 2, 4, 6, 7] + shoppers_frequency(product_ids) diff --git a/December 03/python3_lakshminarayanans_sunburnt.py b/December 03/python3_lakshminarayanans_sunburnt.py new file mode 100644 index 0000000..06768f6 --- /dev/null +++ b/December 03/python3_lakshminarayanans_sunburnt.py @@ -0,0 +1,36 @@ +""" +Module documentation: count_buildings_with_sunrise + +This module defines a function count_buildings_with_sunrise to determine the number of buildings with a sunrise view. + +Usage: + buildings_height = [7, 4, 8, 2, 9] + count_buildings_with_sunrise(buildings_height) +""" + +def count_buildings_with_sunrise(buildings_height): + """ + Count the number of buildings with a sunrise view based on their heights. + + Parameters: + buildings_height (list): A list representing the heights of buildings. + + Returns: + None + """ + + count = 1 + highest = buildings_height[0] + + for height in buildings_height[1:]: + if height > highest: + count += 1 + highest = height + + print("Output") + print(count) + + +if __name__ == "__main__": + buildings_height = [7, 4, 8, 2, 9] + count_buildings_with_sunrise(buildings_height) diff --git a/December 04/python3_lakshminarayanans_mirrormagic.py b/December 04/python3_lakshminarayanans_mirrormagic.py new file mode 100644 index 0000000..ea6f993 --- /dev/null +++ b/December 04/python3_lakshminarayanans_mirrormagic.py @@ -0,0 +1,54 @@ +""" +Module documentation: Mirror Magic + +This module defines a function find_palindromic_substring to find the smallest palindromic substring in a given string. + +Usage: + input_name_1 = "Hollow" + output_1 = find_palindromic_substring(input_name_1) + print("Input:", input_name_1) + print("Output:", output_1) + + input_name_2 = "Master" + output_2 = find_palindromic_substring(input_name_2) + print("\nInput:", input_name_2) + print("Output:", output_2) +""" + + +def find_palindromic_substring(name): + """ + Find the smallest palindromic substring in a given string. + + Parameters: + name (str): The input string. + + Returns: + str: The smallest palindromic substring, or "Error" if none is found. + """ + length = len(name) + possibilities = [] + + for i in range(length): + for j in range(i + 1, length + 1): + substring = name[i:j] + if substring == substring[::-1] and len(substring) > 1: + possibilities.append(substring) + + if len(possibilities) < 1: + return "Error" + else: + return min(possibilities) + + +if __name__ == "__main__": + # Example Usage + input_name_1 = "Hollow" + output_1 = find_palindromic_substring(input_name_1) + print("Input:", input_name_1) + print("Output:", output_1) + + input_name_2 = "Master" + output_2 = find_palindromic_substring(input_name_2) + print("\nInput:", input_name_2) + print("Output:", output_2) diff --git a/December 05/python3_lakshminarayanans_peakyblinders.py b/December 05/python3_lakshminarayanans_peakyblinders.py new file mode 100644 index 0000000..7cbafce --- /dev/null +++ b/December 05/python3_lakshminarayanans_peakyblinders.py @@ -0,0 +1,45 @@ +""" +Module documentation: Peaky Blinders + +This module provides functions for analyzing a list of amounts, specifically for finding the average amount +and calculating the total amount stolen, considering amounts greater than or equal to the average. + +Usage: + amount_list = [5, 10, 15, 20, 25] + amount_stolen = find_amount_stolen(amount_list) + print("Output: " + str(amount_stolen)) +""" + +def find_avg(amount_list): + """ + Calculate the average of a list of amounts. + + Parameters: + amount_list (list): A list of amounts. + + Returns: + float: The average of the amounts. + """ + total = sum(amount_list) + return total / len(amount_list) + + +def find_amount_stolen(amount_list): + """ + Calculate the total amount stolen, considering amounts greater than or equal to the average. + + Parameters: + amount_list (list): A list of amounts. + + Returns: + int: The total amount stolen. + """ + avg = find_avg(amount_list) + sum_amount_stolen = sum(amount for amount in amount_list if amount >= avg) + return sum_amount_stolen + + +if __name__ == "__main__": + amount_list = [5, 10, 15, 20, 25] + amount_stolen = find_amount_stolen(amount_list) + print("Output: " + str(amount_stolen)) diff --git a/December 06/python3_lakshminarayanans_lostscrolls.py b/December 06/python3_lakshminarayanans_lostscrolls.py new file mode 100644 index 0000000..22396b5 --- /dev/null +++ b/December 06/python3_lakshminarayanans_lostscrolls.py @@ -0,0 +1,50 @@ +""" +Module documentation: The Lost Algorithm Scrolls + +This module defines a function decode_pattern to find valid pairs of words from a list of spells. + +Usage: + spell_list = ["cat", "cot", "dot", "dog", "cog", "coat", "doll"] + output = decode_pattern(spell_list) + print("Output:") + print(output) +""" + + +def decode_pattern(spells): + """ + Find valid pairs of words from a list of spells where each pair differs by exactly one character. + + Parameters: + spells (list): A list of spells. + + Returns: + list: A list of valid pairs of words. + """ + ancient_scrolls = [] + for i in range(len(spells)): + if i + 1 < len(spells) and spells[i + 1] is None: + spells[i + 1] = '' + for j in range(i + 1, len(spells)): # Start from i + 1 to avoid duplicate pairs + count = 0 + if len(spells[i]) == len(spells[j]): + for k in range(len(spells[i])): + if spells[i][k] != spells[j][k]: + count += 1 + if count == 1: + if spells[i] not in ancient_scrolls: + ancient_scrolls.append(spells[i]) + if spells[j] not in ancient_scrolls: + ancient_scrolls.append(spells[j]) + if ancient_scrolls: + return ancient_scrolls + else: + return "No valid chain." + + +if __name__ == "__main__": + # Example usage + spell_list = ["cat", "cot", "dot", "dog", "cog", "coat", "doll"] + output = decode_pattern(spell_list) + print("Output:") + print(output) diff --git a/December 07/python3_lakshminarayanans_babyblocks.py b/December 07/python3_lakshminarayanans_babyblocks.py new file mode 100644 index 0000000..4c3f717 --- /dev/null +++ b/December 07/python3_lakshminarayanans_babyblocks.py @@ -0,0 +1,35 @@ +""" +Module documentation: rectangle_in_circle + +This module defines a function rectangle_in_circle to check if a rectangle with given width and height +can fit within a circle of a specified radius. + +Usage: + result = rectangle_in_circle(8, 6, 5) + print("Output:") + print(result) +""" + + +def rectangleInCircle(width, height, radius): + """ + Check if a rectangle with given width and height can fit within a circle of a specified radius. + + Parameters: + width (float): The width of the rectangle. + height (float): The height of the rectangle. + radius (float): The radius of the circle. + + Returns: + bool: True if the rectangle can fit within the circle, False otherwise. + """ + diag = ((width ** 2) + (height ** 2)) ** 0.5 + diameter = radius * 2 + + return diag <= diameter + + +if __name__ == "__main__": + result = rectangleInCircle(8, 6, 5) + print("Output:") + print(result) diff --git a/December 08/python3_lakshminarayanans_enchantedforest.py b/December 08/python3_lakshminarayanans_enchantedforest.py new file mode 100644 index 0000000..a7624c6 --- /dev/null +++ b/December 08/python3_lakshminarayanans_enchantedforest.py @@ -0,0 +1,54 @@ +""" +Module documentation: magic_square_generator + +This module defines a function find_path to generate a magic square of odd order. + +Usage: + n = 3 + result = find_path(n) + + # Display the result + for row in result: + print(" ".join(map(str, row))) +""" + + +def find_path(n): + """ + Generate a magic square of odd order. + + Parameters: + n (int): The order of the magic square. Must be an odd integer. + + Returns: + list: A 2D list representing the magic square. + """ + if n % 2 == 0: + raise ValueError("Input must be an odd integer") + + magic_square = [[0] * n for _ in range(n)] + i, j = 0, n // 2 + num = 1 + + while num <= n * n: + magic_square[i][j] = num + num += 1 + + newi, newj = (i - 1) % n, (j + 1) % n + + if magic_square[newi][newj] == 0: + i, j = newi, newj + else: + i += 1 + + return magic_square + + +if __name__ == "__main__": + # Example usage + n = 3 + result = find_path(n) + + # Display the result + for row in result: + print(" ".join(map(str, row))) diff --git a/December 09/python3_lakshminarayanans_camelsonastring.py b/December 09/python3_lakshminarayanans_camelsonastring.py new file mode 100644 index 0000000..5b06016 --- /dev/null +++ b/December 09/python3_lakshminarayanans_camelsonastring.py @@ -0,0 +1,35 @@ +""" +Module documentation: camelcase_word_counter + +This module defines a function number_of_words_camelcase_string to count the number of words in a camelCase string. + +Usage: + total_words = number_of_words_camelcase_string('SaveChangesInTheEditor') + print("Output:", total_words) +""" + +import re + + +def number_of_words_camelcase_string(string): + """ + Count the number of words in a camelCase string. + + Parameters: + string (str): The camelCase string. + + Returns: + int: The number of words in the camelCase string. + """ + count = 0 + for char in string: + if bool(re.match('[A-Z]', char)): + count += 1 + + return count + + +if __name__ == "__main__": + # Example usage + total_words = number_of_words_camelcase_string('SaveChangesInTheEditor') + print("Output:", total_words) diff --git a/December 10/python3_lakshminarayanans_forgotpassword.py b/December 10/python3_lakshminarayanans_forgotpassword.py new file mode 100644 index 0000000..48f761a --- /dev/null +++ b/December 10/python3_lakshminarayanans_forgotpassword.py @@ -0,0 +1,59 @@ +""" +Module Documentation: Forgot Password + +This module processes substring queries on a specified table and column. + +Functions: + - process_substring_query(query): Processes a substring query on a specified table and column. + +Usage: + - Call process_substring_query(query) to process substring queries and print the results. + +""" + +import re + +# Database information +tables = {"emp"} +table_column_map = {"emp": ["empname"]} +column_values = {"empname": ["Shivnash Kumar", "Ragul Gupta"]} + + +def process_substring_query(query): + """ + Processes a substring query on a specified table and column. + + Parameters: + query (str): The substring query. + + Raises: + ValueError: Raises an error if the query format is invalid, the table name is not present, or the column is not present in the table. + """ + query = query.lower() + pattern = re.compile(r"select\s+substring\((\w+),(\d+),(\d+)\)\s+from\s+(\w+);") + matches = re.match(pattern, query) + + if not matches: + raise ValueError("Invalid query format.") + + columnName = matches.group(1) + startIndex = int(matches.group(2)) - 1 + length = int(matches.group(3)) + tableName = matches.group(4) + + if tableName not in tables: + raise ValueError("Invalid Table Name") + + if tableName not in table_column_map or columnName not in table_column_map[tableName]: + raise ValueError("Column is not present in the table.") + + for value in column_values[columnName]: + print(value[startIndex:startIndex + length]) + + +if __name__ == "__main__": + query_input = "select substring(empname,4,13) from emp;" + try: + process_substring_query(query_input) + except ValueError as e: + print(e) diff --git a/December 11/python3_lakshminarayanans_coderofconversions.py b/December 11/python3_lakshminarayanans_coderofconversions.py new file mode 100644 index 0000000..afdf7d5 --- /dev/null +++ b/December 11/python3_lakshminarayanans_coderofconversions.py @@ -0,0 +1,47 @@ +""" +Module documentation: Coder of Conversions + +This module defines a function decimal_to_binary to convert a decimal number to its binary representation. + +Usage: + val_set = (51, 12) + binary_representation = decimal_to_binary(val_set) + print("Output:") + print(binary_representation) +""" + + +def decimal_to_binary(val): + """ + Convert a decimal number to its binary representation. + + Parameters: + val (tuple): A tuple containing two decimal values. + + Returns: + str: The binary representation of the concatenated decimal values. + """ + decimal_number = val[0] + val[1] + + if decimal_number == 0: + return '0' # binary representation of 0 + + binary_digits = [] + while decimal_number > 0: + remainder = decimal_number % 2 + binary_digits.append(str(remainder)) + decimal_number //= 2 + + binary_representation = '' + for digit in binary_digits[::-1]: # Traverse the list in reverse order + binary_representation += digit + return binary_representation + + +if __name__ == "__main__": + # Example: Finding the binary representation of a number + val_set = (51, 12) + binary_representation = decimal_to_binary(val_set) + + print("Output:") + print(binary_representation) diff --git a/December 12/python3_lakshminarayanans_theheist.py b/December 12/python3_lakshminarayanans_theheist.py new file mode 100644 index 0000000..fa789ec --- /dev/null +++ b/December 12/python3_lakshminarayanans_theheist.py @@ -0,0 +1,68 @@ +""" +Module Documentation: The Heist + +This module provides a function to find the box containing "Gold" among a list of boxes. + +Functions: + - binary_search(box, target): Performs binary search on a sorted list to find the target. + - find_gold_box(boxes): Finds the box containing "Gold" among a list of boxes. + +Usage: + - Call find_gold_box(boxes) to find the box containing "Gold" and print the result. + +""" + + +def binary_search(box, target): + """ + Performs binary search on a sorted list to find the target. + + Parameters: + box (list): The sorted list to search. + target (str): The target value to find. + + Returns: + bool: True if the target is found, False otherwise. + """ + low, high = 0, len(box) - 1 + + while low <= high: + mid = low + (high - low) // 2 + + if box[mid] == target: + return True + elif box[mid] < target: + low = mid + 1 + else: + high = mid - 1 + + return False + + +def find_gold_box(boxes): + """ + Finds the box containing "Gold" among a list of boxes. + + Parameters: + boxes (list): List of boxes, where each box is represented as a list of items. + + Returns: + str: A string indicating the result, either the box containing "Gold" or a message indicating that "Gold" is not found in any box. + """ + for i, box in enumerate(boxes, 1): + box.sort() + if binary_search(box, "Gold"): + return f"Box{i} contains the Gold" + + return "Gold not found in any box" + + +if __name__ == "__main__": + # Example usage + boxes = [ + ["Emerald", "Ruby", "Bronze", "Silver"], + ["Gold", "Diamond", "Ruby", "Copper"], + ["Ruby", "Platinum", "Bronze", "Silver"] + ] + + print(find_gold_box(boxes)) diff --git a/December 13/python3_lakshminarayanans_callcipher.py b/December 13/python3_lakshminarayanans_callcipher.py new file mode 100644 index 0000000..f6fded9 --- /dev/null +++ b/December 13/python3_lakshminarayanans_callcipher.py @@ -0,0 +1,54 @@ +""" +Module documentation: Call Cipher + +This module defines a function textToNum to convert an alphanumeric phone number to its numeric representation. + +Usage: + output = textToNum("123-647-EYES") + print("Output:") + print(output) +""" + + +def textToNum(number_string): + """ + Convert an alphanumeric phone number to its numeric representation. + + Parameters: + number_string (str): The alphanumeric phone number. + + Returns: + str: The numeric representation of the phone number. + """ + phone_dictionary = { + 0: '', + 1: '', + 2: 'ABC', + 3: 'DEF', + 4: 'GHI', + 5: 'JKL', + 6: 'MNO', + 7: 'PQRS', + 8: 'TUV', + 9: 'WXYZ', + } + + final_string = number_string.upper() # Convert to uppercase for case insensitivity + new_string_list = [] + + for char in final_string: + if char.isalpha(): # Check if the character is alphabetic + for digit, letters in phone_dictionary.items(): + if char in letters: + new_string_list.append(str(digit)) + else: + new_string_list.append(char) + + return ''.join(new_string_list) + + +if __name__ == "__main__": + # Example usage + output = textToNum("123-647-EYES") + print("Output:") + print(output) diff --git a/December 14/python3_lakshminarayanans_callofjustice.py b/December 14/python3_lakshminarayanans_callofjustice.py new file mode 100644 index 0000000..43f970b --- /dev/null +++ b/December 14/python3_lakshminarayanans_callofjustice.py @@ -0,0 +1,168 @@ +""" +Module Documentation: Call of Justice + +This module defines a binary tree structure and a solution class to find k-distance nodes from a given target node. + +Classes: + - TreeNode: Represents a node in a binary tree. + - Solution: Provides a solution to find k-distance nodes in a binary tree. + +Functions: + - build_tree(s): Builds a binary tree from the given string representation. + - k_distance_nodes(root, target, k): Finds k-distance nodes from a target node in a binary tree. + +Usage: + - Create an instance of Solution. + - Parse the input and build the binary tree using build_tree. + - Call the k_distance_nodes method with the root of the tree, target node value, and k-distance. + - Print the result. + +""" + +from collections import deque + + +class TreeNode: + def __init__(self, value): + """ + Represents a node in a binary tree. + + Parameters: + value (int): The value of the node. + """ + self.data = value + self.left = None + self.right = None + + +def build_tree(s): + """ + Builds a binary tree from the given string representation. + + Parameters: + s (str): The string representation of the binary tree. + + Returns: + TreeNode: The root of the built binary tree. + """ + if len(s) == 0 or s[0] == 'N': + return None + + ip = s.split() + root = TreeNode(int(ip[0])) + queue = deque([root]) + i = 1 + + while queue and i < len(ip): + curr_node = queue.popleft() + + curr_val = ip[i] + if curr_val != "N": + curr_node.left = TreeNode(int(curr_val)) + queue.append(curr_node.left) + + i += 1 + if i >= len(ip): + break + + curr_val = ip[i] + if curr_val != "N": + curr_node.right = TreeNode(int(curr_val)) + queue.append(curr_node.right) + + i += 1 + + return root + + +class Solution: + def __init__(self): + """ + Provides a solution to find k-distance nodes in a binary tree. + """ + self.nodes = [] + + def k_distance_nodes_down(self, root, k): + """ + Helper function to find k-distance nodes down the tree from a given node. + + Parameters: + root (TreeNode): The current node in the tree. + k (int): The distance from the original target node. + + Returns: + None + """ + if root is None: + return + if k == 0: + self.nodes.append(root.data) + return + self.k_distance_nodes_down(root.left, k - 1) + self.k_distance_nodes_down(root.right, k - 1) + + def helper(self, root, target, k): + """ + Recursive helper function to find k-distance nodes. + + Parameters: + root (TreeNode): The current node in the tree. + target (int): The value of the target node. + k (int): The distance from the target node. + + Returns: + int: The distance from the target node to the current node. + """ + if root is None: + return -1 + if root.data == target: + self.k_distance_nodes_down(root, k) + return 0 + dl = self.helper(root.left, target, k) + if dl != -1: + if dl + 1 == k: + self.nodes.append(root.data) + else: + self.k_distance_nodes_down(root.right, k - dl - 2) + return 1 + dl + dr = self.helper(root.right, target, k) + if dr != -1: + if dr + 1 == k: + self.nodes.append(root.data) + else: + self.k_distance_nodes_down(root.left, k - dr - 2) + return 1 + dr + return -1 + + def k_distance_nodes(self, root, target, k): + """ + Finds k-distance nodes from a target node in a binary tree. + + Parameters: + root (TreeNode): The root of the binary tree. + target (int): The value of the target node. + k (int): The distance from the target node. + + Returns: + list: A list of k-distance nodes sorted in ascending order. + """ + self.nodes.clear() + self.helper(root, target, k) + self.nodes.sort() + return self.nodes + + +# Example usage +if __name__ == "__main__": + t = int(input()) + x = Solution() + + for _ in range(t): + s = input() + head = build_tree(s) + + target, k = map(int, input().split()) + + res = x.k_distance_nodes(head, target, k) + + print(*res) diff --git a/December 15/python3_lakshminarayanans_subsequencesorcery.py b/December 15/python3_lakshminarayanans_subsequencesorcery.py new file mode 100644 index 0000000..27c730b --- /dev/null +++ b/December 15/python3_lakshminarayanans_subsequencesorcery.py @@ -0,0 +1,52 @@ +""" +Module documentation: Subsequence Sorcery + +This module defines a function countDistinctSubsequences to count the number of distinct subsequences in a given string. + +Usage: + input_str1 = "ghg" + output1 = countDistinctSubsequences(input_str1) + print("Output 1:", output1) + + input_str2 = "ice" + output2 = countDistinctSubsequences(input_str2) + print("Output 2:", output2) +""" + +def countDistinctSubsequences(s): + """ + Count the number of distinct subsequences in a given string. + + Parameters: + s (str): The input string. + + Returns: + int: The number of distinct subsequences. + """ + mod = 10 ** 9 + 7 + n = len(s) + + dp = [0] * (n + 1) + dp[0] = 1 + + last_occurrence = {} + + for i in range(1, n + 1): + dp[i] = (2 * dp[i - 1]) % mod + + if s[i - 1] in last_occurrence: + dp[i] = (dp[i] - dp[last_occurrence[s[i - 1]] - 1] + mod) % mod + + last_occurrence[s[i - 1]] = i + + return dp[n] + +if __name__ == "__main__": + # Example usage + input_str1 = "ghg" + output1 = countDistinctSubsequences(input_str1) + print("Output 1:", output1) + + input_str2 = "ice" + output2 = countDistinctSubsequences(input_str2) + print("Output 2:", output2) diff --git a/December 16/python3_lakshminarayanans_outbreakdynamics.py b/December 16/python3_lakshminarayanans_outbreakdynamics.py new file mode 100644 index 0000000..39b0f44 --- /dev/null +++ b/December 16/python3_lakshminarayanans_outbreakdynamics.py @@ -0,0 +1,93 @@ +""" +Module Documentation: Outbreak Dynamics + +This module defines a function to calculate the time required for a contagion to spread in a grid. + +Functions: + - check(x, y, m, n): Checks if the coordinates (x, y) are within the grid bounds (m x n). + - calculate_time(grid): Calculates the time required for contagion to spread in the grid. + +Usage: + - Call the calculate_time function with a 2D grid representing the contagion spread. + - Print or use the returned value as needed. + +""" + +from collections import deque + + +def check(x, y, m, n): + """ + Checks if the coordinates (x, y) are within the grid bounds (m x n). + + Parameters: + x (int): The x-coordinate. + y (int): The y-coordinate. + m (int): The number of rows in the grid. + n (int): The number of columns in the grid. + + Returns: + bool: True if coordinates are within bounds, False otherwise. + """ + return 0 <= x < m and 0 <= y < n + + +def calculate_time(grid): + """ + Calculates the time required for contagion to spread in the grid. + + Parameters: + grid (list[list[int]]): A 2D grid representing the contagion spread. + - 1 indicates an infected cell, + - 0 indicates a healthy cell, + - -1 indicates an obstacle. + + Returns: + int: The time required for contagion to spread. Returns -1 if not all cells can be infected. + """ + time = 0 + m, n = len(grid), len(grid[0]) + q = deque() + + for i in range(m): + for j in range(n): + if grid[i][j] == 1: + q.append((i, j)) + + cur_queue_size, next_queue_size = len(q), 0 + + while q: + for _ in range(cur_queue_size): + x, y = q.popleft() + + for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]: + new_x, new_y = x + dx, y + dy + if check(new_x, new_y, m, n) and grid[new_x][new_y] == 0: + q.append((new_x, new_y)) + next_queue_size += 1 + grid[new_x][new_y] = 1 + + if next_queue_size == 0: + break + + cur_queue_size = next_queue_size + next_queue_size = 0 + time += 1 + + for i in range(m): + for j in range(n): + if grid[i][j] == 0: + return -1 + + return time + + +if __name__ == "__main__": + grid = [ + [1, 0, 1, 1, 0], + [0, 0, 0, 1, 1], + [1, 0, 1, 1, 1], + [1, 0, -1, 0, 0], + [1, 1, 0, 0, 1] + ] + print(calculate_time(grid)) diff --git a/December 17/python3_lakshminarayanans_bookshelfdilemma.py b/December 17/python3_lakshminarayanans_bookshelfdilemma.py new file mode 100644 index 0000000..c9f5c00 --- /dev/null +++ b/December 17/python3_lakshminarayanans_bookshelfdilemma.py @@ -0,0 +1,78 @@ +class Node: + def __init__(self, val): + self.data = val + self.next = None + + +def loopHere(head, tail, position): + if position == 0: + return + walk = head + for i in range(1, position): + walk = walk.next + tail.next = walk + + +def isLoop(head): + if not head: + return False + fast = head.next + slow = head + while fast != slow: + if not fast or not fast.next: + return False + fast = fast.next.next + slow = slow.next + return True + + +def length(head): + ret = 0 + while head: + ret += 1 + head = head.next + return ret + + +def removeLoop(head): + myMap = {} + while head: + if head in myMap: + myMap[head].next = None + break + myMap[head] = head + head = head.next + + +def create_linked_list(values): + if not values: + return None + head = Node(values[0]) + current = head + for val in values[1:]: + current.next = Node(val) + current = current.next + return head + + +def print_linked_list(head): + current = head + while current: + print(current.data, end=" ") + current = current.next + print() + + +if __name__ == "__main__": + elements = [1, 2, 3, 4, 5, 6, 7, 8, 1] + head = create_linked_list(elements) + tail = head + while tail.next: + tail = tail.next + + loop_position = 3 + + removeLoop(head) + + print("Linked List after removing Loop:") + print_linked_list(head) diff --git a/December 18/python3_lakshminarayanans_itschristmasseason.py b/December 18/python3_lakshminarayanans_itschristmasseason.py new file mode 100644 index 0000000..ab1baac --- /dev/null +++ b/December 18/python3_lakshminarayanans_itschristmasseason.py @@ -0,0 +1,95 @@ +""" +Module Documentation: It's Chirstmas Season + +This module defines functions for counting subtrees with a given property in a tree. + +Functions: + - dfs(src, par, edges, arr): Performs depth-first search to calculate the subtree sums. + - nCr(n, r): Calculates the binomial coefficient "n choose r" using logarithmic formula. + - main(): Main function to handle input, perform calculations, and print results. + +Usage: + - Run the main function to execute the counting subtrees algorithm. + - Input is taken from standard input. + - Results are printed to standard output. + +""" + +from math import log, exp + + +def dfs(src, par, edges, arr): + """ + Performs depth-first search to calculate the subtree sums. + + Parameters: + src (int): Current source node. + par (int): Parent node of the current source node. + edges (list[list[int]]): List representing the edges in the tree. + arr (list[int]): List representing the subtree sums. + + Returns: + None + """ + for ch in edges[src]: + if ch == par: + continue + dfs(ch, src, edges, arr) + arr[src] += arr[ch] + + +def nCr(n, r): + """ + Calculates the binomial coefficient "n choose r" using logarithmic formula. + + Parameters: + n (int): Total number of elements. + r (int): Number of elements to choose. + + Returns: + int: The binomial coefficient value. + """ + if r > n: + return 0 + + if r == 0 or n == r: + return 1 + + res = 0 + for i in range(r): + res += log(n - i) - log(i + 1) + return round(exp(res)) + + +def main(): + """ + Main function to handle input, perform calculations, and print results. + + Returns: + None + """ + t = int(input()) + for _ in range(t): + n, x = map(int, input().split()) + arr = [0] + list(map(int, input().split())) + edges = [[] for _ in range(n + 1)] + + for _ in range(n - 1): + u, v = map(int, input().split()) + edges[u].append(v) + edges[v].append(u) + + dfs(1, -1, edges, arr) + + if arr[1] % x != 0: + print(" ".join(["0"] * n)) + continue + + ct = sum(1 for i in range(2, n + 1) if arr[i] % x == 0) + + result = " ".join(str(nCr(ct, i - 1)) for i in range(1, n + 1)) + print(result) + + +if __name__ == "__main__": + main() diff --git a/December 19/python3_lakshminarayanans_symbolicsum.py b/December 19/python3_lakshminarayanans_symbolicsum.py new file mode 100644 index 0000000..e279bcc --- /dev/null +++ b/December 19/python3_lakshminarayanans_symbolicsum.py @@ -0,0 +1,57 @@ +""" +Module Documentation: Symbolic Sum + +This module defines functions for calculating the symbolic sum of a sequence. + +Functions: + - sum_subsequence(sequence, start, end): Calculates the sum of a subsequence within the given range. + - symbolic_sum(sequence): Calculates the symbolic sum of the entire sequence. + +Usage: + - Run the main block to execute the symbolic sum calculation. + - The result is printed to standard output. + +""" + +def sum_subsequence(sequence, start, end): + """ + Calculates the sum of a subsequence within the given range. + + Parameters: + sequence (list[str]): List of strings representing the sequence. + start (int): Starting index of the subsequence. + end (int): Ending index of the subsequence. + + Returns: + int: The sum of the subsequence. + """ + return sum(int(x) for x in sequence[start:end + 1] if x.isdigit()) + + +def symbolic_sum(sequence): + """ + Calculates the symbolic sum of the entire sequence. + + Parameters: + sequence (list[str]): List of strings representing the sequence. + + Returns: + int: The symbolic sum of the sequence. + """ + result = 0 + n = len(sequence) + for i in range(n): + if sequence[i][0] == 'X': + multiplier = 1 + if len(sequence[i]) > 1: + multiplier = int(sequence[i][1:]) + subsum = sum_subsequence(sequence, i, n - 1) + result += multiplier * subsum + return result + + +if __name__ == "__main__": + # Example usage + sequence = ["X3", "3", "X2", "2", "X1", "1", "4"] + result = symbolic_sum(sequence) + print(result) diff --git a/December 20/python3_lakshminarayanans_treasurehuntintheisles.py b/December 20/python3_lakshminarayanans_treasurehuntintheisles.py new file mode 100644 index 0000000..c725cdf --- /dev/null +++ b/December 20/python3_lakshminarayanans_treasurehuntintheisles.py @@ -0,0 +1,97 @@ +""" +Module Documentation: Treasure Hunt In The Isles + +This module implements Dijkstra's shortest path algorithm to find the shortest path +from a starting cave to an ending cave in a graph. + +Functions: + - min_dist(distances, spt_set): Helper function to find the node with the minimum distance. + - dijkstra(graph, distances, prev_node, spt_set): Dijkstra's algorithm for finding the shortest path. + - print_path(prev_node, end_cave): Helper function to print the path from start to end. + +Usage: + - Define the graph with weights between caves. + - Specify the starting and ending caves. + - Run the script to find and print the shortest path. + +""" + +import sys + + +def min_dist(distances, spt_set): + """ + Helper function to find the node with the minimum distance. + + Parameters: + distances (dict): Dictionary containing distances from the start node. + spt_set (set): Set containing nodes already processed. + + Returns: + str: Node with the minimum distance. + """ + u = None + min_value = sys.maxsize + for node, dist in distances.items(): + if dist < min_value and node not in spt_set: + u = node + min_value = dist + return u + + +def dijkstra(graph, distances, prev_node, spt_set): + """ + Dijkstra's algorithm for finding the shortest path. + + Parameters: + graph (dict): Graph representation with weights. + distances (dict): Dictionary containing distances from the start node. + prev_node (dict): Dictionary containing the previous node in the shortest path. + spt_set (set): Set containing nodes already processed. + """ + n = len(graph) + for _ in range(n - 1): + u = min_dist(distances, spt_set) + spt_set.add(u) + for neighbor, weight in graph[u].items(): + if neighbor not in spt_set and (distances[u] + weight < distances[neighbor]): + distances[neighbor] = distances[u] + weight + prev_node[neighbor] = u + + +def print_path(prev_node, end_cave): + """ + Helper function to print the path from start to end. + + Parameters: + prev_node (dict): Dictionary containing the previous node in the shortest path. + end_cave (str): Ending node for the path. + """ + if end_cave is None: + return + prev_cave = prev_node[end_cave] + print_path(prev_node, prev_cave) + print(end_cave, end=" ") + + +if __name__ == "__main__": + # Example usage + graph = { + "Cave_A": {"Cave_B": 3, "Cave_C": 7}, + "Cave_B": {"Cave_D": 7, "Cave_E": 1}, + "Cave_C": {"Cave_D": 3}, + "Cave_D": {"Cave_E": 5}, + "Cave_E": {} + } + start_cave = "Cave_A" + end_cave = "Cave_E" + n = len(graph) + + spt_set = set() + distances = {node: sys.maxsize for node in graph} + prev_node = {node: None for node in graph} + distances[start_cave] = 0 + dijkstra(graph, distances, prev_node, spt_set) + + print_path(prev_node, end_cave) + print() diff --git a/December 21/python3_lakshminarayanans_riddlemethis.py b/December 21/python3_lakshminarayanans_riddlemethis.py new file mode 100644 index 0000000..f6b7ac3 --- /dev/null +++ b/December 21/python3_lakshminarayanans_riddlemethis.py @@ -0,0 +1,58 @@ +""" +Module documentation: Riddle Me This + +This module defines functions for decrypting a Caesar cipher and finding the original message. + +Functions: + - decrypt_caesar_cipher(ciphertext, shift): Decrypts a Caesar cipher. + - find_bomb_location(code, shift): Finds the original message by trying different shifts. + +Usage: + - Enter the code and shift when prompted to find the decrypted message. +""" + + +def decrypt_caesar_cipher(ciphertext, shift): + """ + Decrypt a Caesar cipher. + + Parameters: + ciphertext (str): The encrypted message. + shift (int): The number of positions to shift the characters. + + Returns: + str: The decrypted message. + """ + decrypted_text = "" + for char in ciphertext: + if char.isalpha(): + if char.islower(): + decrypted_text += chr((ord(char) - shift - ord('a') + 26) % 26 + ord('a')) + else: + decrypted_text += chr((ord(char) - shift - ord('A') + 26) % 26 + ord('A')) + else: + decrypted_text += char + return decrypted_text + + +def find_bomb_location(code, shift): + """ + Find the original message by trying different shifts. + + Parameters: + code (str): The encrypted message. + shift (int): The maximum number of positions to try for decryption. + + Returns: + decrypted_message (str): The decrypted message. + """ + for s in range(shift+1): + decrypted_message = decrypt_caesar_cipher(code, s) + return decrypted_message + + +if __name__ == "__main__": + code = input("Enter code: ").upper() + shift = int(input("Enter shift: ")) + message = find_bomb_location(code, shift) + print(f"The Bomb location is: {message} - Shift {shift}") diff --git a/December 22/python3_lakshminarayanans_rottenoranges.py b/December 22/python3_lakshminarayanans_rottenoranges.py new file mode 100644 index 0000000..87406fe --- /dev/null +++ b/December 22/python3_lakshminarayanans_rottenoranges.py @@ -0,0 +1,64 @@ +""" +Module documentation: Rotting Oranges + +This module defines a function for calculating the time it takes for all oranges to rot in a given grid. + +Functions: + - rotting_time(grid): Calculates the time it takes for all oranges to rot in the grid. + +Usage: + - Define a grid with values representing the state of each cell (0 for empty, 1 for fresh orange, 2 for rotten orange). + - Call the rotting_time function with the grid to get the time it takes for all oranges to rot. +""" + +from collections import deque + + +def rotting_time(grid): + """ + Calculates the time it takes for all oranges to rot in the given grid. + + Parameters: + grid (list): A 2D grid representing the state of oranges (0 for empty, 1 for fresh orange, 2 for rotten orange). + + Returns: + int: The time it takes for all oranges to rot. Returns -1 if it's not possible for all oranges to rot. + """ + rows, cols = len(grid), len(grid[0]) + directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # Up, Down, Left, Right + + queue = deque() + for i in range(rows): + for j in range(cols): + if grid[i][j] == 2: + queue.append((i, j, 0)) + + def is_valid(x, y): + return 0 <= x < rows and 0 <= y < cols + + time = 0 + while queue: + i, j, time = queue.popleft() + for dx, dy in directions: + ni, nj = i + dx, j + dy + if is_valid(ni, nj) and grid[ni][nj] == 1: + grid[ni][nj] = 2 + queue.append((ni, nj, time + 1)) + + for i in range(rows): + for j in range(cols): + if grid[i][j] == 1: + return -1 + + return time + + +# Example usage: +grid1 = [[0, 1, 2], [0, 1, 2], [2, 1, 1]] +grid2 = [[2, 2, 0, 1]] + +output1 = rotting_time(grid1) +output2 = rotting_time(grid2) + +print("Output 1:", output1) +print("Output 2:", output2) diff --git a/December 23/python3_lakshminarayanans_dominoes.py b/December 23/python3_lakshminarayanans_dominoes.py new file mode 100644 index 0000000..026e41f --- /dev/null +++ b/December 23/python3_lakshminarayanans_dominoes.py @@ -0,0 +1,53 @@ +""" +Module documentation: Dominoes + +This module defines a function for calculating the minimum rotations needed to achieve even sums for dominoes. + +Functions: + - min_rotations_for_even_sums(n, dominoes): Calculates the minimum rotations needed to achieve even sums for dominoes. + +Usage: + - Provide the number of dominoes 'n' and a list of dominoes 'dominoes' with their values. + - Call the min_rotations_for_even_sums function to get the minimum rotations needed for even sums. +""" + + +def min_rotations_for_even_sums(n, dominoes): + """ + Calculates the minimum rotations needed to achieve even sums for dominoes. + + Parameters: + n (int): The number of dominoes. + dominoes (list): A list of tuples representing the values of dominoes. + + Returns: + int: The minimum rotations needed to achieve even sums. Returns 0 if even sums are already achieved, + 1 for one rotation needed, and -1 if it's not possible to achieve even sums. + """ + upper_sum = sum(domino[0] for domino in dominoes) + lower_sum = sum(domino[1] for domino in dominoes) + + if upper_sum % 2 == 0 and lower_sum % 2 == 0: + return 0 # No rotations needed + + if upper_sum % 2 == 1 and lower_sum % 2 == 1: + for i in range(n): + if dominoes[i][0] % 2 != dominoes[i][1] % 2: + return 1 # One rotation needed + return -1 # Not possible to achieve even sums + + return -1 # Not possible to achieve even sums + + +# Example usage: +n1 = 2 +dominoes1 = [(4, 2), (6, 4)] + +n2 = 1 +dominoes2 = [(2, 3)] + +output1 = min_rotations_for_even_sums(n1, dominoes1) +output2 = min_rotations_for_even_sums(n2, dominoes2) + +print("Output 1:", output1) +print("Output 2:", output2) diff --git a/December 24/python3_lakshminarayanans_goldenruleviolation.py b/December 24/python3_lakshminarayanans_goldenruleviolation.py new file mode 100644 index 0000000..7181c8d --- /dev/null +++ b/December 24/python3_lakshminarayanans_goldenruleviolation.py @@ -0,0 +1,45 @@ +""" +Module documentation: Golden Rule Violation + +This module defines a function for counting violations in a list of numbers. + +Functions: + - count_violations(n, numbers): Counts the number of violations in the given list of numbers. + +Usage: + - Provide the number of elements 'n' and a list of 'numbers'. + - Call the count_violations function to get the count of violations in the list. +""" + +def count_violations(n, numbers): + """ + Counts the number of violations in the given list of numbers. + + Parameters: + n (int): The number of elements in the list. + numbers (list): A list of numbers. + + Returns: + int: The count of violations in the list. + """ + violations = 0 + + for i in range(n - 1): + for j in range(i + 1, n): + if numbers[i] > numbers[j]: + violations += 1 + + return violations + +# Example usage: +n1 = 5 +numbers1 = [4, 5, 6, 7, 1] + +n2 = 5 +numbers2 = [5, 4, 3, 2, 1] + +output1 = count_violations(n1, numbers1) +output2 = count_violations(n2, numbers2) + +print("Output 1:", output1) +print("Output 2:", output2) diff --git a/December 25/python3_lakshminarayanans_harmonyhurdle.py b/December 25/python3_lakshminarayanans_harmonyhurdle.py new file mode 100644 index 0000000..71f8981 --- /dev/null +++ b/December 25/python3_lakshminarayanans_harmonyhurdle.py @@ -0,0 +1,74 @@ +""" +Module documentation: Harmony Hurdle + +This module defines a function to calculate the minimum time required to complete a set of tasks with dependencies. + +Functions: + - min_time_to_complete_tasks(tasks, dependencies): Calculates the minimum time to complete tasks with dependencies. + +Usage: + - Provide the list of 'tasks' and their 'dependencies'. + - Call the min_time_to_complete_tasks function to get the minimum time required for completion. +""" + +from collections import defaultdict, deque + + +def min_time_to_complete_tasks(tasks, dependencies): + """ + Calculates the minimum time required to complete tasks with dependencies. + + Parameters: + tasks (list): A list of tasks. + dependencies (list): A list of dependencies where each element is a list representing dependencies of a task. + + Returns: + int: The minimum time required to complete the tasks. + """ + graph = defaultdict(list) + in_degrees = defaultdict(int) + + for i in range(len(tasks)): + in_degrees[tasks[i]] = 0 + + for i in range(len(dependencies)): + for j in range(1, len(dependencies[i])): + graph[dependencies[i][j]].append(dependencies[i][0]) + in_degrees[dependencies[i][0]] += 1 + + # Topological Sorting using Kahn's algorithm + order = [] + queue = deque() + + for task in tasks: + if in_degrees[task] == 0: + queue.append(task) + + while queue: + current_task = queue.popleft() + order.append(current_task) + + for dependent_task in graph[current_task]: + in_degrees[dependent_task] -= 1 + if in_degrees[dependent_task] == 0: + queue.append(dependent_task) + + completion_time = {task: 0 for task in tasks} + + for task in order: + completion_time[task] = max(completion_time[task], sum(dependencies[tasks.index(task)]) + 1) + + return max(completion_time.values()) + + +# Example usage: +tasks1 = [1, 2, 3, 4, 5] +dependencies1 = [[], [1], [2], [3], [4, 1]] + +tasks2 = [1, 2, 3, 4, 5] +dependencies2 = [[], [1], [2], [3], [4]] +output1 = min_time_to_complete_tasks(tasks1, dependencies1) +output2 = min_time_to_complete_tasks(tasks2, dependencies2) + +print("Output 1:", output1) +print("Output 2:", output2) diff --git a/December 26/python3_lakshminarayanans_phantomcycle.py b/December 26/python3_lakshminarayanans_phantomcycle.py new file mode 100644 index 0000000..e659b6d --- /dev/null +++ b/December 26/python3_lakshminarayanans_phantomcycle.py @@ -0,0 +1,89 @@ +""" +Module documentation: Phantom Cycle + +This module defines a ListNode class and two functions to create a linked list and check for the presence of a cycle. + +Classes: + - ListNode: Represents a node in a linked list. + +Functions: + - create_linked_list(): Creates a linked list from user-input space-separated values. + - has_cycle(head): Checks if a linked list has a cycle. + +Usage: + - Call create_linked_list() to create a linked list. + - Call has_cycle(head) to check if the linked list has a cycle. +""" + +class ListNode: + """ + Represents a node in a linked list. + + Attributes: + value: The value of the node. + next: Reference to the next node in the linked list. + """ + + def __init__(self, value): + self.value = value + self.next = None + + +def create_linked_list(): + """ + Creates a linked list from user-input space-separated values. + + Returns: + ListNode: The head of the linked list. + """ + values = input("Enter space-separated values for the linked list: ").split() + if not values: + return None + + head = ListNode(int(values[0])) + current = head + + for value in values[1:]: + current.next = ListNode(int(value)) + current = current.next + return head + + +def has_cycle(head): + """ + Checks if a linked list has a cycle. + + Parameters: + head (ListNode): The head of the linked list. + + Returns: + bool: True if a cycle is found, False otherwise. + """ + if not head or not head.next: + return False + + slow = head + fast = head.next + + while slow and slow.next.next: + while fast: + if slow.value == fast.value: + return True + fast = fast.next + fast = slow.next.next + slow = slow.next + + return False # No cycle found + + +# Example usage: +head = create_linked_list() +print("Linked List 1:") +current = head +while current: + print(current.value, end=" -> ") + current = current.next +print("None") + +output = has_cycle(head) +print("Output:", "Cycle Found" if output else "No Cycle Found") diff --git a/December 27/python3_lakshminarayanans_circleofendurance.py b/December 27/python3_lakshminarayanans_circleofendurance.py new file mode 100644 index 0000000..0c3b60f --- /dev/null +++ b/December 27/python3_lakshminarayanans_circleofendurance.py @@ -0,0 +1,55 @@ +""" +Module documentation: Circle of Endurance + +This module defines a function to find the starting point for a circular tour given the petrol and distance arrays. + +Functions: + - find_starting_point(N, petrol, distance): Finds the starting point for a circular tour. + +Usage: + - Call find_starting_point(N, petrol, distance) to get the starting point for a circular tour. +""" + + +def find_starting_point(N, petrol, distance): + """ + Finds the starting point for a circular tour. + + Parameters: + N (int): Number of petrol pumps. + petrol (list): List of petrol available at each pump. + distance (list): List of distances to the next pump. + + Returns: + int: The index of the starting petrol pump if possible, -1 otherwise. + """ + start = 0 + end = 1 + curr_petrol = petrol[start] - distance[start] + + while start != end or curr_petrol < 0: + + while curr_petrol < 0 and start != end: + curr_petrol -= petrol[start] - distance[start] + start = (start + 1) % N + + if start == 0: + return -1 + + curr_petrol += petrol[end] - distance[end] + end = (end + 1) % N + + if curr_petrol >= 0: + return start + 1 + else: + return -1 + + +# Example usage: +N = 4 +petrol = [4, 6, 7, 4] +distance = [6, 5, 3, 5] + +output = find_starting_point(N, petrol, distance) + +print("Output:", output) diff --git a/December 28/python3_lakshminarayanans_thesellinggame.py b/December 28/python3_lakshminarayanans_thesellinggame.py new file mode 100644 index 0000000..99c0c2d --- /dev/null +++ b/December 28/python3_lakshminarayanans_thesellinggame.py @@ -0,0 +1,61 @@ +""" +Module documentation: The Selling Game + +This module defines a function to calculate the maximum number of gadgets that can be sold based on certain criteria. + +Functions: + - max_gadgets_sold(x, z, items, clients): Calculates the maximum number of gadgets that can be sold. + +Usage: + - Call max_gadgets_sold(x, z, items, clients) to get the maximum number of gadgets that can be sold. +""" + + +def max_gadgets_sold(x, z, items, clients): + """ + Calculates the maximum number of gadgets that can be sold. + + Parameters: + x (int): Placeholder parameter x. + z (int): Placeholder parameter z. + items (list): List of items with specified criteria. + clients (list): List of clients with specified criteria. + + Returns: + int: The maximum number of gadgets that can be sold. + """ + # Sort items and clients in descending order based on their criteria + sorted_items = sorted(items, key=lambda item: item['m'], reverse=True) + sorted_clients = sorted(clients, key=lambda client: client['k'], reverse=True) + + gadgets_sold = 0 + assigned_clients = set() + + for item in sorted_items: + for i, client in enumerate(sorted_clients): + if i not in assigned_clients and client['k'] < item['m'] and client['r'] >= item['n']: + gadgets_sold += 1 + assigned_clients.add(i) + break + + return gadgets_sold + + +# Example usage: +x, z = 4, 4 +items = [ + {'k': 8, 'r': 150, 'm': 10, 'n': 160}, + {'k': 5, 'r': 180, 'm': 12, 'n': 200}, + {'k': 20, 'r': 250, 'm': 15, 'n': 300}, + {'k': 15, 'r': 300, 'm': 18, 'n': 250} +] +clients = [ + {'k': 6, 'r': 200}, + {'k': 14, 'r': 280}, + {'k': 8, 'r': 220}, + {'k': 25, 'r': 350} +] + +output = max_gadgets_sold(x, z, items, clients) + +print("Output:", output) diff --git a/December 29/python3_lakshminarayanans_cartesianwalkvalidator.py b/December 29/python3_lakshminarayanans_cartesianwalkvalidator.py new file mode 100644 index 0000000..3d4f81f --- /dev/null +++ b/December 29/python3_lakshminarayanans_cartesianwalkvalidator.py @@ -0,0 +1,63 @@ +""" +Module documentation: Cartesian Walk Validator + +This module defines functions to analyze walking directions. + +Functions: + - count_directions(walk): Counts the number of steps for each unique direction in the walk. + - is_valid_walk(walk): Checks if the walk is valid based on certain criteria. + +Usage: + - Call count_directions(walk) to get the count of steps for each unique direction. + - Call is_valid_walk(walk) to check if the walk is valid. +""" + + +def count_directions(walk): + """ + Counts the number of steps for each unique direction in the walk. + + Parameters: + walk (list): List of directions representing the walk. + + Returns: + list: List of dictionaries containing the count of steps for each unique direction. + """ + direction_counts = [] + + unique_directions = set(walk) + + for direction in unique_directions: + count = walk.count(direction) + direction_counts.append({direction: count}) + + return direction_counts + + +def is_valid_walk(walk): + """ + Checks if the walk is valid based on certain criteria. + + Parameters: + walk (list): List of directions representing the walk. + + Returns: + bool: True if the walk is valid, False otherwise. + """ + if len(walk) != 10: + return False + + direction_counts = count_directions(walk) + + if len(direction_counts) > 1: + count_1 = list(direction_counts[0].values())[0] + count_2 = list(direction_counts[1].values())[0] + return count_1 == count_2 + return False + + +walk_input = input("Enter the walk sequence as a string of directions (e.g., 'n s n s n s n s'): ").lower().split(" ") +output = is_valid_walk(walk_input) + +# Display the result +print("Output: ", output) diff --git a/December 30/python3_lakshminarayanans_treeinversions.py b/December 30/python3_lakshminarayanans_treeinversions.py new file mode 100644 index 0000000..71ac20b --- /dev/null +++ b/December 30/python3_lakshminarayanans_treeinversions.py @@ -0,0 +1,155 @@ +""" +Module documentation: Tree Inversions + +This module provides a solution for processing shortest path queries on a tree and calculating inversion counts. + +Functions: + - shortest_path(n, tree, start, end): Finds the shortest path between two nodes in a tree. + - merge(left, mid, right, arr): Merges two sorted halves of an array during merge sort and counts inversions. + - merge_sort(left, right, arr): Implements the merge sort algorithm to count inversions. + - main(): Reads input from the user and performs shortest path queries with inversion counts. + +Usage: + - Call shortest_path(n, tree, start, end) to find the shortest path between two nodes in a tree. + - Call merge_sort(left, right, arr) to perform merge sort on a specified portion of an array and count inversions. + - Call main() to run the program and input the number of test cases, tree information, and queries. + +""" + +from io import StringIO +import sys + +inversions = 0 # Global variable to store inversion counts + + +def shortest_path(n, tree, start, end): + """ + Finds the shortest path between two nodes in a tree. + + Parameters: + n (int): The number of nodes in the tree. + tree (dict): The tree represented as an adjacency list. + start (int): The starting node. + end (int): The ending node. + + Returns: + list: The shortest path as a list of nodes. + """ + distance = [-1] * (n + 1) + parent = [-1] * (n + 1) + + queue = [start] + distance[start] = 0 + + while queue: + current = queue.pop(0) + + for neighbor in tree[current]: + if distance[neighbor] == -1: + distance[neighbor] = distance[current] + 1 + parent[neighbor] = current + queue.append(neighbor) + + path = [] + current = end + + while current != start: + path.append(current) + current = parent[current] + + path.append(start) + path.reverse() + + return path + + +def merge(left, mid, right, arr): + """ + Merges two sorted halves of an array during merge sort and counts inversions. + + Parameters: + left (int): The left index of the array. + mid (int): The middle index of the array. + right (int): The right index of the array. + arr (list): The array to be merged and sorted. + """ + i, j, n = left, mid + 1, right - left + 1 + merged = [] + + while i <= mid and j <= right: + if arr[i] <= arr[j]: + merged.append(arr[i]) + i += 1 + else: + merged.append(arr[j]) + global inversions + inversions += (mid - i + 1) + j += 1 + + while i <= mid: + merged.append(arr[i]) + i += 1 + + while j <= right: + merged.append(arr[j]) + j += 1 + + for p in range(n): + arr[left + p] = merged[p] + + +def merge_sort(left, right, arr): + """ + Implements the merge sort algorithm to count inversions. + + Parameters: + left (int): The left index of the array. + right (int): The right index of the array. + arr (list): The array to be sorted. + """ + if left >= right: + return + mid = (left + right) // 2 + merge_sort(left, mid, arr) + merge_sort(mid + 1, right, arr) + merge(left, mid, right, arr) + + +def main(): + """ + Reads input from the user and performs shortest path queries with inversion counts. + """ + t = int(input()) + for _ in range(t): + n, q = map(int, input().split()) + color = [0] + list(map(int, input().split())) + + tree = {i: [] for i in range(1, n + 1)} + for _ in range(n - 1): + x, y = map(int, input().split()) + tree[x].append(y) + tree[y].append(x) + + for _ in range(q): + x, y = map(int, input().split()) + path = shortest_path(n, tree, x, y) + query_path = [color[node] for node in path] + + query_path_reverse = query_path[::-1] + + global inversions + inversions = 0 + merge_sort(0, len(path) - 1, query_path) + f = inversions + + inversions = 0 + merge_sort(0, len(path) - 1, query_path_reverse) + f += inversions + + print(f) + + +if __name__ == "__main__": + input_str = "1\n8 7\n1 2 3 1 2 1 3 1\n1 2\n1 3\n2 4\n3 5\n3 6\n5 7\n6 8\n4 6\n7 8\n5 4\n7 6\n3 8\n1 2\n4 8\n" + sys.stdin = StringIO(input_str) + main() diff --git a/December 31/python3_lakshminarayanans_nqueens.py b/December 31/python3_lakshminarayanans_nqueens.py new file mode 100644 index 0000000..dd82e58 --- /dev/null +++ b/December 31/python3_lakshminarayanans_nqueens.py @@ -0,0 +1,106 @@ +""" +Module documentation: N Queens + +This module provides functions to solve the N-Queens problem. + +Functions: + - is_safe(board, row, col, n): Checks if it's safe to place a queen at the specified position. + - solve_n_queens_util(board, row, n, solutions): Recursive utility function to find all solutions for N-Queens. + - solve_n_queens(n): Finds all solutions for the N-Queens problem. + - print_solutions(solutions): Prints the solutions in a readable format. + - main(): Reads input from the user and calls the solve_n_queens function. + +Usage: + - Call solve_n_queens(N) to find all solutions for the N-Queens problem. + - Call print_solutions(solutions) to print the solutions in a readable format. + - Call main() to run the program and input the value of N. + +""" + +def is_safe(board, row, col, n): + """ + Checks if it's safe to place a queen at the specified position. + + Parameters: + board (list): The chessboard configuration. + row (int): The current row. + col (int): The current column. + n (int): The size of the chessboard. + + Returns: + bool: True if safe, False otherwise. + """ + # Check if there is a queen in the same column + for i in range(row): + if board[i][col] == 1: + return False + + # Check upper left diagonal + for i, j in zip(range(row, -1, -1), range(col, -1, -1)): + if board[i][j] == 1: + return False + + # Check upper right diagonal + for i, j in zip(range(row, -1, -1), range(col, n)): + if board[i][j] == 1: + return False + + return True + +def solve_n_queens_util(board, row, n, solutions): + """ + Recursive utility function to find all solutions for N-Queens. + + Parameters: + board (list): The chessboard configuration. + row (int): The current row. + n (int): The size of the chessboard. + solutions (list): List to store the found solutions. + """ + if row == n: + # Found a solution, add it to the list + solution = [(i + 1, j + 1) for i, j in enumerate(board[row])] + solutions.append(solution) + return + + for col in range(n): + if is_safe(board, row, col, n): + board[row][col] = 1 + solve_n_queens_util(board, row + 1, n, solutions) + board[row][col] = 0 # Backtrack + +def solve_n_queens(n): + """ + Finds all solutions for the N-Queens problem. + + Parameters: + n (int): The size of the chessboard. + + Returns: + list: List of solutions, where each solution is a list of coordinates. + """ + board = [[0] * n for _ in range(n)] + solutions = [] + solve_n_queens_util(board, 0, n, solutions) + return solutions + +def print_solutions(solutions): + """ + Prints the solutions in a readable format. + + Parameters: + solutions (list): List of solutions, where each solution is a list of coordinates. + """ + for solution in solutions: + print(" ".join(f"({row}, {col})" for row, col in solution)) + +def main(): + """ + Reads input from the user and calls the solve_n_queens function. + """ + N = int(input("Enter the value of N: ")) + solutions = solve_n_queens(N) + print_solutions(solutions) + +if __name__ == "__main__": + main()