Skip to content

Commit d86ce4f

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 9823e26 + e3eb9da commit d86ce4f

File tree

7 files changed

+723
-2
lines changed

7 files changed

+723
-2
lines changed

Diff for: backtracking/crossword_puzzle_solver.py

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# https://www.geeksforgeeks.org/solve-crossword-puzzle/
2+
3+
4+
def is_valid(
5+
puzzle: list[list[str]], word: str, row: int, col: int, vertical: bool
6+
) -> bool:
7+
"""
8+
Check if a word can be placed at the given position.
9+
10+
>>> puzzle = [
11+
... ['', '', '', ''],
12+
... ['', '', '', ''],
13+
... ['', '', '', ''],
14+
... ['', '', '', '']
15+
... ]
16+
>>> is_valid(puzzle, 'word', 0, 0, True)
17+
True
18+
>>> puzzle = [
19+
... ['', '', '', ''],
20+
... ['', '', '', ''],
21+
... ['', '', '', ''],
22+
... ['', '', '', '']
23+
... ]
24+
>>> is_valid(puzzle, 'word', 0, 0, False)
25+
True
26+
"""
27+
for i in range(len(word)):
28+
if vertical:
29+
if row + i >= len(puzzle) or puzzle[row + i][col] != "":
30+
return False
31+
else:
32+
if col + i >= len(puzzle[0]) or puzzle[row][col + i] != "":
33+
return False
34+
return True
35+
36+
37+
def place_word(
38+
puzzle: list[list[str]], word: str, row: int, col: int, vertical: bool
39+
) -> None:
40+
"""
41+
Place a word at the given position.
42+
43+
>>> puzzle = [
44+
... ['', '', '', ''],
45+
... ['', '', '', ''],
46+
... ['', '', '', ''],
47+
... ['', '', '', '']
48+
... ]
49+
>>> place_word(puzzle, 'word', 0, 0, True)
50+
>>> puzzle
51+
[['w', '', '', ''], ['o', '', '', ''], ['r', '', '', ''], ['d', '', '', '']]
52+
"""
53+
for i, char in enumerate(word):
54+
if vertical:
55+
puzzle[row + i][col] = char
56+
else:
57+
puzzle[row][col + i] = char
58+
59+
60+
def remove_word(
61+
puzzle: list[list[str]], word: str, row: int, col: int, vertical: bool
62+
) -> None:
63+
"""
64+
Remove a word from the given position.
65+
66+
>>> puzzle = [
67+
... ['w', '', '', ''],
68+
... ['o', '', '', ''],
69+
... ['r', '', '', ''],
70+
... ['d', '', '', '']
71+
... ]
72+
>>> remove_word(puzzle, 'word', 0, 0, True)
73+
>>> puzzle
74+
[['', '', '', ''], ['', '', '', ''], ['', '', '', ''], ['', '', '', '']]
75+
"""
76+
for i in range(len(word)):
77+
if vertical:
78+
puzzle[row + i][col] = ""
79+
else:
80+
puzzle[row][col + i] = ""
81+
82+
83+
def solve_crossword(puzzle: list[list[str]], words: list[str]) -> bool:
84+
"""
85+
Solve the crossword puzzle using backtracking.
86+
87+
>>> puzzle = [
88+
... ['', '', '', ''],
89+
... ['', '', '', ''],
90+
... ['', '', '', ''],
91+
... ['', '', '', '']
92+
... ]
93+
94+
>>> words = ['word', 'four', 'more', 'last']
95+
>>> solve_crossword(puzzle, words)
96+
True
97+
>>> puzzle = [
98+
... ['', '', '', ''],
99+
... ['', '', '', ''],
100+
... ['', '', '', ''],
101+
... ['', '', '', '']
102+
... ]
103+
>>> words = ['word', 'four', 'more', 'paragraphs']
104+
>>> solve_crossword(puzzle, words)
105+
False
106+
"""
107+
for row in range(len(puzzle)):
108+
for col in range(len(puzzle[0])):
109+
if puzzle[row][col] == "":
110+
for word in words:
111+
for vertical in [True, False]:
112+
if is_valid(puzzle, word, row, col, vertical):
113+
place_word(puzzle, word, row, col, vertical)
114+
words.remove(word)
115+
if solve_crossword(puzzle, words):
116+
return True
117+
words.append(word)
118+
remove_word(puzzle, word, row, col, vertical)
119+
return False
120+
return True
121+
122+
123+
if __name__ == "__main__":
124+
PUZZLE = [[""] * 3 for _ in range(3)]
125+
WORDS = ["cat", "dog", "car"]
126+
127+
if solve_crossword(PUZZLE, WORDS):
128+
print("Solution found:")
129+
for row in PUZZLE:
130+
print(" ".join(row))
131+
else:
132+
print("No solution found:")

Diff for: conversions/ipv4_conversion.py

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# https://www.geeksforgeeks.org/convert-ip-address-to-integer-and-vice-versa/
2+
3+
4+
def ipv4_to_decimal(ipv4_address: str) -> int:
5+
"""
6+
Convert an IPv4 address to its decimal representation.
7+
8+
Args:
9+
ip_address: A string representing an IPv4 address (e.g., "192.168.0.1").
10+
11+
Returns:
12+
int: The decimal representation of the IP address.
13+
14+
>>> ipv4_to_decimal("192.168.0.1")
15+
3232235521
16+
>>> ipv4_to_decimal("10.0.0.255")
17+
167772415
18+
>>> ipv4_to_decimal("10.0.255")
19+
Traceback (most recent call last):
20+
...
21+
ValueError: Invalid IPv4 address format
22+
>>> ipv4_to_decimal("10.0.0.256")
23+
Traceback (most recent call last):
24+
...
25+
ValueError: Invalid IPv4 octet 256
26+
"""
27+
28+
octets = [int(octet) for octet in ipv4_address.split(".")]
29+
if len(octets) != 4:
30+
raise ValueError("Invalid IPv4 address format")
31+
32+
decimal_ipv4 = 0
33+
for octet in octets:
34+
if not 0 <= octet <= 255:
35+
raise ValueError(f"Invalid IPv4 octet {octet}") # noqa: EM102
36+
decimal_ipv4 = (decimal_ipv4 << 8) + int(octet)
37+
38+
return decimal_ipv4
39+
40+
41+
def alt_ipv4_to_decimal(ipv4_address: str) -> int:
42+
"""
43+
>>> alt_ipv4_to_decimal("192.168.0.1")
44+
3232235521
45+
>>> alt_ipv4_to_decimal("10.0.0.255")
46+
167772415
47+
"""
48+
return int("0x" + "".join(f"{int(i):02x}" for i in ipv4_address.split(".")), 16)
49+
50+
51+
def decimal_to_ipv4(decimal_ipv4: int) -> str:
52+
"""
53+
Convert a decimal representation of an IP address to its IPv4 format.
54+
55+
Args:
56+
decimal_ipv4: An integer representing the decimal IP address.
57+
58+
Returns:
59+
The IPv4 representation of the decimal IP address.
60+
61+
>>> decimal_to_ipv4(3232235521)
62+
'192.168.0.1'
63+
>>> decimal_to_ipv4(167772415)
64+
'10.0.0.255'
65+
>>> decimal_to_ipv4(-1)
66+
Traceback (most recent call last):
67+
...
68+
ValueError: Invalid decimal IPv4 address
69+
"""
70+
71+
if not (0 <= decimal_ipv4 <= 4294967295):
72+
raise ValueError("Invalid decimal IPv4 address")
73+
74+
ip_parts = []
75+
for _ in range(4):
76+
ip_parts.append(str(decimal_ipv4 & 255))
77+
decimal_ipv4 >>= 8
78+
79+
return ".".join(reversed(ip_parts))
80+
81+
82+
if __name__ == "__main__":
83+
import doctest
84+
85+
doctest.testmod()

0 commit comments

Comments
 (0)