Skip to content
Merged
35 changes: 30 additions & 5 deletions all-your-base/all_your_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"""


def rebase(input_base: int, digits: list[int], output_base: int):
def rebase(input_base: int, digits: list[int], output_base: int) -> list[int]:
"""
Convert a non-negative integer represented as digits in one base
to digits in another base.
Expand All @@ -20,16 +20,41 @@ def rebase(input_base: int, digits: list[int], output_base: int):
:raises ValueError: If ``input_base < 2``, if any digit violates
``0 <= d < input_base``, or if ``output_base < 2``.
"""

# for input.
# Step 1: Validate the Inputs (Before Any Calculations)
# Validate input_base >= 2
if input_base < 2:
raise ValueError("input base must be >= 2")

# another example for input.
# Validate each digit is 0 <= d < input_base
for d in digits:
if not 0 <= d < input_base:
raise ValueError("all digits must satisfy 0 <= d < input base")

# or, for output.
# Validate output_base >= 2
if output_base < 2:
raise ValueError("output base must be >= 2")

# Step 2: Calculate the Intermediate Value Using input_base and digits
# Start from the least significant number (from the right in original list)
# -> hence reverse the list
intermediate_val: int = sum(
digit * (input_base**i) for i, digit in enumerate(digits[::-1])
)

# Step 3: Convert the Intermediate Value to digits in output_base
answer: list[int] = []
while True:
# Compute quotient (new intermediate_val)
# and remainder (least significant digit)
intermediate_val, remainder = (
intermediate_val // output_base,
intermediate_val % output_base,
)
# Add the next least significant number into a new list of digits
# Start always from the right
answer.insert(0, remainder)
# Break the loop since reach zero, no more calculation needed
if intermediate_val == 0:
break

return answer
33 changes: 33 additions & 0 deletions solutions/python/all-your-base/1/all_your_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
Convert a sequence of digits in one base, representing a number,
into a sequence of digits in another base, representing the same number.
"""


def rebase(input_base: int, digits: list[int], output_base: int):
"""
Convert a non-negative integer represented as digits in one base to digits in another base.

:param int input_base: Base of the input digits; must be >= 2.
:param list[int] digits: Sequence of digits where each d satisfies 0 <= d < input_base.
Leading zeros are allowed; an empty list denotes 0.
:param int output_base: Base for the output digits; must be >= 2.
:returns: Digits of the same number in ``output_base``, without leading zeros
(except ``[0]`` for zero).
:rtype: list[int]
:raises ValueError: If ``input_base < 2``, if any digit violates ``0 <= d < input_base``,
or if ``output_base < 2``.
"""

# for input.
if input_base < 2:
raise ValueError("input base must be >= 2")

# another example for input.
for d in digits:
if not 0 <= d < input_base:
raise ValueError("all digits must satisfy 0 <= d < input base")

# or, for output.
if output_base < 2:
raise ValueError("output base must be >= 2")
51 changes: 51 additions & 0 deletions solutions/python/sublist/7/sublist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""
This exercise stub and the test suite contain several enumerated constants.

Enumerated constants can be done with a NAME assigned to an arbitrary,
but unique value. An integer is traditionally used because it’s memory
efficient.

It is a common practice to export both constants and functions that work with
those constants (ex. the constants in the os, subprocess and re modules).

You can learn more here: https://en.wikipedia.org/wiki/Enumerated_type
"""

# Possible sublist categories.
# Change the values as you see fit.
SUBLIST = 0
SUPERLIST = 1
EQUAL = 2
UNEQUAL = 3


def sublist(list_one: list, list_two: list) -> int:
"""
Classify the relationship between two lists.

Determines whether ``list_one`` and ``list_two`` are equal, or whether one
is a contiguous sublist of the other, and returns the appropriate constant.

:param list_one: First list to compare.
:type list_one: list
:param list_two: Second list to compare.
:type list_two: list
:returns: One of ``EQUAL``, ``SUBLIST``, ``SUPERLIST``, or ``UNEQUAL``.
:rtype: int
"""

if len(list_one) == len(list_two):
if list_one == list_two:
return EQUAL
return UNEQUAL

l1: str = ",".join(str(i) for i in list_one)
l2: str = ",".join(str(i) for i in list_two)

if l2 in l1:
return SUPERLIST

if l1 in l2:
return SUBLIST

return UNEQUAL
13 changes: 5 additions & 8 deletions sublist/sublist.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,19 @@ def sublist(list_one: list, list_two: list) -> int:
:returns: One of ``EQUAL``, ``SUBLIST``, ``SUPERLIST``, or ``UNEQUAL``.
:rtype: int
"""

len1: int = len(list_one)
len2: int = len(list_two)

if len1 == len2:
# Step #1: test list with same length
if len(list_one) == len(list_two):
if list_one == list_two:
return EQUAL
return UNEQUAL

# Step #2: convert list to a string
l1: str = ",".join(str(i) for i in list_one)
l2: str = ",".join(str(i) for i in list_two)

# Step #3: check for substring
if l2 in l1:
return SUPERLIST

if l1 in l2:
return SUBLIST

# Step #4: Return default
return UNEQUAL
10 changes: 10 additions & 0 deletions sublist/sublist_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,13 @@ def test_spread_sublist(self):
self.assertEqual(
sublist(list(range(3, 200, 3)), list(range(15, 200, 15))), UNEQUAL
)


if __name__ == '__main__':
import time

start_time = time.time()
unittest.main(verbosity=2) # Verbosity=2 for detailed output; adjust if needed
end_time = time.time()
duration = end_time - start_time
print(f"\nAll tests completed in {duration:.4f} seconds.")