| Problem statement | Source code | Tags: Modular arithmetic
Once we have the list of bus IDs, we can compute the next time each bus arrives, which is the smallest multiple of the bus ID that is greater than or equal to the earliest timestamp: np.ceil(time / buses) * buses. We then find the bus with the smallest arrival time with np.argmin.
If buses[i] departs at timestamp t + i, that means t + i is a multiple of buses[i], or . If we denote each pair as , then we just need to solve the system of congruences for the lowest positive . A nice observation is that all bus IDs are prime numbers, which means that by the Chinese Remainder Theorem, there exists a unique solution for modulo .
To find the solution, we iteratively satisfy each congruence while holding all previous ones true. Start with , , which denotes . For each congruence , we increment by some multiple of to satisfy it, and then update to . Because each time, is a multiple of all previous bus IDs, all previous congruences remain satisfied when is incremented by . To find in , we want , where is the modular inverse of modulo . Last time, it was a lot of trouble because C++ doesn't have either modular exponentiation or big integers built in, but Python has both. So the final code looks like this:
By the way, a trivia: in Python, % is modulo, not remainder, unlike C or its derivatives like JavaScript. This means that the result of x % y takes the sign of y instead of x. This is handy for us since our moduli (bus IDs) are positive.