#ruby
#ruby
Вопрос:
Это описание ката кода, над которым я работаю для code wars. Цель ката — выполнить это:
Цель этого ката — изменить класс Fixnum, чтобы присвоить ему метод palindrome_below . Этот метод возвращает все числа от 1 до 1 включительно, но не включая себя, которые являются палиндромами для данной базы.
Например, в базе 2 (двоичной)
1 = "1"
2 = "10"
3 = "11"
4 = "100"
Следовательно, 1 и 3 являются палиндромами в базе два, и метод должен возвращать следующее.
5.palindrome_below(2)
=> [1, 3]
Вот код, который я написал до сих пор для этого ката:
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
Я попытался уменьшить self
на 1
. Возвышенный говорит мне, что я не могу уменьшить значение self
, но мне нужно уменьшить self
. Поскольку это метод класса, мне нужно изменить self
.
Это то, что я пытался обойти:
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
На этот раз я поместил self
в переменную-оболочку, чтобы я мог ее изменить. Когда я пытаюсь это сделать, он говорит, что вызывается неопределенный метод palindrome_below
. При выполнении этой реализации обезьяна должна быть исправлена Fixnum
. Я не уверен, что я делаю неправильно. Может кто-нибудь указать мне правильное направление?
Комментарии:
1. Нет проблем. Вы можете найти его здесь codewars.com/kata/530d0298e09e54a3620006c2/train/ruby Однако вам, возможно, потребуется зарегистрироваться / войти.
2. Как сказал @sawa, вам, несомненно, нужен метод экземпляра, как у вас в вашем примере:
5.palindrome_below(2)
. Нет необходимости изменятьself
, и на самом деле вы не смогли бы, даже если бы захотели. (Единственными способами измененияself
являются вызов метода или создание класса или модуля.) Попробуйте это:def palendrome(base); 1.upto(self-1).select { |n| ....}
.1
toself-1
будет передан в блок и назначен переменной блокаn
. Вы должны добавить выражение к блоку, которое возвращаетtrue
значение if и толькоn
вычисляет значение palendrome для заданного значения параметраbase
.3. @CarySwoveland — Я думаю, что ваше решение намного лучше, чем общепринятый ответ — почему вы не опубликовали его как один?
4. Спасибо, @Uri, но у меня не было достаточно времени, чтобы опубликовать правильный ответ. Если это поможет, этого достаточно.
Ответ №1:
Рабочее решение (основанное на вашей второй попытке выше):
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
Что я изменил:
- Вы были правы, добавив
self_placeholder
— я назвал эту переменнуюnum
. В RubyFixnum
s являются неизменяемыми, поэтому вы не можете изменить значение самого конкретногоFixnum
.- Я вычел 1 из
num
самого начала, чтобы избежать включения самого числа в результирующий массив
- Я вычел 1 из
palindrome_below(base)
должен быть метод экземпляра. Вы очень заботитесь о значении конкретного экземпляра класса Fixnum (т. Е. О значении числа).- Вам нужно вычесть 1 из
num
-за пределов вашегоif
оператора. - Я перевернул
palindrome_match
массив так, чтобы он возвращался в правильном порядке возрастания.
Гораздо лучшее решение (любезно предоставлено комментарием @CarySwoveland выше).
class Fixnum
def palindrome_below(base)
1.upto(self-1).select { |num| num.to_s(base) == num.to_s(base).reverse }
end
end