From 1b7d323665c6f2ff06b8ebd132ae2a9e3af54b75 Mon Sep 17 00:00:00 2001 From: MaJaneb Date: Tue, 17 Jan 2023 16:35:38 +0300 Subject: [PATCH 1/3] s --- .idea/Chzh.iml | 14 ++++++++++++++ .idea/misc.xml | 4 ++++ .idea/workspace.xml | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 .idea/Chzh.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/workspace.xml diff --git a/.idea/Chzh.iml b/.idea/Chzh.iml new file mode 100644 index 0000000..8e5446a --- /dev/null +++ b/.idea/Chzh.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..cc2518d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..73eaf47 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + 1673962365428 + + + + \ No newline at end of file From c13c53878999b997c6d4390786b38049092180b5 Mon Sep 17 00:00:00 2001 From: MaJaneb Date: Tue, 17 Jan 2023 16:38:23 +0300 Subject: [PATCH 2/3] s --- .idea/.name | 1 + .idea/vcs.xml | 6 +++ homework02/sudoku.py | 93 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 86 insertions(+), 14 deletions(-) create mode 100644 .idea/.name create mode 100644 .idea/vcs.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..b15c5a4 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +sudoku.py \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/homework02/sudoku.py b/homework02/sudoku.py index df78ab1..87139b0 100644 --- a/homework02/sudoku.py +++ b/homework02/sudoku.py @@ -1,11 +1,12 @@ import pathlib +import random import typing as tp T = tp.TypeVar("T") def read_sudoku(path: tp.Union[str, pathlib.Path]) -> tp.List[tp.List[str]]: - """ Прочитать Судоку из указанного файла """ + """Прочитать Судоку из указанного файла""" path = pathlib.Path(path) with path.open() as f: puzzle = f.read() @@ -19,7 +20,7 @@ def create_grid(puzzle: str) -> tp.List[tp.List[str]]: def display(grid: tp.List[tp.List[str]]) -> None: - """Вывод Судоку """ + """Вывод Судоку""" width = 2 line = "+".join(["-" * (width * 3)] * 3) for row in range(9): @@ -42,7 +43,16 @@ def group(values: tp.List[T], n: int) -> tp.List[tp.List[T]]: >>> group([1,2,3,4,5,6,7,8,9], 3) [[1, 2, 3], [4, 5, 6], [7, 8, 9]] """ - pass + t: tp.List[T] = [] + res = [] + length = len(values) + for i in range(length): + if i % n == 0 and i != 0: + res.append(t) + t = [] + t.append(values[i]) + res.append(t) + return res def get_row(grid: tp.List[tp.List[str]], pos: tp.Tuple[int, int]) -> tp.List[str]: @@ -55,7 +65,7 @@ def get_row(grid: tp.List[tp.List[str]], pos: tp.Tuple[int, int]) -> tp.List[str >>> get_row([['1', '2', '3'], ['4', '5', '6'], ['.', '8', '9']], (2, 0)) ['.', '8', '9'] """ - pass + return grid[pos[0]] def get_col(grid: tp.List[tp.List[str]], pos: tp.Tuple[int, int]) -> tp.List[str]: @@ -68,7 +78,10 @@ def get_col(grid: tp.List[tp.List[str]], pos: tp.Tuple[int, int]) -> tp.List[str >>> get_col([['1', '2', '3'], ['4', '5', '6'], ['.', '8', '9']], (0, 2)) ['3', '6', '9'] """ - pass + res = [] + for arr in grid: + res.append(arr[pos[1]]) + return res def get_block(grid: tp.List[tp.List[str]], pos: tp.Tuple[int, int]) -> tp.List[str]: @@ -82,10 +95,16 @@ def get_block(grid: tp.List[tp.List[str]], pos: tp.Tuple[int, int]) -> tp.List[s >>> get_block(grid, (8, 8)) ['2', '8', '.', '.', '.', '5', '.', '7', '9'] """ - pass + res = [] + r = pos[0] // 3 * 3 + c = pos[1] // 3 * 3 + for i in range(r, r + 3): + for j in range(c, c + 3): + res.append(grid[i][j]) + return res -def find_empty_positions(grid: tp.List[tp.List[str]]) -> tp.Optional[tp.Tuple[int, int]]: +def find_empty_positions(grid: tp.List[tp.List[str]]) -> tp.Tuple[int, int]: """Найти первую свободную позицию в пазле >>> find_empty_positions([['1', '2', '.'], ['4', '5', '6'], ['7', '8', '9']]) @@ -95,7 +114,13 @@ def find_empty_positions(grid: tp.List[tp.List[str]]) -> tp.Optional[tp.Tuple[in >>> find_empty_positions([['1', '2', '3'], ['4', '5', '6'], ['.', '8', '9']]) (2, 0) """ - pass + if grid != 0: + for i in range(len(grid)): + for j in range(len(grid[i])): + if not grid[i][j].isdigit(): + r, c = i, j + return r, c + return -1, -1 def find_possible_values(grid: tp.List[tp.List[str]], pos: tp.Tuple[int, int]) -> tp.Set[str]: @@ -109,11 +134,20 @@ def find_possible_values(grid: tp.List[tp.List[str]], pos: tp.Tuple[int, int]) - >>> values == {'2', '5', '9'} True """ - pass + res = [] + for arr in range(1, 10): + s = str(arr) + if ( + s not in get_block(grid, pos) + and s not in get_col(grid, pos) + and s not in get_row(grid, pos) + ): + res.append(s) + return set(res) def solve(grid: tp.List[tp.List[str]]) -> tp.Optional[tp.List[tp.List[str]]]: - """ Решение пазла, заданного в grid """ + """Решение пазла, заданного в grid""" """ Как решать Судоку? 1. Найти свободную позицию 2. Найти все возможные значения, которые могут находиться на этой позиции @@ -125,13 +159,36 @@ def solve(grid: tp.List[tp.List[str]]) -> tp.Optional[tp.List[tp.List[str]]]: >>> solve(grid) [['5', '3', '4', '6', '7', '8', '9', '1', '2'], ['6', '7', '2', '1', '9', '5', '3', '4', '8'], ['1', '9', '8', '3', '4', '2', '5', '6', '7'], ['8', '5', '9', '7', '6', '1', '4', '2', '3'], ['4', '2', '6', '8', '5', '3', '7', '9', '1'], ['7', '1', '3', '9', '2', '4', '8', '5', '6'], ['9', '6', '1', '5', '3', '7', '2', '8', '4'], ['2', '8', '7', '4', '1', '9', '6', '3', '5'], ['3', '4', '5', '2', '8', '6', '1', '7', '9']] """ - pass + empty = find_empty_positions(grid) # type: tp.Tuple[int, int] + if empty[0] < 0: + return grid + possible = find_possible_values(grid, empty) # type: tp.Set[str] + if not possible: + return None + for i in possible: + grid[empty[0]][empty[1]] = i + if solve(grid): + return grid + grid[empty[0]][empty[1]] = "." + return None def check_solution(solution: tp.List[tp.List[str]]) -> bool: - """ Если решение solution верно, то вернуть True, в противном случае False """ + """Если решение solution верно, то вернуть True, в противном случае False""" # TODO: Add doctests with bad puzzles - pass + g = solution + for i in range(9): + if len(get_row(g, (i, 0))) != len(set(get_row(g, (i, 0)))) or len( + get_col(g, (0, i)) + ) != len(set(get_col(g, (0, i)))): + return False + if i == 0 or i == 3 or i == 6: + for j in range(0, 9, 3): + if len(get_block(g, (i, j))) != len(set(get_block(g, (i, j)))): + return False + if "." in g[i]: + return False + return True def generate_sudoku(N: int) -> tp.List[tp.List[str]]: @@ -156,7 +213,15 @@ def generate_sudoku(N: int) -> tp.List[tp.List[str]]: >>> check_solution(solution) True """ - pass + grid = [["."] * 9 for _ in range(9)] + solve(grid) + count, N = 0, min(81, N) + while count < 81 - N: + i, j = random.randint(0, 8), random.randint(0, 8) + if grid[i][j] != ".": + grid[i][j] = "." + count += 1 + return grid if __name__ == "__main__": From 182cf8424ddd47d7a3594c9b376f34416af9f3b7 Mon Sep 17 00:00:00 2001 From: MaJaneb Date: Tue, 17 Jan 2023 16:40:40 +0300 Subject: [PATCH 3/3] s --- .github/workflows/cs102.yml | 4 +-- .../inspectionProfiles/profiles_settings.xml | 6 ++++ .idea/workspace.xml | 34 +++++++++++++++++++ main.py | 16 +++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 main.py diff --git a/.github/workflows/cs102.yml b/.github/workflows/cs102.yml index 4509ac4..8e1e8be 100644 --- a/.github/workflows/cs102.yml +++ b/.github/workflows/cs102.yml @@ -7,10 +7,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Set up Python 3.8.6 + - name: Set up Python 3.10.7 uses: actions/setup-python@v2 with: - python-version: '3.8.6' + python-version: '3.10.7' - name: Install dependencies run: | python -m pip install --upgrade pip 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/workspace.xml b/.idea/workspace.xml index 73eaf47..adbc062 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -22,6 +22,29 @@ + + + + @@ -33,4 +56,15 @@ + + + + + file://$PROJECT_DIR$/main.py + 8 + + + + \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..5596b44 --- /dev/null +++ b/main.py @@ -0,0 +1,16 @@ +# This is a sample Python script. + +# Press Shift+F10 to execute it or replace it with your code. +# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings. + + +def print_hi(name): + # Use a breakpoint in the code line below to debug your script. + print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint. + + +# Press the green button in the gutter to run the script. +if __name__ == '__main__': + print_hi('PyCharm') + +# See PyCharm help at https://www.jetbrains.com/help/pycharm/