Codewars snippets where I learned something

krz · May 22, 2021

From time to time I practice my python skills in codewars. What I like about it is the clever solutions some people come up with. Let’s look at some examples where I learned some useful tricks.

Is Integer Array? (6 kyu)

This sounds like an easy one. Here is the task:

Write a function with the signature shown below:

def is_int_array(arr):
    return True

returns true / True if every element in an array is an integer or a float with no decimals. returns true / True if array is empty. returns false / False for every other input.

I assumed this was an easy one-liner, something like

def is_int_array(arr):
    return all([i.is_integer() for i in arr if i not isinstance(i, int)])

or something like this. However, I did not consider all the edge cases:

test.assert_equals(is_int_array([]), True, "Input: []")
test.assert_equals(is_int_array([1, 2, 3, 4]), True, "Input: [1, 2, 3, 4]")
test.assert_equals(is_int_array([-11, -12, -13, -14]), True, "Input: [-11, -12, -13, -14]")
test.assert_equals(is_int_array([1.0, 2.0, 3.0]), True, "Input: [1.0, 2.0, 3.0]")
test.assert_equals(is_int_array([1, 2, None]), False, "Input: [1,2, None]")
test.assert_equals(is_int_array(None), False, "Input: None")
test.assert_equals(is_int_array(""), False, "Input: ''")
test.assert_equals(is_int_array([None]), False, "Input: [None]")
test.assert_equals(is_int_array([1.0, 2.0, 3.0001]), False, "Input: [1.0, 2.0, 3.0001]")
test.assert_equals(is_int_array(["-1"]), False, "Input: ['-1']")

I didn’ know that 1.is_integer() returns a SyntaxError, for example.

My actual solution covers all edge cases:

def check_array(arr):
    # check if array is empty array
    if arr == []:
        return True
    # check if array is None or empty string
    if not arr:
        return False
    # loop through each element in array
    for element in arr:
    # check if element is an integer or a float with no decimals
        if not (isinstance(element, int) or (isinstance(element, float) and element.is_integer())):
        # return False if not
            return False
    # return True if all elements pass the check
    return True

This solution works, but it’s not pretty.

Let’s look at other peoples’ solutions. I like this one because it’s short:

def is_int_array(arr):
    try:
        return list(map(int, arr)) == arr
    except:
        return False

However, many developers hate try/except blocks. In addition, this solution creates a new list by mapping each element to an integer. This may not be very efficient.

The most upvoted solution is this one:

def is_int_array(a):
    return isinstance(a, list) and all(isinstance(x, (int, float)) and x == int(x) for x in a)

It’s clever because it immediately returns False if arr is not a list, saving computation. It also early stops if it finds a False value in the loop. And, it’s a one-liner!

Elevator Distance (7 kyu)

Imagine you start on the 5th floor of a building, then travel down to the 2nd floor, then back up to the 8th floor. You have travelled a total of 3 + 6 = 9 floors of distance.

Given an array representing a series of floors you must reach by elevator, return an integer representing the total distance travelled for visiting each floor in the array in order.

// simple examples
elevatorDistance([5,2,8]) = 9
elevatorDistance([1,2,3]) = 2
elevatorDistance([7,1,7,1]) = 18

// if two consecutive floors are the same,
//distance travelled between them is 0
elevatorDistance([3,3]) = 0

Array will always contain at least 2 floors. Random tests will contain 2-20 elements in array, and floor values between 0 and 30.

This is a reminder to myself to use zip more. First, here is the solution I came up with, pretty straightforward:

def elevator_distance(array):
    res = 0
    for i in range(len(array)-1):
     res += abs(int(array[i]) - int(array[i+1]))
    return res

This works, but zip is way more elegant:

def elevator_distance(array):
    return sum(abs(a - b) for a, b in zip(array, array[1:]))

I also found this numpy solution interesting, because it makes use of the vectorized approach:

import numpy as np
def elevator_distance(array):
    return np.sum(np.abs(np.diff(array)))

Twitter, Facebook