Let's solve FizzBuzz! Detailed problem-solving process
Introduction
FizzBuzz is probably one of the most well-known programming problems, and the task is as follows:
- Print the numbers from
1
to100
- If the number is a multiple of
3
, printFizz
- If the number is a multiple of
5
, printBuzz
- If the number is a multiple of both
3
and5
, printFizzBuzz
- If the number is a multiple of
Problem Solving
Basic Solution
The most straightforward solution is to create a function that prints the numbers from 1
to 100
and checks the rules to determine whether to print Fizz
, Buzz
, or FizzBuzz
. However, this approach clearly hardcodes all values into the program, making it inflexible for future condition expansions.
Separating Data and Logic
Since we can expect the rules to be some number
should print some result
, we might use an object to record these key-value structured data:
The data has been separated, but the logic still relies on specific contents in the designated map
object. Let’s write a loop to automatically extract the contents of the map
object, allowing the data to drive the logic:
Keep Values Immutable
The above solution shows that we have defined two variables, i
and output
, and continuously modified their contents in the program. In some programming styles, this is considered a habit to avoid. We can try to change the part where variables are overwritten to use pure functions.
Document Completion and Boundary Case Checking
JavaScript is a dynamically typed language, so others may not be clear about the specific parameter requirements when using this function. Here, we use JSDoc to complete the documentation, and we can also consider using TypeScript for type checking or runtime type validation:
Simplifying numberReplacer
with Partial Application
You might be thinking: Oh my! Why do we have to calculate using numberReplacer
every time just to print FizzBuzz
? Is there a way to create a function that only takes the maximum value? Just like at the beginning? Let’s simplify this by using partial application to create abstraction:
In this problem-solving process, I applied the DRY principle and improved the readability and maintainability of the code through continuous refactoring. However, we can also consider whether it’s really necessary to create more abstraction. Premature optimization is the root of all evil, perhaps YAGNI.