我一直在尝试在Ruby中实现Luhn算法,但一直收到错误消息: nil不能被强制转换为Fixnum。
Luhn算法被认为是:
从倒数第二位开始,每隔一位翻一番,直到达到第一位。
将所有未接触的数字和双倍数字相加(双倍数字需要分开,10变成1+ 0)
如果总数是十的倍数,则您已收到有效的信用卡号码!
这就是我所拥有的:
class CreditCard
def initialize (card_number)
if (card_number.to_s.length != 16 )
raise ArgumentError.new("Please enter a card number with exactly 16 integars")
end
@card_number = card_number
@total_sum = 0
end
def check_card
@new_Array = []
@new_Array = @card_number.to_s.split('')
@new_Array.map! { |x| x.to_i }
@new_Array.each_with_index.map { |x,y|
if (y % 2 != 0)
x = x*2
end
}
@new_Array.map! {|x|
if (x > 9)
x = x-9
end
}
@new_Array.each { |x|
@total_sum = @total_sum + x
}
if (@total_sum % 10 == 0)
return true
else
return false
end
end
end发布于 2013-08-10 01:51:05
在你的分区中
@new_Array.each_with_index.map { |x,y|
if (y % 2 != 0)
x = x*2
end
}这些变化不是永久性的。此外,正如维克多所写的,如果测试失败,您的@new_Array将充满nils。在最后
if (@total_sum % 10 == 0)
return true
else
return false
end相反,您可以简单地编写
@total_sum % 10 == 0因为ruby方法中的最后一行已经是一个return。我找到了一个slightly different algorithm并在这里实现了它:
# 1) Reverse the order of the digits in the number.
# 2) Take the first, third, ... and every other odd digit in the reversed digits
# and sum them to form the partial sum s1
# 3) Taking the second, fourth ... and every other even digit in the reversed digits:
# a) Multiply each digit by two (and sum the digits if the answer is greater than nine) to form partial sums for the even digits
# b) Sum the partial sums of the even digits to form s2
# 4) If s1 + s2 ends in zero then the original number is in the form of a valid credit card number as verified by the Luhn test.
def luhn n
s = n.to_s.reverse
sum=0
tmp=0
(0..s.size-1).step(2) {|k| #k is odd, k+1 is even
sum+=s[k].to_i #s1
tmp = s[k+1].to_i*2
tmp = tmp.to_s.split(//).map(&:to_i).reduce(:+) if tmp>9
sum+=tmp
}
sum%10 == 0
end
[49927398716, 49927398717, 1234567812345678, 1234567812345670].each {|num|
puts "%20s %s" % [num, luhn(num)]
}
# 49927398716 true
# 49927398717 false
# 1234567812345678 false
# 1234567812345670 true希望这能有所帮助。
发布于 2013-08-09 10:21:24
if (x > 9)
x = x-9
end=>
x > 9 ? x - 9 : x或者,您也可以编写
if x > 9
x - 9
else
x
end如果没有else子句,if false; ...; end的值将始终为nil
发布于 2015-05-30 00:03:49
如果你不介意改变你的代码...
...
def check_card
sum = 0
@card_number.to_s.split("").each_with_index do |digit, index|
d = digit.to_i
sum += index % 2 == 1 ? d : d * 2 > 9 ? ( d * 2 - 9) : d * 2
end
sum % 10 == 0
end这只是立即得到数字的总和,如果索引是偶数(从数组索引的角度来看,从第二个到最后一个开始的每隔一个数都是偶数),则将其加倍并减去9。
https://stackoverflow.com/questions/18138907
复制相似问题