Dan Rubio
Dan Rubio

Reputation: 4887

Fixnum class method modification

This is a description of a code kata that I'm working on for code wars. The aim of the kata is to accomplish this:


The aim of this Kata is to modify the Fixnum class to give it the palindrome_below method. This method returns all numbers from and including 1 up to but not including itself that are palindromes for a given base.

For example in base 2 (binary)

 1 = "1"
 2 = "10"
 3 = "11"
 4 = "100"

Therefore 1 and 3 are palindromes in base two and the method should return the following.

5.palindrome_below(2)
=> [1, 3]

Here is the code that I wrote so far for this kata:

class Fixnum
  def self.palindrome_below(binary)
    palindrome_match = []
    until self == 0
      if to_s(binary) == to_s(binary).reverse
       palindrome_match << self
       self -= 1
      end
    end
    palindrome_match
  end
end

I tried to decrease self by 1. Sublime is telling me that I'm not able to decrease the value of self but I need to reduce self. Because this is a class method, I need to modify self.

This is what I tried as a work around:

class Fixnum
  def self.palindrome_below(binary)
    palindrome_match = []
    self_placeholder = self
    until self_placeholder == 0
      if self_placeholder.to_s(binary) == self_placeholder.to_s(binary).reverse
        palindrome_match << self_placeholder
        self_placeholder -= 1
      end
    end
    palindrome_match
  end
end

This time, I placed self in a wrapper variable so I could modify it. When I try this, it says that there is an undefined method called palindrome_below. Doing this implementation should have monkey patched Fixnum. I'm not sure what I'm doing wrong. Can someone point me in the right direction?

Upvotes: 0

Views: 555

Answers (1)

charlierproctor
charlierproctor

Reputation: 1182

A Working Solution (based your second attempt above):

class Fixnum
    def palindrome_below(base)
        palindrome_match = []
        num = self - 1
        until num == 0
            if num.to_s(base) == num.to_s(base).reverse
                palindrome_match << num
            end
            num -= 1
        end
       palindrome_match.reverse
    end
end

What I changed:

  1. You were right in adding a self_placeholder -- I named this variable num. In Ruby, Fixnums are immutable, so you can't change the value of the particular Fixnum itself.
    • I subtracted 1 from num right at the beginning, so as to avoid including the number itself in the result array
  2. palindrome_below(base) needs to be an instance method. You very much care about the value of the specific instance of the Fixnum class (ie., the value of the number).
  3. You need to subtract 1 from num outside your if statement.
  4. I reversed the palindrome_match array so that it returns in the proper ascending order.

A Far Superior Solution (courtesy of @CarySwoveland's comment above).

class Fixnum
    def palindrome_below(base)
        1.upto(self-1).select { |num| num.to_s(base) == num.to_s(base).reverse }
    end
end

Upvotes: 1

Related Questions