I'm not sure why but this version (building a slice as we go) is faster on average
Still about 3x slower than str.split though
def split(string, separator): split_list = [] current_slice = '' for char in string: if char == separator: split_list.append(current_slice) current_slice = '' else: current_slice += char split_list.append(current_slice) return split_list
# ojeriejire rust version in python- def split(string, separator):
- split_list = []
i = 0- current_slice = ''
- for char in string:
- if char == separator:
- split_list.append(current_slice)
- current_slice = ''
- else:
- current_slice += char
for j, c in enumerate(string):if c == separator:slice_ = string[i:j]split_list.append(slice_)i = j + 1split_list.append(string[i:])return split_list- split_list.append(current_slice)
- return split_list
import codewars_test as test @test.describe("Tests") def test(): @test.it("Works") def functional(): test.assert_equals(split("Hello World", ' '), ["Hello", "World"]) test.assert_equals(split("John-brings-his-cat", '-'), ["John", "brings", "his", "cat"]) test.assert_equals(split(",joe,mama,", ','), ["", "joe", "mama", ""]) @test.it("Is fast enough") def fast(): test.assert_equals(split("*".join("" for i in range(2000000)), "*"), [""]*2000000) test.assert_equals(split(":".join("character sequence" for i in range(1500000)), ":"), ["character sequence"]*1500000) test.assert_equals(split(":".join("performance test number three" for i in range(3000000)), ":"), ["performance test number three"]*3000000) print("All test cases passed.")
#[test]- import codewars_test as test
- @test.describe("Tests")
- def test():
assert split("Hello World", ' ') == ["Hello", "World"]assert split("John-brings-his-cat", '-') == ["John", "brings", "his", "cat"]assert split(",joe,mama,", ',') == ["", "joe", "mama", ""]- @test.it("Works")
- def functional():
- test.assert_equals(split("Hello World", ' '), ["Hello", "World"])
- test.assert_equals(split("John-brings-his-cat", '-'), ["John", "brings", "his", "cat"])
- test.assert_equals(split(",joe,mama,", ','), ["", "joe", "mama", ""])
- @test.it("Is fast enough")
- def fast():
- test.assert_equals(split("*".join("" for i in range(2000000)), "*"), [""]*2000000)
- test.assert_equals(split(":".join("character sequence" for i in range(1500000)), ":"), ["character sequence"]*1500000)
- test.assert_equals(split(":".join("performance test number three" for i in range(3000000)), ":"), ["performance test number three"]*3000000)
- print("All test cases passed.")
# Running the test function to check if the function workstest()
When writing a number in base 3, the number is even only if its digit sum is also
This function uses this fact as well as recursion to check whether a number is odd or even
To sum the digits, we sum their ascii codepoints. This works because the ascii values for 0, 1, 2 have the same parity as the digits they represent:
ord('0') == 48
ord('1') == 49
ord('2') == 50
This program also fulfils one of the points of the original brief because it almost always times out:
Bonus points for skirting the execution time limit without waits or unnecessary loops
# By using base 3, there are fewer possible digits to check: only 0, 1, or 2 def odd_even(n): # Make n positive; this won't affect whether it's even if n < 0: n *= -1 # Express n in base 3 for easier parity checking b3_n = '' while n: b3_n = str(n%3) + b3_n n //= 3 # Now we can sum the digits - if the answer is even, then n was even # Unfortunately we have a string, not an int, but we can convert with `ord`: digit_sum = sum(ord(char) for char in b3_n) # If the digit sum was even, so was n try: return odd_even(digit_sum) except RecursionError: # The fixed point of this process is 294 or 295, so we just check which it was return digit_sum == 295 print(f'{odd_even(0) = }') print(f'{odd_even(1) = }')
import randomimport timedef not_even(n):pizza_time = time.ctime()if n % 2 == 0:return 'its not even', pizza_timeelse:return 'its still not even', pizza_timereturn pizza_timen = random.randint(0, 10000)print(not_even(n))- # By using base 3, there are fewer possible digits to check: only 0, 1, or 2
- def odd_even(n):
- # Make n positive; this won't affect whether it's even
- if n < 0: n *= -1
- # Express n in base 3 for easier parity checking
- b3_n = ''
- while n:
- b3_n = str(n%3) + b3_n
- n //= 3
- # Now we can sum the digits - if the answer is even, then n was even
- # Unfortunately we have a string, not an int, but we can convert with `ord`:
- digit_sum = sum(ord(char) for char in b3_n)
- # If the digit sum was even, so was n
- try:
- return odd_even(digit_sum)
- except RecursionError:
- # The fixed point of this process is 294 or 295, so we just check which it was
- return digit_sum == 295
- print(f'{odd_even(0) = }')
- print(f'{odd_even(1) = }')
import codewars_test as test from solution import odd_even @test.describe("Example") def test_group(): @test.it("test case 1: Testing Even Numbers") def test_case(): for n in range(-1900, 1901, 2): test.assert_equals(odd_even(n), 0) @test.it("test case 2: Testing Odd Numbers") def test_case(): for n in range(-1901, 1901, 2): test.assert_equals(odd_even(n), 1)
- import codewars_test as test
- from solution import odd_even
# TODO Write testsimport solution # or from solution import exampleimport time# test.assert_equals(actual, expected, [optional] message)- @test.describe("Example")
- def test_group():
@test.it("test case")- @test.it("test case 1: Testing Even Numbers")
- def test_case():
- for n in range(-1900, 1901, 2):
- test.assert_equals(odd_even(n), 0)
- @test.it("test case 2: Testing Odd Numbers")
- def test_case():
if time.ctime() == time.ctime():test.assert_equals('its not even', 'its not even') or test.assert_equals('its still even', 'its still even')- for n in range(-1901, 1901, 2):
- test.assert_equals(odd_even(n), 1)