【发布时间】:2015-04-30 11:12:11
【问题描述】:
帮我重构实现Luhn algorithm,具体描述如下:
该公式根据其包含的校验位验证一个数字,该校验位 通常附加到部分帐号以生成完整的帐号 帐号。此帐号必须通过以下测试:
- 从最右边的数字(即校验位)开始,向左移动,每隔一个数字加一倍;如果这个加倍运算的乘积大于 9(例如,8 × 2 = 16),则将乘积的数字相加(例如,16: 1 + 6 = 7, 18: 1 + 8 = 9)。李>
- 取所有数字的总和。
- 如果总计模 10 等于 0(如果总计以 0 结尾)则根据 Luhn 公式该数字有效;否则无效。
假设一个帐号为“7992739871”的示例将具有 添加校验位,格式为 7992739871x:
Account number 7 9 9 2 7 3 9 8 7 1 xDouble every other 7 18 9 4 7 6 9 16 7 2 -Sum of digits 7 9 9 4 7 6 9 7 7 2 =67校验位(x)是通过计算数字的总和得到的 计算该值的 9 倍模 10(以方程形式,(67 × 9 mod 10))。算法形式:
- 计算数字的总和 (67)。
- 乘以 9 (603)。
- 最后一位数字 3 是校验位。因此,x=3。
以下是我的实现,我相信它可以工作,但可能会更好。
def credit_check(num)
verify = num.to_s.split('').map(&:to_i)
half1 = verify.reverse.select.each_with_index { |str, i| i.even? }
half1 = half1.inject(0) { |r,i| r + i }
# This implements rule 1
half2 = verify.reverse.select.each_with_index { |str, i| i.odd? }
double = half2.map { |n| n * 2 }
double = double.map { |n| n.to_s.split('') }
double = double.flatten.map(&:to_i)
double = double.inject(0) { |r,i| r + i }
final = double + half1
puts final % 10 == 0 && (num.to_s.length > 12 && num.to_s.length < 17) ? "VALID" : "INVALID"
end
显然,我在所有这些方面都是一个等级菜鸟。但我感谢任何帮助,包括正确的风格!
【问题讨论】:
-
第一步是使用有助于强制缩进的编辑器。这对编写正确的代码大有帮助。
-
谢谢。我正在使用 pico,它没有任何帮助!
-
优秀的编辑器很多。两个支柱是 vim 和 emacs。它们有点学习曲线,但它们可以在多个平台上运行,所以一旦你学习了一个或另一个,你就可以在其他机器上使用相同的命令和配置。我在 Mac OS、Windows 和 Linux 上使用 vim,都具有相同的配置。 Sublime Text Editor 和 Textmate 也都不错; Sublime 正在不断发展中,Textmate 似乎已经过时了。
标签: ruby refactoring credit-card