我是一个绝对的编码初学者,刚刚开始学习ruby。我有一个挑战,我应该检查一个数字是否"彩色"。
当给定数时,子序列中每个数字的乘积不同。这个数字叫做彩色数字。
例如,"263是一个彩色数字,因为[2,6,3,2 * 6,6 * 3,2 *6*3]都是不同的;而236不是彩色的,因为[2,3,6,2 * 3,3 * 6,2 *3*6]有2个6。
取所有连续的数字子集,取它们的乘积,并确保所有乘积都不同。">
在给定的挑战中,我们只接受三位数以内的数字。
所以,由于我是一个初学者,我试图单独编写每个产品。我知道这并不"好"。代码,但我仍然想了解为什么它不工作。我认为应该……但它没有:)
如果有人能告诉我为什么这不起作用,我会很高兴的。我不是在寻找更好的解决办法,我只是想知道为什么我的办法不行。 非常感谢!def colorful?(number)
if number.class != Integer
return false
elsif number.to_s.length > 3
return false
elsif number == 0 || 1
return true
end
digits_arr = number.digits.reverse
product_1 = digits_arr[0]*digits_arr[1]
product_2 = digits_arr[1]*digits_arr[2]
product_3 = digits_arr[0]*digits_arr[1]*digits_arr[2]
final_array = digits_arr + product_1 + product_2 + product_3
if final_array.uniq.length == final_array.length
return true
else
return false
end
end
所以,你最大的问题在这里:
elsif number == 0 || 1
表示"当number等于0时"或"当1为真值时"。在Ruby中,1
总是一个真值,所以这个条件总是满足的,导致执行return true
,终止你的方法并返回true
对于任何值。
一旦你用
elsif number == 0 || number == 1
或
elsif [0,1].include? number
你仍然有一些更多的问题要解决-下一个将是No implicit conversion of Integer into an Array
当你试图添加数字到数组。我希望你能自己解决这个问题。:)
既然我们在这里,有几个小注意事项。
在Ruby中,我们更喜欢duck-typing而不是强类型(主要是因为我们没有强类型),所以任何形式的参数类型检查(比如if number.class != Integer
)都会被抛弃(更不用说它不会很好地工作,因为你会拒绝大量其他Numeric
类——如果你必须检查类,请使用is_a?
或kind_of?
)。注意,如果你的方法被执行时带有非数字的东西,你确实想抛出一个异常,而不是让计算继续——防止系统进入糟糕的状态比调试糟糕的状态并猜测你是如何到达那里的要容易得多。
可能是个人意见,但elsif
很糟糕-几乎总是有更好的方法。在这种情况下,既然你返回在每种情况下,你可以做的事:
return false unless number.is_a? Integer # really unnecessary
return false if number.to_s.length > 3
return true if number == 0 || number == 1
require 'set'
def colorful?(n)
digits = n.digits.reverse
products = Set.new
(1..digits.size-1).each do |n|
digits.each_cons(n) { |a| return false unless products.add?(a.reduce(:*)) }
end
true
end
colorful? 263
#=> true
colorful? 236
#=> false
colorful? 3245
#=> true
看到设置#添加吗?
我可以通过添加一些puts
语句并对上面的两个示例整数执行该方法来最好地展示该方法的工作方式。
def colorful?(n)
digits = n.digits.reverse
puts "digits = #{digits}"
products = Set.new
(1..digits.size-1).each do |n|
puts "n = #{n}"
puts "digits.each_cons(#{n}).to_a #=> #{digits.each_cons(n).to_a}"
digits.each_cons(n) do |a|
m = a.reduce(:*)
puts " a = #{a}, m = #{m}"
puts " products = #{products}"
puts " products.include?(#{m}) = #{products.include?(m)}"
return false unless products.add?(m)
end
end
puts "true is returned"
true
end
colorful? 263
#=> true
显示如下:
digits = [2, 6, 3]
n = 1
digits.each_cons(1).to_a #=> [[2], [6], [3]]
a = [2], m = 2
products = #<Set: {}>
products.include?(2) = false
a = [6], m = 6
products = #<Set: {2}>
products.include?(6) = false
a = [3], m = 3
products = #<Set: {2, 6}>
products.include?(3) = false
n = 2
digits.each_cons(2).to_a #=> [[2, 6], [6, 3]]
a = [2, 6], m = 12
products = #<Set: {2, 6, 3}>
products.include?(12) = false
a = [6, 3], m = 18
products = #<Set: {2, 6, 3, 12}>
products.include?(18) = false
true is returned
colorful? 236
#=> false
显示如下:
digits = [2, 3, 6]
n = 1
digits.each_cons(1).to_a #=> [[2], [3], [6]]
a = [2], m = 2
products = #<Set: {}>
products.include?(2) = false
a = [3], m = 3
products = #<Set: {2}>
products.include?(3) = false
a = [6], m = 6
products = #<Set: {2, 3}>
products.include?(6) = false
n = 2
digits.each_cons(2).to_a #=> [[2, 3], [3, 6]]
a = [2, 3], m = 6
products = #<Set: {2, 3, 6}>
products.include?(6) = true
因为products
被发现含有m
(3
),返回false
。
所以最后我已经解决了它这样(我知道有更好的方法,但仍然,它现在工作(因为可以告诉如果一个数字是彩色的或不超过3个数字):
def colorful?(number)
return false unless number.is_a? Integer
digits_arr = number.digits.reverse
return false if digits_arr.length > 3
return true if digits_arr.length == 1
final_array = []
final_array << digits_arr
case digits_arr.length
when 3
product_one = digits_arr[0] * digits_arr[1]
final_array << product_one
product_two = digits_arr[1] * digits_arr[2]
final_array << product_two
product_three = digits_arr[0] * digits_arr[1] * digits_arr[2]
final_array << product_three
when 2
product_one = digits_arr[0] * digits_arr[1]
final_array << product_one
end
if final_array.flatten.uniq == final_array.flatten
return true
else
return false
end
end
def colorful?(number)
return false unless number.is_a? Integer
return false if number == 10
digits_a = number.digits.reverse
return false if digits_a.size > 3
return true if number == 0 || number == 1 || digits_a.size < 3
products = []
digits_a.each_index do |i|
digits_a.each_index do |j|
next if i > j
product = digits_a[i..j].reduce(:*)
return false if products.include?(product)
products << product
end
end
true
end
所以这段代码对我有效。我也是一个初学者,呵呵,刚刚完成了编码训练营