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]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
files = [
|
||||
|
@ -16,7 +15,6 @@ files = [
|
|||
name = "exceptiongroup"
|
||||
version = "1.2.2"
|
||||
description = "Backport of PEP 654 (exception groups)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -31,7 +29,6 @@ test = ["pytest (>=6)"]
|
|||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
description = "brain-dead simple config-ini parsing"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -43,7 +40,6 @@ files = [
|
|||
name = "packaging"
|
||||
version = "24.2"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -55,7 +51,6 @@ files = [
|
|||
name = "pluggy"
|
||||
version = "1.5.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -71,7 +66,6 @@ testing = ["pytest", "pytest-benchmark"]
|
|||
name = "pytest"
|
||||
version = "8.3.4"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -94,7 +88,6 @@ dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments
|
|||
name = "tomli"
|
||||
version = "2.2.1"
|
||||
description = "A lil' TOML parser"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
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