🎉 Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io 🎉
Avatar of Cueball

Cueball's solution

to Prime Factors in the Ruby Track

Published at Jun 07 2020 · 0 comments
Instructions
Test suite
Solution

Compute the prime factors of a given natural number.

A prime number is only evenly divisible by itself and 1.

Note that 1 is not a prime number.

Example

What are the prime factors of 60?

  • Our first divisor is 2. 2 goes into 60, leaving 30.
  • 2 goes into 30, leaving 15.
    • 2 doesn't go cleanly into 15. So let's move on to our next divisor, 3.
  • 3 goes cleanly into 15, leaving 5.
    • 3 does not go cleanly into 5. The next possible factor is 4.
    • 4 does not go cleanly into 5. The next possible factor is 5.
  • 5 does go cleanly into 5.
  • We're left only with 1, so now, we're done.

Our successful divisors in that computation represent the list of prime factors of 60: 2, 2, 3, and 5.

You can check this yourself:

  • 2 * 2 * 3 * 5
  • = 4 * 15
  • = 60
  • Success!

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 prime_factors_test.rb

To include color from the command line:

ruby -r minitest/pride prime_factors_test.rb

Source

The Prime Factors Kata by Uncle Bob http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata

Submitting Incomplete Solutions

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

prime_factors_test.rb

require 'minitest/autorun'
require_relative 'prime_factors'

class PrimeFactorsTest < Minitest::Test
  def test_1
    assert_equal [], PrimeFactors.of(1)
  end

  def test_2
    skip
    assert_equal [2], PrimeFactors.of(2)
  end

  def test_3
    skip
    assert_equal [3], PrimeFactors.of(3)
  end

  def test_4
    skip
    assert_equal [2, 2], PrimeFactors.of(4)
  end

  def test_6
    skip
    assert_equal [2, 3], PrimeFactors.of(6)
  end

  def test_8
    skip
    assert_equal [2, 2, 2], PrimeFactors.of(8)
  end

  def test_9
    skip
    assert_equal [3, 3], PrimeFactors.of(9)
  end

  def test_27
    skip
    assert_equal [3, 3, 3], PrimeFactors.of(27)
  end

  def test_625
    skip
    assert_equal [5, 5, 5, 5], PrimeFactors.of(625)
  end

  def test_901255
    skip
    assert_equal [5, 17, 23, 461], PrimeFactors.of(901_255)
  end

  def test_93819012551
    skip
    assert_equal [11, 9539, 894_119], PrimeFactors.of(93_819_012_551)
  end
end
require 'Prime'

class PrimeFactors
  def self.of(n)
    raise DomainError if n <= 0
    return [] if n == 1

    # problem has no restriction on using library functions;
    # get the prime factors & exponents; format it as expected
    n.prime_division
      .each_with_object([]) { |(x, exp), obj| obj << [x] * exp }
      .flatten
  end
end

Cueball's Reflection

Finally - a math problem that doesn't impose asinine restrictions on using standard library functionality.