FizzBuzz Implementation: A Step-by-Step Guide in Ruby
# Problem Statement
# The FizzBuzz problem is a classic coding challenge used to test a programmer's understanding of basic control flow, loops, and conditional statements. The task involves:
# Printing numbers from 1 to 100.
# Replacing certain numbers with specific words:
# Replace multiples of 3 with "Fizz".
# Replace multiples of 5 with "Buzz".
# Replace multiples of both 3 and 5 with "FizzBuzz".
# If a number is not a multiple of either 3 or 5, print the number itself.
# This problem requires:
# Iterating through a range of numbers.
# Applying modular arithmetic to identify divisibility.
# Printing appropriate outputs based on conditions.
# fizz_buzz.rb
# FizzBuzz implementation
class FizzBuzz
# Method to generate fizzbuzz for a range
def self.generate(range)
validate_range(range)
range.map { |number| evaluate(number) }
end
# Method to evaluate what to print for each number
def self.evaluate(number)
validate_number(number)
if number % 3 == 0 && number % 5 == 0
"FizzBuzz"
elsif number % 3 == 0
"Fizz"
elsif number % 5 == 0
"Buzz"
else
number.to_s
end
end
private
# Validate that the range is valid
def self.validate_range(range)
unless range.is_a?(Range) && range.first.is_a?(Integer) && range.last.is_a?(Integer)
raise ArgumentError, "Input must be a valid range of integers."
end
end
# Validate that the number is an integer
def self.validate_number(number)
raise ArgumentError, "Input must be an integer." unless number.is_a?(Integer)
end
end
# Print FizzBuzz results for 1 to 100
puts "FizzBuzz Results (1 to 100):"
FizzBuzz.generate(1..100).each { |result| puts result }
# Test cases using RSpec
if __FILE__ == $0
require 'rspec/autorun'
RSpec.describe FizzBuzz do
describe '.evaluate' do
context 'when the number is divisible by both 3 and 5' do
it 'returns "FizzBuzz"' do
expect(FizzBuzz.evaluate(15)).to eq("FizzBuzz")
expect(FizzBuzz.evaluate(30)).to eq("FizzBuzz")
end
end
context 'when the number is divisible only by 3' do
it 'returns "Fizz"' do
expect(FizzBuzz.evaluate(3)).to eq("Fizz")
expect(FizzBuzz.evaluate(9)).to eq("Fizz")
end
end
context 'when the number is divisible only by 5' do
it 'returns "Buzz"' do
expect(FizzBuzz.evaluate(5)).to eq("Buzz")
expect(FizzBuzz.evaluate(20)).to eq("Buzz")
end
end
context 'when the number is not divisible by 3 or 5' do
it 'returns the number as a string' do
expect(FizzBuzz.evaluate(1)).to eq("1")
expect(FizzBuzz.evaluate(7)).to eq("7")
end
end
context 'when input is invalid' do
it 'raises an error for non-integer input' do
expect { FizzBuzz.evaluate("three") }.to raise_error(ArgumentError, "Input must be an integer.")
expect { FizzBuzz.evaluate(nil) }.to raise_error(ArgumentError, "Input must be an integer.")
end
end
end
describe '.generate' do
it 'generates the correct sequence for a given range' do
result = FizzBuzz.generate(1..15)
expected = [
"1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz",
"11", "Fizz", "13", "14", "FizzBuzz"
]
expect(result).to eq(expected)
end
context 'when the input range is invalid' do
it 'raises an error for non-range input' do
expect { FizzBuzz.generate("1..15") }.to raise_error(ArgumentError, "Input must be a valid range of integers.")
expect { FizzBuzz.generate(nil) }.to raise_error(ArgumentError, "Input must be a valid range of integers.")
end
it 'raises an error if range contains non-integer values' do
expect { FizzBuzz.generate(1.0..15.0) }.to raise_error(ArgumentError, "Input must be a valid range of integers.")
end
end
end
end
end
Run this Code
Save the Ruby code in a file named FizzBuzz.rb
and execute it using the command: ruby FizzBuzz.rb
.