Skip to content
CCC Python Course

Clock and calendar arithmetic (modulo and periodicity)

Module
M3.8
Lesson
1 of 1
Reading time
4 min

In this lesson

  • Use modulo to work with periodic data like hours, days, and weeks.
  • Solve time-addition problems by adding and using modulo.
  • Recognize periodicity in data and apply modulo to reduce it.
  • Use modulo to handle wrap-around (circular) sequences.

Hours on a clock repeat every 12 or 24 hours. Days of the week repeat every 7 days. Many real-world problems involve this kind of cycling. You can use modulo to handle the wrap-around cleanly.

Modulo finds the remainder after division. In Python, a % b gives the remainder when a is divided by b. For positive numbers, the result is always between 0 and b - 1.

Working with modulo

Think of a 12-hour clock. After hour 11 comes hour 0. If it is now 10 o'clock and you add 5 hours, what time is it?

10 + 5 = 1515 % 12 = 3

It is 3 o'clock. The modulo wraps the result back into the valid range 0 to 11.

On a clock with 24 hours, you use modulo 24. In a week with 7 days, you use modulo 7. The modulus is the period of the cycle.

Modulo is powerful because it handles wrap-around without explicit conditionals or loops. Instead of writing code that counts 10, 11, 12, 0, 1, 2, 3, you just compute (10 + 5) % 12. The modulo operation does the wrapping automatically. This makes code simpler and less error-prone. It also makes the algorithm clear: you are working with a cyclic structure.

Periodic scheduling

Say an event repeats every 3 days, starting on day 0. When does it occur? On days 0, 3, 6, 9, 12, and so on. Day d has the event if d % 3 == 0.

If the event starts on day 1 and repeats every 5 days, it occurs on days 1, 6, 11, 16, and so on. Day d has the event if (d - 1) % 5 == 0, or equivalently, if d % 5 == 1.

Here is a program that counts how many times a recurring event happens in a given number of days:

examples/event_count.py
period = int(input())offset = int(input())days = int(input())
count = 0for d in range(days):    if d % period == offset % period:        count += 1
print(count)

Input

3
1
10

Output

3
Counting occurrences of a periodic event

The program reads the period, the offset (which day the first event is on), and the total number of days. It counts how many multiples of the period, plus the offset, fall within the range.

Circular sequences

Modulo is useful for cycling through a list. If you have a list of items and want to index them in a repeating pattern, use modulo.

Days of the week are: Monday (0), Tuesday (1), ..., Sunday (6). If today is Tuesday (day 1) and you add 10 days, what day is it?

1 + 10 = 1111 % 7 = 4

It is Friday (day 4). The modulo keeps the index in the valid range.

A calendar example

Modulo also handles longer calendars, not just a single week. Suppose day 0 of a year is a Monday, and a problem asks which day of the week day 100 falls on.

Python
day_names = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]day_number = 100print(day_names[day_number % 7])

100 % 7 is 2, so day_names[2] is "Wednesday". The same idea scales to any day count. A problem asking about day 10,000 needs no more work than one asking about day 10. The remainder after dividing by 7 is all that ever mattered, and computing it costs the same regardless of how large the day number gets. This is the same lookup-table pattern from an earlier lesson, with modulo supplying the index instead of the raw day number.

Handling large numbers with modulo

Modulo is also useful when numbers get very large. Suppose a machine cycles through states 0, 1, 2, 3, and then back to 0. After 1,000,000 cycles, which state is it in?

Python
state = 1000000 % 4

The answer is state 0. Without modulo, you would have to count 1 million steps. Modulo gives the answer instantly.

This applies to any repeating sequence. If you know the period, you can jump directly to the current position without simulating every step.

Common mistakes

One mistake is forgetting that modulo has a lower bound. In Python, a % b is always between 0 and b - 1 for positive b. If a is negative, the result can be negative. For time problems, keep your numbers positive. If you must work with negative numbers, add the modulus to shift them into range: (a % b + b) % b ensures a result between 0 and b - 1.

Another mistake is using the wrong modulus. If a pattern repeats every 12 hours, use modulo 12. If it repeats every 7 days, use modulo 7. Confusing the cycle period causes wrong answers. Think carefully about what the period is before you write the code.

A third mistake is reducing each side with modulo but forgetting to reduce the sum. (a % m) + (b % m) can add up to as much as 2 * m - 2, which is outside the valid range 0 to m - 1. The safe pattern always applies modulo to the whole sum last: (a + b) % m, or, if you already reduced a and b separately for some other reason, ((a % m) + (b % m)) % m.

A fourth mistake is assuming modulo works with negative divisors. Always use a positive modulus. Modulo with negative divisors behaves differently across languages and is a source of bugs.

Modulo makes periodic problems simple. Whenever a problem describes a repeating cycle, a fixed number of hours, days, positions, or states, that keeps coming back around, reach for modulo. It turns a problem that looks like it needs a step-by-step simulation into one you can solve directly with arithmetic, no matter how large the numbers involved get.

Practice

Try these on the judges. Each link opens the problem on WMOJ or DMOJ.

  1. 2024 S1
    Hat Circle (opens on WMOJ in a new tab) WMOJ

    Compare values at paired positions around a circular arrangement, wrapping the index with modulo.

  2. 2017 J4
    Favourite Times (opens on DMOJ in a new tab) DMOJ

    Count occurrences of a periodic event across a long span, using cycles and a remainder.

    Why DMOJ: A periodicity problem matching this lesson's cycle-and-remainder pattern.