Created
April 7, 2023 21:28
-
-
Save kjhf/2b06b888c02772e7c361d1a2aebb8fef to your computer and use it in GitHub Desktop.
Guriddo compartment helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ast | |
from typing import Union | |
def is_contiguous(lst: list[int]) -> bool: | |
"""Checks if a list of integers is contiguous. | |
A list is considered contiguous if each element is equal to the | |
previous element plus one. | |
Args: | |
lst: A list of integers. | |
Returns: | |
True if the list is contiguous, False otherwise. | |
""" | |
sorted_list = get_sorted(lst) | |
return all(sorted_list[i] == sorted_list[0]+i for i in range(len(sorted_list))) | |
def get_sorted(lst: list[int]) -> list[int]: | |
"""Returns a sorted copy of a list of integers. | |
Args: | |
lst: A list of integers. | |
Returns: | |
A sorted copy of the input list. | |
""" | |
sorted_list = lst[:] | |
sorted_list.sort() | |
return sorted_list | |
def parse_input(input_str: str): | |
"""Parses the input string into a list of lists of integers. | |
The input string should be in one of two formats: | |
- A comma-separated list of lists of integers enclosed in square brackets, | |
e.g. "[[1, 4, 2], [6], [8, 7]]". | |
- A space-separated list of integers, where each integer is the candidate | |
digits concatenated together, e.g. "123 456 789". | |
Args: | |
input_str: A string containing the input. | |
Returns: | |
A list of lists of integers. | |
""" | |
if input_str.startswith("[") and input_str.endswith("]"): | |
# Parse as a list of lists | |
return ast.literal_eval(input_str) | |
else: | |
# Parse as a space-separated list of integers | |
cell_strs = input_str.strip().replace(',', '').split() | |
cells = [] | |
for cell_str in cell_strs: | |
cell = [int(digit) for digit in cell_str] | |
cells.append(cell) | |
return cells | |
def permute_lists(lst: list[list[int]], i: int, current: list[int], result: list[list[int]]) -> None: | |
"""Generates all valid contiguous permutations of a list of lists of integers. | |
A contiguous permutation is one where each sublist in the permutation is | |
either unchanged or replaced with a contiguous sequence of integers. | |
Args: | |
lst: A list of lists of integers. | |
i: The current index being processed. | |
current: A list containing the current permutation being generated. | |
result: A list to collect all valid contiguous permutations. | |
Returns: | |
None. | |
""" | |
if i == len(lst): | |
if is_contiguous(current): | |
result.append(current[:]) | |
return | |
for j in lst[i]: | |
current[i] = j | |
permute_lists(lst, i + 1, current, result) | |
def main(): | |
"""Main function that prompts the user for input and prints the results. | |
This function prompts the user to enter a list of lists of integers, | |
then generates all contiguous permutations of those lists using the | |
permute_lists function. It then prints each valid permutation along with | |
its sorted form and lists candidates that can be eliminated. | |
Args: | |
None. | |
Returns: | |
None. | |
""" | |
input_str = input("Enter cells' candidates either in form [1, 4, 2], [6], [8, 7], or concat form 142 6 87: ").strip("\'\"`, ") | |
try: | |
input_list: list[Union[int, list[int]]] = parse_input(input_str) | |
# Fix any ints that are given singly | |
for i in range(0, len(input_list)): | |
if isinstance(input_list[i], int): | |
input_list[i] = [input_list[i]] | |
input_list: list[list[int]] | |
current_permutation: list[int] = [0] * len(input_list) | |
valid_permutations: list[list[int]] = [] | |
permute_lists(input_list, 0, current_permutation, valid_permutations) | |
if len(valid_permutations) == 0: | |
print("No valid contiguous sequences found.") | |
else: | |
# Print out the solutions | |
for solution in valid_permutations: | |
sorted_vals = get_sorted(solution) | |
print(f"{', '.join((str(cell) for cell in solution))} --> {', '.join((str(val) for val in sorted_vals))}") | |
# Print out the requirements | |
requirements: set[int] = set() | |
for i in range(1, 10): | |
# if all valid_permutations contain a cell with i it is a requirement | |
if all(i in solution for solution in valid_permutations): | |
requirements.add(i) | |
lower = min(cell for solution in valid_permutations for cell in solution) | |
upper = max(cell for solution in valid_permutations for cell in solution) | |
print(f"Lower={lower}, Upper={upper}") | |
if requirements: | |
print(f"Required={repr(requirements)}; Min={min(requirements)}, Max={max(requirements)}") | |
else: | |
print(f"Required=none") | |
remove: list[list[int]] = [] | |
for i in range(0, len(input_list)): | |
input_cell = input_list[i] | |
remove.append([]) | |
for candidate in input_cell: | |
# If the input candidate is not the cell's number for any of the solutions | |
if all(candidate != valid_permutation[i] for valid_permutation in valid_permutations): | |
remove[i].append(candidate) | |
if remove: | |
print("Candidates that can be eliminated:") | |
print(repr(remove)) | |
else: | |
print("No candidates to eliminate") | |
except (SyntaxError, ValueError): | |
print("Invalid input format.") | |
if __name__ == '__main__': | |
while True: | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment