Skip to content

Activity 1: Charlie

Topic Focus

This activity focuses on Iteration and Recursion, which expands on knowledge learnt about Loop Structures (e.g., for loops, while loops) as well as Selection Statements (if-else). Like most of the content being tested in this module, it also promotes practice with creating Functions as means to solve problems.

Charlie and his mom love being in car rides. One of their favorite things to do whenever they go on a field trip is to look at car plates of vehicles passing by and determine if the plate number is divisible by a given number. Charlie and his mom want you to play along, but they will not tell you how to play the game. They did, however, mention that totalling up each of the digits would help.

For this activity, you may assume that all car plate numbers will have at least ONE (1) digit and at most FOUR (4) digits in them. Additionally, no car plate number starts with the digit zero (0).

Task 0

You begin by observing each car plate number as each vehicle passes by.

Suppose you assign a variable named num to contain the car plate number. Using a loop structure, iterate through each digit in num from right to left. For example, if num is 6230, this should be the result:

0
3
2
6

Task 1

In an attempt to follow their hint, you proceed with trying to add up each digit in the car plate number.

Write a function called sum_of_digits_i(num) that takes in a positive integer called num and returns the total sum of all the digits in the integer. Your function should contain loop structures and not be recursive.

A sample output is as follows:

>>> sum_of_digits_i(6230)
11
Iterating through an Integer Value

One of the ways you could have created your loop structure involved ending as soon as no more digits are to be read (left-to-right direction). This would involve changing num into a string data type, and then iterating through each digit in the string.

Now that you need to add each of these digits to an accumulator sum value, you would then need to cast each digit read back into an int data type. How would you deal with this, preferrably without changing its data type to string in the first place?

Tip

For integer values, try working it from right to left. Namely, read the last digit, and then discard it before passing it into a recursive call to the same function again. Obtaining the last digit involves the modulo/remainder % operator. The way how you removed it though would involve the use of the integer division // operator.

Task 2

Write a function called sum_of_digits_r(num) that takes in a positive integer called num and returns the total sum of all the digits in the integer. Your function should be recursive and not contain any loop structures.

A sample output is as follows:

>>> sum_of_digits_r(6230)
11
Note

Remember: Recursion involves at least 1 base case and at least 1 recursive case.

Recursion involves calling the same function repetitively instead of using a loop structure, until a condition or a set of conditions is met. This condition or set of conditions is regarded as the base case.

Otherwise, the repetitive calling of the same function is carried out - this is regarded as the recursive case.

Implementing Base Case(s) and Recursive Case(s)

How would you approach your base case(s) and recursive case(s)?

Tip

You may have caught on the approach to the iterative solution as dividing off the last integer as soon as you add it to an accumulator sum variable iteratively using the integer division // operator. The iteration stops as soon as you reduce the car plate number value to 0. Use this as your base case.

Should the car plate number (or coincidentally what is left of it) is not 0 yet, you could create your recursive case by adding the last digit, discarding it, then pass the quotient of the integer division to a recursive call to sum_of_digits_r().

Here, you may choose to create a second base case, namely to return a single-digit integer if that is what is left being sent in a recursive call, or to modify the original base case to not check for if the car plate number is 0 but simply less than 10. It really is up to you - pick one that works best, or explore other options of crafting your solution.

Task 3

Write a function called is_divisible_by_3(num) that takes in a positive integer called num and returns True if divisible by 3, and False otherwise. You will need to use either one of the functions created in Tasks 1 or 2 to create this function.

A sample output is as follows:

>>> is_divisible_by_3(6230)
False

>>> is_divisible_by_3(3891)
True
Why did we add those digits up?

Look at the sum of the digits of each car plate number you decide to try out. What about it can help you determine if the car plate number whose digits you added is divisible by 3 or not?

Tip

Notice that when you add up 6230 and 3891, you end up with 11 and 21 respectively. Observe that 11 is not a multiple of 3, but 21 is a multiple of 3.

Task 4

Armed with your way of playing Charlie's game, you begin playing with him and his mother.

Throughout the remainder of the trip, you observed up to 50 more car plate numbers. The template below includes code that generates 50 car plate numbers at random, and stores them in a list structure.

charlie.py
from random import randint


# Task 1
def sum_of_digits_i(num):
    # ...


# Task 2
def sum_of_digits_r(num):
    # ...


# Task 3
def is_divisible_by_3(num):
    # ...


car_plate_numbers = [randint(1, 10000) for _ in range(50)]

Using the given template, complete the program by looping through the list structure car_plate_numbers to check if each car plate number is divisible by 3 or not. A sample output is as follows:

6925 is not divisible by 3
7941 is divisible by 3
4442 is not divisible by 3
5095 is not divisible by 3
1641 is divisible by 3
149 is not divisible by 3
9744 is divisible by 3
7886 is not divisible by 3
...
To Ponder

It is said that iterative and recursive solutions perform differently. Within this context, is there any difference observed, particularly from a timing perspective?

Try modifying your code to run through a different number of car plate numbers, swapping iterative and recursive solutions to be used with is_divisible_by_3(), and including a feature to observe the duration taken by the program to complete.