Back to questions
Before, you work on this question, make sure you've solved the easier warmup problem Factorial Formula, where you need to write a function to compute factorial as follows:
.
Now that you know the factorial formula, let's define a rotating factorial: instead of multiplying out all the numbers, we rotate between arithmetic operators like multiplication (), floor division (), addition (), and subtraction ().
For example, rotating_factorial(10)
When computing the above equation remember to apply PEMDAS (the order of operations) where multiplication and floor division come before addition/subtraction.
p.s. floor division is a type of division operation that returns the largest integer less than or equal to the result of dividing two numbers (aka we chop off the remainder and return a whole integer).
Floor Division Example:
One way to solve this problem is by simulating a series of operations (multiply, divide, add, subtract) while managing the results step-by-step using a stack. But why do we need a stack?
When we perform operations like multiplication or division, we need to make sure that the previous results are correctly applied before moving on to the next number. A stack helps us manage this process efficiently by allowing us to "store" intermediate results and apply them in the correct order.
For example, when you multiply a number and get a result, you need to save that result before moving on to the next operation. If we didn’t use a stack, it would be harder to keep track of previous results and the order of operations would get confusing. Stacks allow us to easily push results in and later pop them out in the right sequence.
Let’s walk through an example using :
Finally, we add up everything in the stack:
How do we alternate between operations?
The operations follow a cycle: multiply, divide, add, subtract. Once we reach the last operation (subtract), we go back to the first one (multiply). To keep track of this, we use a number that cycles between 0 and 3.
We use a variable called to keep track of which operation we’re currently on (multiply, divide, add, or subtract). Instead of applying modulo directly when checking each operation, we check the value of and then cycle through the operations by updating at the end of each iteration using modulo.
Here’s how it works:
After each operation, we move to the next number and increase the variable. We use at the end of each iteration to ensure the value of resets after (when ), so it goes back to (), and the cycle continues.
This way, we loop through the four operations in the right order, starting with multiply, divide, add, and then subtract, before repeating the cycle.
Here is the full code:
If we write down the operations for a few numbers, we can observe a clear pattern. Let’s calculate the clumsy factorial for a few values:
For ( n = 12 ),
(which is n + 1)
For ( n = 11 ),
(which is n - 1)
For ( n = 10 ),
(which is n + 2)
For ( n = 9 ),
(which is n + 2)
When you compute this for , you’ll see a similar pattern to , and for , you'll observe the same as .
The reason for this repeating pattern lies in the number of operations (multiplication, division, addition, and subtraction) and the number of terms remaining. Since the operations repeat in cycles of four (due to the four basic arithmetic operations), the result will fall into specific predictable outcomes based on the remainder when is divided by . This can be related to modulo arithmetic, which helps us keep track of where we are in the cycle of operations.
Finally, when ( n ) is less than or equal to 4, we have some edge cases:
Now that we’ve established the pattern and considered the edge cases, here’s the complete code: