ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

# nihilismus's solution

## to Raindrops in the Ruby Track

Published at Aug 11 2020 · 0 comments
Instructions
Test suite
Solution

Convert a number to a string, the contents of which depend on the number's factors.

• If the number has 3 as a factor, output 'Pling'.
• If the number has 5 as a factor, output 'Plang'.
• If the number has 7 as a factor, output 'Plong'.
• If the number does not have 3, 5, or 7 as a factor, just pass the number's digits straight through.

## Examples

• 28's factors are 1, 2, 4, 7, 14, 28.
• In raindrop-speak, this would be a simple "Plong".
• 30's factors are 1, 2, 3, 5, 6, 10, 15, 30.
• In raindrop-speak, this would be a "PlingPlang".
• 34 has four factors: 1, 2, 17, and 34.
• In raindrop-speak, this would be "34".

For installation and learning resources, refer to the Ruby resources page.

For running the tests provided, you will need the Minitest gem. Open a terminal window and run the following command to install minitest:

``````gem install minitest
``````

If you would like color output, you can `require 'minitest/pride'` in the test file, or note the alternative instruction, below, for running the test file.

Run the tests from the exercise directory using the following command:

``````ruby raindrops_test.rb
``````

To include color from the command line:

``````ruby -r minitest/pride raindrops_test.rb
``````

## Source

A variation on a famous interview question intended to weed out potential candidates. http://jumpstartlab.com

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### raindrops_test.rb

``````require 'minitest/autorun'
require_relative 'raindrops'

# Common test data version: 1.1.0 99de15d
class RaindropsTest < Minitest::Test
def test_the_sound_for_1_is_1
# skip
assert_equal "1", Raindrops.convert(1)
end

def test_the_sound_for_3_is_pling
skip
assert_equal "Pling", Raindrops.convert(3)
end

def test_the_sound_for_5_is_plang
skip
assert_equal "Plang", Raindrops.convert(5)
end

def test_the_sound_for_7_is_plong
skip
assert_equal "Plong", Raindrops.convert(7)
end

def test_the_sound_for_6_is_pling_as_it_has_a_factor_3
skip
assert_equal "Pling", Raindrops.convert(6)
end

def test_2_to_the_power_3_does_not_make_a_raindrop_sound_as_3_is_the_exponent_not_the_base
skip
assert_equal "8", Raindrops.convert(8)
end

def test_the_sound_for_9_is_pling_as_it_has_a_factor_3
skip
assert_equal "Pling", Raindrops.convert(9)
end

def test_the_sound_for_10_is_plang_as_it_has_a_factor_5
skip
assert_equal "Plang", Raindrops.convert(10)
end

def test_the_sound_for_14_is_plong_as_it_has_a_factor_of_7
skip
assert_equal "Plong", Raindrops.convert(14)
end

def test_the_sound_for_15_is_plingplang_as_it_has_factors_3_and_5
skip
assert_equal "PlingPlang", Raindrops.convert(15)
end

def test_the_sound_for_21_is_plingplong_as_it_has_factors_3_and_7
skip
assert_equal "PlingPlong", Raindrops.convert(21)
end

def test_the_sound_for_25_is_plang_as_it_has_a_factor_5
skip
assert_equal "Plang", Raindrops.convert(25)
end

def test_the_sound_for_27_is_pling_as_it_has_a_factor_3
skip
assert_equal "Pling", Raindrops.convert(27)
end

def test_the_sound_for_35_is_plangplong_as_it_has_factors_5_and_7
skip
assert_equal "PlangPlong", Raindrops.convert(35)
end

def test_the_sound_for_49_is_plong_as_it_has_a_factor_7
skip
assert_equal "Plong", Raindrops.convert(49)
end

def test_the_sound_for_52_is_52
skip
assert_equal "52", Raindrops.convert(52)
end

def test_the_sound_for_105_is_plingplangplong_as_it_has_factors_3_5_and_7
skip
assert_equal "PlingPlangPlong", Raindrops.convert(105)
end

def test_the_sound_for_3125_is_plang_as_it_has_a_factor_5
skip
assert_equal "Plang", Raindrops.convert(3125)
end
end``````
``````# frozen_string_literal: true

# Based on: https://refactoring.guru/design-patterns/chain-of-responsibility/ruby/example

class Integer
def factors()
(1..self).select { |number| (self % number).zero? }
end

def factor?(number)
number.factors.include? self
end
end

class Handler
def next_handler=(handler)
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end

def handle(request)
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
end

class AbstractHandler < Handler
attr_writer :next_handler

def next_handler(handler)
@next_handler = handler
handler
end

def handle(request)
return @next_handler.handle(request) if @next_handler

nil
end
end

class Pling < AbstractHandler
def handle(number)
(3.factor?(number) ? 'Pling' : '') + super(number)
end
end

class Plang < AbstractHandler
def handle(number)
(5.factor?(number) ? 'Plang' : '') + super(number)
end
end

class Plong < AbstractHandler
def handle(number)
(7.factor?(number) ? 'Plong' : '') + super(number)
end
end

class Plzng < AbstractHandler
def handle(number)
return number.to_s unless 3.factor?(number) || 5.factor?(number) || 7.factor?(number)

''
end
end

class Raindrops
def self.convert(number)
pling = Pling.new
plang = Plang.new
plong = Plong.new
plzng = Plzng.new

pling.next_handler(plang).next_handler(plong).next_handler(plzng)
pling.handle(number)
end
end``````