In this article, we’ll tackle multiple coding challenges from CodeWars, specifically focusing on the `kyu 6`

level. Using Python as our language of choice, we’ll walk through each problem, offering insights into problem-solving techniques and Pythonic best practices. Whether you’re a beginner looking to level up your skills or an experienced developer seeking some coding fun, this article aims to provide valuable takeaways for everyone. Stay tuned as we dive into the world of CodeWars challenges.

**Multiples of 3 or 5**

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Finish the solution so that it returns the sum of all the multiples of 3 or 5 below the number passed in. Additionally, if the number is negative, return 0 (for languages that do have them).

Note: If the number is a multiple of both 3 and 5, only count it once.

**Solution**

1
2

def solution(n):
return sum([i for i in range(n) if i % 3 == 0 or i % 5 == 0]) # List Comprehension

In the function `solution(n)`

, I used list comprehension to create a list of numbers less than n that are divisible by either 3 or 5. Then, I used the `sum()`

function to calculate the sum of these multiples. If `n`

is negative, the function returns 0 since the list will be empty.

**Stop gninnipS My sdroW!**

Write a function that takes in a string of one or more words, and returns the same string, but with all five or more letter words reversed (Just like the name of this Kata). Strings passed in will consist of only letters and spaces. Spaces will be included only when more than one word is present.

Examples:

1
2
3

spinWords( "Hey fellow warriors" ) => returns "Hey wollef sroirraw"
spinWords( "This is a test") => returns "This is a test"
spinWords( "This is another test" )=> returns "This is rehtona test"

**Solution**

1
2

def spin_words(sentence):
return ' '.join(i[::-1] if len(i) > 4 else i for i in sentence.split())

In the `spin_words(sentence)`

function, the input sentence is broken down into individual words using `sentence.split()`

. For each word, I check its length. If the length is more than 4 characters, I reverse it using slicing `i[::-1]`

. Otherwise, I keep it as is.

Then, I join all the processed words back into a single string using `' '.join()`

and return it.

**Find the odd int**

Given an array of integers, find the one that appears an odd number of times.

There will always be only one integer that appears an odd number of times.

Examples

`[7]`

should return`7`

, because it occurs 1 time (which is odd).`[0]`

should return`0`

, because it occurs 1 time (which is odd).`[1,1,2]`

should return`2`

, because it occurs 1 time (which is odd).`[0,1,0,1,0]`

should return`0`

, because it occurs 3 times (which is odd).`[1,2,2,3,3,3,4,3,3,3,2,2,1]`

should return`4`

, because it appears 1 time (which is odd).

**Solution**

1
2
3
4
5

def find_it(seq):
for i in seq:
x = seq.count(i)
if x % 2 != 0:
return i

**Enhanced Solution**

1
2

def find_it(seq):
return [x for x in seq if seq.count(x) % 2][0]

In the initial `find_it(seq)`

function, a loop iterates through each integer in the array `seq`

. For each integer, the function counts its occurrences using `seq.count(i)`

. If the count is odd, the integer is returned.

In the enhanced version, list comprehension is used to create a list of integers that appear an odd number of times. The `[0]`

at the end returns the first element of this list, which is the answer.

The enhanced solution is better because it’s more concise. However, both solutions have the same time complexity due to the use of `seq.count(x)`

, making them inefficient for large lists.

**Who likes it?**

You probably know the “like” system from Facebook and other pages. People can “like” blog posts, pictures or other items. We want to create the text that should be displayed next to such an item.

Implement the function which takes an array containing the names of people that like an item. It must return the display text as shown in the examples:

1
2
3
4
5

[] --> "no one likes this"
["Peter"] --> "Peter likes this"
["Jacob", "Alex"] --> "Jacob and Alex like this"
["Max", "John", "Mark"] --> "Max, John and Mark like this"
["Alex", "Jacob", "Mark", "Max"] --> "Alex, Jacob and 2 others like this"

Note: For 4 or more names, the number in `"and 2 others"`

simply increases.

**Solution**

1
2
3
4
5
6

def likes(names):
if len(names) == 0: return "no one likes this"
elif len(names) == 1: return f"{names[0]} likes this"
elif len(names) == 2: return f"{names[0]} and {names[1]} like this"
elif len(names) == 3: return f"{names[0]}, {names[1]} and {names[2]} like this"
else: return f"{names[0]}, {names[1]} and {len(names)-2} others like this"

**Enhanced Solution**

1
2
3
4
5
6
7
8
9

def likes(names):
n = len(names)
return {
0: 'no one likes this',
1: '{} likes this',
2: '{} and {} like this',
3: '{}, {} and {} like this',
4: '{}, {} and {others} others like this'
}[min(4, n)].format(*names[:3], others=n-2)

In the initial `likes(names)`

function, multiple `if-elif-else`

statements are used to handle different cases based on the length of the `names`

list. It returns the appropriate string format for each case.

The enhanced version uses a dictionary to map the number of names to the corresponding string format. It then uses the `format()`

method to fill in the placeholders. The `min(4, n)`

ensures that all cases with 4 or more names use the same string format.

The enhanced solution is better because it’s more concise and easier to maintain. If you need to change the format of the output string, you only have to update it in one place, making the code more DRY (Don’t Repeat Yourself).

**Sum of Digits / Digital Root**

Digital root is the recursive sum of all the digits in a number.

Given `n`

, take the sum of the digits of `n`

. If that value has more than one digit, continue reducing in this way until a single-digit number is produced. The input will be a non-negative integer.

Example

1
2
3
4

16 --> 1 + 6 = 7
942 --> 9 + 4 + 2 = 15 --> 1 + 5 = 6
132189 --> 1 + 3 + 2 + 1 + 8 + 9 = 24 --> 2 + 4 = 6
493193 --> 4 + 9 + 3 + 1 + 9 + 3 = 29 --> 2 + 9 = 11 --> 1 + 1 = 2

**Solution**

1
2

def digital_root(n):
return n if n < 10 else digital_root(sum([int(i) for i in str(n)]))

**Enhanced Solution**

1
2

def digital_root(n):
return n%9 or n and 9

The first `digital_root(n)`

function employs recursion to keep summing the digits of `n`

until a single-digit number is reached. If `n`

is already a single digit, it’s returned immediately. Otherwise, the function sums the digits and calls itself again.

On the other hand, the enhanced function leverages a mathematical trick: the digital root of a number `n`

is the same as `n % 9`

. The only exception is when `n`

is a multiple of 9. In that case, the digital root is 9, not 0. This optimized version is more efficient, particularly for large numbers, as it computes the digital root in constant time.