Add sudoku
This commit is contained in:
parent
b3694d589d
commit
012f7b9e44
4 changed files with 168 additions and 8 deletions
89
neetcode/arrays/valid_sudoku/README.md
Normal file
89
neetcode/arrays/valid_sudoku/README.md
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
You are given a a 9 x 9 Sudoku board board. A Sudoku board is valid if the following rules are followed:
|
||||||
|
|
||||||
|
Each row must contain the digits 1-9 without duplicates.
|
||||||
|
Each column must contain the digits 1-9 without duplicates.
|
||||||
|
Each of the nine 3 x 3 sub-boxes of the grid must contain the digits 1-9 without duplicates.
|
||||||
|
Return true if the Sudoku board is valid, otherwise return false
|
||||||
|
|
||||||
|
Note: A board does not need to be full or be solvable to be valid.
|
||||||
|
|
||||||
|
Example 1:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Input: board =
|
||||||
|
[["1","2",".",".","3",".",".",".","."],
|
||||||
|
["4",".",".","5",".",".",".",".","."],
|
||||||
|
[".","9","8",".",".",".",".",".","3"],
|
||||||
|
["5",".",".",".","6",".",".",".","4"],
|
||||||
|
[".",".",".","8",".","3",".",".","5"],
|
||||||
|
["7",".",".",".","2",".",".",".","6"],
|
||||||
|
[".",".",".",".",".",".","2",".","."],
|
||||||
|
[".",".",".","4","1","9",".",".","8"],
|
||||||
|
[".",".",".",".","8",".",".","7","9"]]
|
||||||
|
|
||||||
|
Output: true
|
||||||
|
Example 2:
|
||||||
|
|
||||||
|
Input: board =
|
||||||
|
[["1","2",".",".","3",".",".",".","."],
|
||||||
|
["4",".",".","5",".",".",".",".","."],
|
||||||
|
[".","9","1",".",".",".",".",".","3"],
|
||||||
|
["5",".",".",".","6",".",".",".","4"],
|
||||||
|
[".",".",".","8",".","3",".",".","5"],
|
||||||
|
["7",".",".",".","2",".",".",".","6"],
|
||||||
|
[".",".",".",".",".",".","2",".","."],
|
||||||
|
[".",".",".","4","1","9",".",".","8"],
|
||||||
|
[".",".",".",".","8",".",".","7","9"]]
|
||||||
|
|
||||||
|
Output: false
|
||||||
|
Explanation: There are two 1's in the top-left 3x3 sub-box.
|
||||||
|
|
||||||
|
Constraints:
|
||||||
|
|
||||||
|
board.length == 9
|
||||||
|
board[i].length == 9
|
||||||
|
board[i][j] is a digit 1-9 or '.'.
|
||||||
|
|
||||||
|
# Решение
|
||||||
|
Пусть будет матрица 3х3 где будут храниться числа в каждом квадрате валидации, т.е.
|
||||||
|
```
|
||||||
|
sq = [
|
||||||
|
(), (), (),
|
||||||
|
(), (), (),
|
||||||
|
(), (), (),
|
||||||
|
]
|
||||||
|
```
|
||||||
|
Когда начнем проходить по двумерной матрице - будем смотреть на номер строк и остаток деления на три от длины проверяемого столбца, чтобы определять в какой квадрат писать
|
||||||
|
|
||||||
|
|
||||||
|
i // 3
|
||||||
|
[
|
||||||
|
0 0 0 0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0 0 0 0
|
||||||
|
|
||||||
|
1 1 1 1 1 1 1 1 1
|
||||||
|
1 1 1 1 1 1 1 1 1
|
||||||
|
1 1 1 1 1 1 1 1 1
|
||||||
|
|
||||||
|
2 2 2 2 2 2 2 2 2
|
||||||
|
2 2 2 2 2 2 2 2 2
|
||||||
|
2 2 2 2 2 2 2 2 2
|
||||||
|
]
|
||||||
|
|
||||||
|
j // 3
|
||||||
|
[
|
||||||
|
0 0 0 1 1 1 2 2 2
|
||||||
|
0 0 0 1 1 1 2 2 2
|
||||||
|
0 0 0 1 1 1 2 2 2
|
||||||
|
|
||||||
|
0 0 0 1 1 1 2 2 2
|
||||||
|
0 0 0 1 1 1 2 2 2
|
||||||
|
0 0 0 1 1 1 2 2 2
|
||||||
|
|
||||||
|
0 0 0 1 1 1 2 2 2
|
||||||
|
0 0 0 1 1 1 2 2 2
|
||||||
|
0 0 0 1 1 1 2 2 2
|
||||||
|
]
|
||||||
|
|
74
neetcode/arrays/valid_sudoku/main.py
Normal file
74
neetcode/arrays/valid_sudoku/main.py
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
from typing import Dict, List, Set
|
||||||
|
import pytest
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
|
class Solution:
|
||||||
|
"""Bruteforce solution (4 hints)"""
|
||||||
|
|
||||||
|
def isValidSudoku(self, board: List[List[str]]) -> bool:
|
||||||
|
squares: Dict = {
|
||||||
|
"00": set(),
|
||||||
|
"01": set(),
|
||||||
|
"02": set(),
|
||||||
|
"10": set(),
|
||||||
|
"11": set(),
|
||||||
|
"12": set(),
|
||||||
|
"20": set(),
|
||||||
|
"21": set(),
|
||||||
|
"22": set(),
|
||||||
|
}
|
||||||
|
lines = defaultdict(set)
|
||||||
|
for i in range(0, len(board)):
|
||||||
|
for j in range(0, len(board[i])):
|
||||||
|
board_elem = board[i][j]
|
||||||
|
squares_index = f"{i // 3}{j // 3}"
|
||||||
|
squares_index_len = len(squares[squares_index])
|
||||||
|
lines_index_len = len(lines[squares_index])
|
||||||
|
if board_elem != ".":
|
||||||
|
squares[squares_index].add(board_elem)
|
||||||
|
if len(squares[squares_index]) == squares_index_len:
|
||||||
|
return False
|
||||||
|
lines[f"{i}{j}"].add(board_elem)
|
||||||
|
if len(lines[f"{i}{j}"]) == lines_index_len:
|
||||||
|
breakpoint()
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"input_value, expected_value",
|
||||||
|
[
|
||||||
|
(
|
||||||
|
[
|
||||||
|
["1", "2", ".", ".", "3", ".", ".", ".", "."],
|
||||||
|
["4", ".", ".", "5", ".", ".", ".", ".", "."],
|
||||||
|
[".", "9", "8", ".", ".", ".", ".", ".", "3"],
|
||||||
|
["5", ".", ".", ".", "6", ".", ".", ".", "4"],
|
||||||
|
[".", ".", ".", "8", ".", "3", ".", ".", "5"],
|
||||||
|
["7", ".", ".", ".", "2", ".", ".", ".", "6"],
|
||||||
|
[".", ".", ".", ".", ".", ".", "2", ".", "."],
|
||||||
|
[".", ".", ".", "4", "1", "9", ".", ".", "8"],
|
||||||
|
[".", ".", ".", ".", "8", ".", ".", "7", "9"],
|
||||||
|
],
|
||||||
|
True,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
[
|
||||||
|
["1", "2", ".", ".", "3", ".", ".", ".", "."],
|
||||||
|
["4", ".", ".", "5", ".", ".", ".", ".", "."],
|
||||||
|
[".", "9", "1", ".", ".", ".", ".", ".", "3"],
|
||||||
|
["5", ".", ".", ".", "6", ".", ".", ".", "4"],
|
||||||
|
[".", ".", ".", "8", ".", "3", ".", ".", "5"],
|
||||||
|
["7", ".", ".", ".", "2", ".", ".", ".", "6"],
|
||||||
|
[".", ".", ".", ".", ".", ".", "2", ".", "."],
|
||||||
|
[".", ".", ".", "4", "1", "9", ".", ".", "8"],
|
||||||
|
[".", ".", ".", ".", "8", ".", ".", "7", "9"],
|
||||||
|
],
|
||||||
|
False,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_solution(input_value, expected_value):
|
||||||
|
s = Solution()
|
||||||
|
assert s.isValidSudoku(board=input_value) == expected_value
|
9
poetry.lock
generated
9
poetry.lock
generated
|
@ -1,10 +1,9 @@
|
||||||
# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "colorama"
|
name = "colorama"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
description = "Cross-platform colored terminal text."
|
description = "Cross-platform colored terminal text."
|
||||||
category = "main"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||||
files = [
|
files = [
|
||||||
|
@ -16,7 +15,6 @@ files = [
|
||||||
name = "exceptiongroup"
|
name = "exceptiongroup"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
description = "Backport of PEP 654 (exception groups)"
|
description = "Backport of PEP 654 (exception groups)"
|
||||||
category = "main"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
|
@ -31,7 +29,6 @@ test = ["pytest (>=6)"]
|
||||||
name = "iniconfig"
|
name = "iniconfig"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
description = "brain-dead simple config-ini parsing"
|
description = "brain-dead simple config-ini parsing"
|
||||||
category = "main"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
|
@ -43,7 +40,6 @@ files = [
|
||||||
name = "packaging"
|
name = "packaging"
|
||||||
version = "24.2"
|
version = "24.2"
|
||||||
description = "Core utilities for Python packages"
|
description = "Core utilities for Python packages"
|
||||||
category = "main"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
|
@ -55,7 +51,6 @@ files = [
|
||||||
name = "pluggy"
|
name = "pluggy"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
description = "plugin and hook calling mechanisms for python"
|
description = "plugin and hook calling mechanisms for python"
|
||||||
category = "main"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
|
@ -71,7 +66,6 @@ testing = ["pytest", "pytest-benchmark"]
|
||||||
name = "pytest"
|
name = "pytest"
|
||||||
version = "8.3.4"
|
version = "8.3.4"
|
||||||
description = "pytest: simple powerful testing with Python"
|
description = "pytest: simple powerful testing with Python"
|
||||||
category = "main"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
|
@ -94,7 +88,6 @@ dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments
|
||||||
name = "tomli"
|
name = "tomli"
|
||||||
version = "2.2.1"
|
version = "2.2.1"
|
||||||
description = "A lil' TOML parser"
|
description = "A lil' TOML parser"
|
||||||
category = "main"
|
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
|
|
4
pyrightconfig.json
Normal file
4
pyrightconfig.json
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"venv": ".venv",
|
||||||
|
"venvPath": "/Users/antonsalimov/Projects/Learning/algos_and_structures",
|
||||||
|
}
|
Loading…
Reference in a new issue