Puzzles to improve Python
After coding in Python for some time, I find programming puzzles to be an exciting way to keep my brain in shape and, most importantly, improve my coding skills. Having worked with veteran Python developers, I have concluded that a professional software programmer must have critical thinking and algorithmic-solving skills.
I compiled a list of puzzles to improve Python. I hope this blog post serves as a humble guide for anyone interested in improving their Python by solving puzzles.
This article teaches how to improve your Python through puzzles.
Puzzle 1
Define a function that takes an integer number as input and prints the “It is an even number” if the number is even, otherwise prints “It is an odd number”.
Solution
Based on simple arithmetic, an even number returns 0 for the remainder when divided by 2. For example, 4/2 =2 and the remainder is 0. With such logic, we can tell if a number is even or not by dividing it by 2. We make use of the built-in Python operator % to find the remainder.
def check_num(num):
if num % 2 == 0:
print("It is an even number.")
else:
print("It is an odd number.")
Puzzle 2
Find the minimum of an array without using Python’s min() built-in, then find the maximum.
Solution
We assign the minimum to the first element and then compare it with other elements inside the array. If the next element is smaller we assign the minimum to it. We keep doing so until the array is finished.
def find_min(array=[]):
minimo = array[0]
for el in array[1:]:
if minimo > el:
minimo = el
return minimo
We do the opposite for finding the maximum element in the array.
def find_max(array=[]):
max = array[0]
for el in array[1:]:
if max < el:
max = el
return max
Puzzle 3
Define a function that can print a dictionary where the keys are numbers between 1 and 3 (both included) and the values are the squares of the keys.
Solution
First, define the keys inside a list. Then use a for loop to assign the key-value pairs to the dictionary.
def gen_dict():
d = {}
keys = [1, 2, 3]
for el in keys:
d[el] = el * el
return d
Puzzle 4
Write a program to generate and print another tuple whose values are even numbers in the given tuple (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).
Solution
The trick here is to store the even numbers inside a Python list and to convert it into a tuple object.
def gen_tup():
tup = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
num_list = []
for el in tup:
if el % 2 == 0:
num_list.append(el)
num_list = tuple(num_list)
return num_list
Puzzle 5
Write a program that accepts a string as input and prints “Yes” if the string is “yes” or “YES” or “Yes;” otherwise, print “No.”
Solution
The key solution here is to store the strings “yes”, “Yes” and “YES” inside a list. Then do a check for the input within the list.
def check_string():
check_list = ["yes", "Yes", "YES"]
sq = raw_input("Enter the sequence:")
if sq in check_list:
print("Yes")
else:
print("No")
Puzzle 6
Write a function to compute 5/0 and use try/except to catch the exceptions.
Solution
Python offers the try/except block to catch errors and handle them in various ways. When you try to divide a number by zero Python throws the ZeroDivisionError.
def doesnt_throw():
try:
5/0
except ZeroDivisionError:
print("Division by zero.")
except Exception, err:
print("Caught an exception.")
finally:
print("Final block for cleanup.")
Puzzle 7
Use the assert statement to verify that every number in the list [2, 4, 6, 8] is even.
Solution
The assert statement in Python tests if a condition is True. If the condition is False, AssertionError is raised. Check if any element returns 0 when divided by 2.
def check_even():
l = [2, 4, 6, 8]
for el in l:
assert(el%2 == 0)
Puzzle 8
Add two numbers without using the addition operator.
Solution
The direct idea is to use the subtract operator. However, that would work only for positive numbers, so it’s not a solution. The following is a better approach.
def add_nums_no_plus(a, b):
while (a > 0):
a -= 1
b += 1
while a < 0:
b -=1
a += 1
return b
If a is greater than zero, we drain it to zero and add each of the units to b. If a is less than zero, we fill it to zero and subtract each of the units from b.
Puzzle 9
Sort an array without using the built-in method. [13, 14, 11, 2, 1] –> [1, 2, 11, 13, 14]
Solution
My idea of solving this puzzle is to create a fresh empty list and then populate it with each minimum of the given array.
def sort_array(array):
# [13, 14, 11, 2, 1] --> [1, 2, 11, 13, 14]
sorted_list = []
while len(array) > 0:
minimal = find_min(array)
sorted_list.append(minimal)
array.remove(minimal)
return sorted_list
As you can see from the solution provided above, we use the find_min from the second puzzle. A better approach to sorting an array would be the implementation of bubble sort or insertion sort algorithms.
Puzzle 10
Write a program that accepts a sentence and calculates the number of uppercase letters and lowercase letters. Suppose the following input is provided to the program:
Hello World!
Then the output should be:
UPPER CASE 2
LOWER CASE 9
Solution
Create a dictionary with UPPER_CASE, and LOWER_CASE as keys mapped to list objects. Use a for loop to populate each one of the lists. Python’s string built-in methods isupper and islower can be used to determine if a character is an uppercase or lowercase letter.
def uppercase_lowercase():
d = {'UPPER_CASE':[], 'LOWER_CASE':[]}
sequence = input("Type here:")
for c in sequence:
if c.isupper():
d['UPPER_CASE'].append(c)
elif c.islower():
d['LOWER_CASE'].append(c)
print('UPPER CASE %d' % len(d['UPPER_CASE']))
print('LOWER CASE %s' % len(d['LOWER_CASE']))
Puzzle 11
Write a program to compute the factorial of a given number.
Solution
The built-in range function becomes useful in our case. We compute the list of factors with the help of it. We then generate the factorial as shown in the following piece of code.
def factorial(number):
result = 1
factors = range(number+1)[1:]
for factor in factors:
result *= factor
return result
Although the above algorithm works fine, the following solution is more professional and elegant.
def fact(num):
if num == 0:
return 1
return num * fact(num-1)
Puzzle 12
Write a program that computes a value of a + aa + aaa + aaaa with a given digit as the value of a. Suppose the following input is supplied to the program:
9
Then, the output should be:
11106
Solution
Convert each one of the strings into an integer. Use the int() built-in in Python.
def compute_expression():
a = input("Enter digit:")
num1 = int("%s" % a)
num2 = int("%s%s" % (a, a))
num3 = int("%s%s%s" % (a, a, a))
num4 = int("%s%s%s%s" % (a, a, a, a))
s = num1 + num2 + num3 + num4
return s
Puzzle 13
Write a program that will find all the numbers that are divisible by 7 but are not a multiple of 5, between 2000 and 3200. The numbers should be printed in a comma-separated sequence on a single line.
Solution
Use the % operator in Python to find the remainder. A number divisible by 7 returns 0 as the remainder when you divide it by 7.
def divisible7():
nums = []
for el in range(2001, 3200):
if el % 7 == 0 and el % 5 != 0:
nums.append(el)
line = ','.join(str(num) for num in nums)
print(line)
Puzzle 14
Write a program to generate all the sentences where the subject is in [“I”, “You”], the verb is in [“Play”, “Love”] and the object is in [“Hockey”, “Football”].
Solution
The solution to this puzzle involves nested for loops.
def all_sentences():
sentence = ""
subjects = ["I", "You"]
verbs = ["Play", "Love"]
objects = ["Hockey", "Football"]
for subject in subjects:
for verb in verbs:
for obj in objects:
sentence = " ".join([subject, verb, obj])
print(sentence)
sentence = ""
Puzzle 15
Write a program that accepts a sequence of comma-separated values from the console and generates a list and a tuple that contains every number. Suppose the following input is supplied to the program:
34, 67, 55, 33, 12, 98
Then the output should be:
[34, 67, 55, 33, 12, 98]
(34, 67, 55, 33, 12, 98)
Solution
Use Python’s string builtin method split.
def sequence_convert():
sequence = input()
l = sequence.split(',')
t = tuple(l)
print(l)
print(t)
Puzzle 16
Define a function that can accept two strings as input and print the string with maximum length on the console. If two strings have the same length, then the function should print both strings line by line.
Solution
The if, else, elif Python conditionals can be easily implemented for the solution of this puzzle.
def longer_string(s1, s2):
first_length = len(s1)
second_length = len(s2)
if first_length - second_length > 0:
print(s1)
elif first_length - second_length == 0:
print(s1)
print(s2)
else:
print(s2)
Puzzle 17
Write a program to filter even numbers in a list using the filter function. The list is [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].
Solution
The filter function is a built-in utility in Python that takes for arguments a function and an iterable. It filters any element that proves True to the function out of the iterable. Use a lambda expression to check if the remainder is 0 when the element is divided by 2.
def filter_list():
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_nums = filter(lambda x:x%2==0, l)
print(list(even_nums))
Puzzle 18
When squirrels get together for a party, they like to have cigars. A squirrel party is successful when the number of cigars is between 40 and 60, inclusive. Unless it is the weekend, in which case there is no upper bound on the number of cigars. Return True if the party with the given values is successful, or False otherwise.
cigar_party(30, False)->False
cigar_party(50, False)->True
cigar_party(70, True)->True
cigar_party(70, False)->False
Solution
def cigar_party(cigars, is_weekend):
if cigars >= 40:
if is_weekend:
return True
else:
return cigars <= 60
return False
Puzzle 19
Given two ints a, and b, return their sum. However, sums in the range 10..19 inclusive, are forbidden, so in that case just return 20.
Solution
def sorta_sum(a, b):
total = a + b
if total in range(10, 20):
return 20
return total
Puzzle 20
The number 6 is truly great. Given two int values, a and b, return True if either one is 6. Or if their sum or difference is 6.
# love6(6, 4)–>True
# love6(4, 5)–>False
# love6(1, 5)–>True
Solution
The abs built-in utility is useful in such cases.
def love6(a, b):
if a == 6 or b == 6:
return True
if abs(a-b) == 6 or (a+b) == 6:
return True
return False
Puzzle 21
Given three int values, a b c, return their sum. However, if one of the values is 13, then it does not count towards the sum and the values to its right do not count. So for example, if b is 13 then both b and c do not count.
Solution
def lucky_sum(a, b, c):
if a == 13:
return 0
elif b == 13:
return a
elif c == 13:
return a+b
else:
return a + b + c
Puzzle 22
For this problem, we’ll round an int value up to the next multiple of 10 if its rightmost digit is 5 or more, so 15 rounds up to 20. Alternately, round down to the previous multiple of 10 if its rightmost digit is less than 5, so 12 rounds down to 10. Given 3 ints, a b c, return the sum of their rounded values. To avoid code repetition, write a separate helper “def round10(num):” and call it 3 times.
Solution
def round10(num):
if num < 5:
return 0
if num % 10 == 0:
return num
if num % 10 >= 5:
return num + (10 - (num % 10))
if num % 10 < 5:
return num - (num % 10)
def round_sum(a, b, c):
return round10(a) + round10(b) + round10(c)
Puzzle 23
Given 3 int values, a b c, return their sum. However, if any of the values is a teen — in the range 13..19 inclusive– then that value counts as 0, except 15 and 16 do not count as teens. Write a separate helper “def fix_teen(n):” that takes n as an int value and returns that value fixed for the teen rule.
# no_teen_sum(1, 2, 3)–>6
# no_teen_sum(2, 13, 1)–>3
# no_teen_sum(2, 1, 14–>3
Solution
def fix_teen(n):
if n in range(13, 20):
if n in (15, 16):
return n
return 0
return n
def no_teen_sum(a, b, c):
return fix_teen(a) + fix_teen(b) + fix_teen(c)
Puzzle 24
Given 3 int values, a b c, return their sum. However, if one of the values is the same as another of the values, it does not count toward the sum.
# lone_sum(1, 2, 3)->6
# lone_sum(3, 2, 3)->2
# lone_sum(3, 3, 3)->0
Solution
def lone_sum(a, b, c):
if a==b and a==c:
return 0
elif a==b and a!=c:
return c
elif a==c and a!=b:
return b
elif c==b and c!=a:
return a
else:
return a + b + c
Puzzle 25
We want to make a package of goal kilos of chocolate. We have small bars (1 kilo each) and big bars (5 kilos each). Return the number of small bars to use, assuming we always use big bars before small bars. Return -1 if it can’t be done.
# make_chocolate(4, 1, 9)–>4
# make_chocolate(4, 1, 10)–>-1
# make_chocolate(4, 1, 7)–> 2
# make_chocolate(6, 1, 10)–>5
Solution
def make_chocolate(small, big, goal):
# we use the big bars first
if goal//5 <= big:
if goal % 5 <= small:
return goal % 5
else:
return -1
if goal//5 >= big:
if (goal//5 - big) * 5 + (goal%5) <= small:
return (goal//5 -big)*5 + goal % 5
else:
return -1
Puzzle 26
We want to make a row of bricks that is goal inches long. We have several small bricks(1 inch each) and big bricks(5 inches each). Return True if it is possible to make the goal by choosing from the given bricks.
# make_bricks(3, 1, 8)–>True
# make_bricks(3, 1, 9)–>False
# make_bricks(3, 2, 10)–True
Solution
def make_bricks(small, big, goal):
if goal < 5:
return goal <= small
if goal//5 >= big:
return ((goal//5 - big)*5 + (goal % 5)) <= small
if goal//5 <= big:
return (goal % 5) <= small
Puzzle 27
You and your date are trying to get a table at a restaurant. The parameter “you” is the stylishness of your clothes, in the range 0..10, and “date” is the stylishness of your date’s clothes. The result getting the table is encoded as an int value with 0=no, 1=maybe, and 2=yes. If either of you is very stylish, 8 or more, then the result is 2 (yes). With the exception that either of you has a style of 2 or less, then the result is 0 (no).
Otherwise, the result is 1 (maybe).
# date_fashion(5, 10)->2
# date_fashion(5, 2)->0
# date_fashion(5, 5)->1
Solution
def date_fashion(you, date):
if you <=2 or date <=2:
return 0
if you >= 8 or date >= 8:
return 2
else:
return 1
Puzzle 28
The squirrels in Palo Alto spend most of the day playing. In particular, they play if the temperature is between 60 and 90. Unless it is summer, then the upper limit is 100 instead of 90. Given an int temperature and a boolean is_summer, return True if the squirrels play and False otherwise.
# squirrel_play(70, False)->True
# squirrel_play(95, False)->False
# squirrel_play(95, True)->True
Solution
def squirrel_play(temp, is_summer=False):
if temp>=60:
if is_summer:
return temp<=100
else:
return temp<=90
return False
Puzzle 29
Given a day of the week encoded as 0=Sun, 1=Mon, 2=Tue,…6=Sat, and a boolean indicating if we are on vacation, return a string of the form “7:00” indicating when the alarm clock should ring. On weekdays, the alarm should be “7:00” and on the weekend it should be “10:00”. Unless we are on vacation, then on weekdays it should be “10:00” and on weekends it should be “off”.
# alarm_clock(1, False)->’7:00′
# alarm_clock(5, False)->’7:00′
# alarm_clock(0, False)->’10:00′
Solution
def alarm_clock(day, vacation=False):
first_alarm = "7:00"
second_alarm = "10:00"
if day in range(1, 6):
if not vacation:
return first_alarm
else:
return second_alarm
if day == 0 or day == 6:
if not vacation:
return second_alarm
else:
return "off"
Puzzle 30
Given a number n, return True if n is in the range 1..10, inclusive. Unless outside_mode is True, in which case return True if the number is less or equal to 1, or greater or equal to 10.
Solution
def int1to10(n, outside_mode=False):
if outside_mode:
if n <=1 or n >= 10:
return True
else:
return n in range(1, 11)
return False
Final thoughts
Great professional coders made it to the top with hard work. It is a fact. Through this article, you learned how to improve your Python through puzzles.
Although there are exactly 30 puzzles shared here, I am going to add more soon.
Great article on using puzzles to sharpen Python skills! The step-by-step solutions for each puzzle are simple yet effective in building logical thinking. It’s great how you highlighted the importance of practising with real puzzles to enhance coding abilities. The strategy for handling even and odd numbers, especially, is a classic must-know for all Python learners.
If you’re keen on exploring more Python-related topics, you might find some of the content on https://sebbie.pl/tag/python/ quite insightful. It delves into programming and AI themes, which complements your puzzle-based learning approach nicely.
Thanks for sharing these puzzles!
I am still wondering if this a human made or AI comment.