From: "Ball, Donald A Jr (Library)" Date: 2007-04-30T08:30:14+09:00 Subject: [SOLUTION] [QUIZ] Checking Credit Cards (#122) ------_=_NextPart_001_01C78AB6.663CF2D0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable My submission is pastied here: http://pastie.caboo.se/57536 and pasted below. I tried to come up with a solution that would allow = easy manipulation of the list of credit card providers. - donald # Ruby Quiz 123 # Donald Ball # version 1.0 require 'enumerator' class Integer def digits self.to_s.scan(/\d/).map{|n| n.to_i} end def sum_digits digits.inject{|sum, n| sum + n} end def luhn digits.reverse.enum_slice(2).inject(0) do |sum, sl| sum + sl[0].sum_digits + (sl.length =3D=3D 2 ? = (2*sl[1]).sum_digits : 0) end end def luhn? luhn % 10 =3D=3D 0 end end module Credit class Provider attr_reader :name def initialize(name, pattern) @name =3D name @pattern =3D pattern end =20 def valid?(number) @pattern.match(number) end def to_s @name end end Providers =3D [] Providers << Provider.new('AMEX', /^(34|37)\d{13}$/) Providers << Provider.new('Discover', /^6011\d{12}$/) Providers << Provider.new('MasterCard', /^5(1|2|3|4|5)\d{14}$/) Providers << Provider.new('Visa', /^4(\d{12}|\d{15})$/) =20 class Card attr_reader :number def initialize(number) if number.is_a? Integer @number =3D number elsif number.is_a? String @number =3D number.gsub(/\s/, '').to_i else raise InvalidArgument, number end end def provider Providers.each do |provider| return provider if provider.valid?(@number.to_s) end return 'Unknown' end def valid? @number.luhn? end def to_s @number.to_s end end end card =3D Credit::Card.new(ARGV[0]) puts card.provider.to_s << ' ' << (card.valid? ? 'valid' : 'invalid') ------_=_NextPart_001_01C78AB6.663CF2D0--