rubygreatest-common-divisorknuth

Testing a counter for an introductory exercise for TAOCP Knuth


The exercise in the first chapter of Vol 1 of The art of computer Programming by Donald Knuth- Has to do with taking the averages of remainder steps using Euclid's gcd algorithm. My code returns the GCD perfectly and has been tested to do so. I cannot get it to return the remainder steps and my second test marked failing test with a comment in the code fails to get the correct remainder steps, and will only return 1 for gcdRemainerSteps on the gcdTestObject.

require 'minitest/autorun'


class GCDTest < Minitest::Test 
  def test_euclid_gcd
    gcdTestObject=GCD.new(20,5)
    assert gcdTestObject.euclidGcd==5
        assert gcdTestObject.gcdRemainderSteps==1

    end

    def test_euclid_two
        gcdTestObject=GCD.new(13,8)
        assert gcdTestObject.euclidGcd==1
    #Failing TEST Passes on 1 not on 5 
    assert gcdTestObject.gcdRemainderSteps==5
    end
end



class GCD
    attr_accessor :m,:n 
    def initialize(m,n)
        @m=m
        @n=n
    end

    def euclidGcd
        r= @m % @n
        until r==0 
            @m=@n
            @n=r
            r= @m % @n
        end
        return @n   
    end

    def gcdRemainderSteps
        r=@m % @n
        counter=1
        until r==0 
            counter+=1
            @m=@n
            @n=r
            r=@m % @n

        end
        return counter
    end
end

A second piece of code that I have written to test counting in an until program works splendidly and It passed all the test perfectly.

And this returns counter at 100 as expected and the test are in the green.

#until_loop_test.rb
require 'minitest/autorun'


class Until_test < Minitest::Test

    def test_till_100_steps
        myUntilTestObject=UntilTester.new

        assert myUntilTestObject.untilLoopCount==100

    end
end


class UntilTester

    def untilLoopCount
        x=0
        counter=0
        until x==100
            x+=1
            counter+=1
        end
        return counter
    end
end

Solution

  • Maybe GCD's methods ought not be modifying its members. gcdRemainderSteps() is called only after euclidGcd() has modified the member variables.

    I made this change, and the test passes:

    def euclidGcd
        m = @m
        n = @n
        r = m % n
        until r==0
            m = n
            n = r
            r  = m % n
        end
        return n
    end
    

    test results:

    # Running:
    
    ..
    
    Finished in 0.001809s, 1105.5202 runs/s, 2211.0405 assertions/s.
    
    2 runs, 4 assertions, 0 failures, 0 errors, 0 skips