```Am 02.05.2007 um 17:13 schrieb Christian Neukirchen:

> Ruby Quiz <james / grayproductions.net> writes:
>
>> This week's Ruby Quiz is to write a program that accepts a credit
>> card number as
>> a command-line argument.  The program should print the card's type
>> (or Unknown)
>> as well a Valid/Invalid indication of whether or not the card
>> passes the Luhn
>> algorithm.
>
> #!ruby
>
> def cardtype(n)
>   case n.delete("^0-9")
>   when /\A3\d{13}\z/:   "AMEX"
>   when /\A6011\d{12}\z/:    "Discover"
>   when /\A5[1-4]\d{14}\z/:  "Master Card"
>   when /\A4\d{12}\d{3}?\z/: "Visa"
>   else "Unknown"
>   end
> end
>
> def luhn?(n)
>   f = 2
>   (n.delete("^0-9").reverse.split(//).map{|d|d.to_i}.
>      inject(0) { |a,e| f=3-f; a + (e*f > 9 ? e*f-9 : e*f) } %
> 10).zero?
> end
>
> puts cardtype(ARGV.join)
> puts luhn?(ARGV.join) ? "valid" : "invalid"
>
> __END__
>
> --
> Christian Neukirchen  <chneukirchen / gmail.com>  http://
> chneukirchen.org
>
>

Wow, very nice solution! Impressive how short it is...

Here is my solution:

#!/usr/bin/env ruby -W

# Assign a regular expression that checks first characters and length
PROVIDERINFO = {
"AMEX"       => /^(34|37)\d{13}\$/,
"Discover"   => /^6011\d{12}\$/,
"MasterCard" => /^5[1-5]\d{14}\$/,
"Visa"       => /^4(\d{12}|\d{15})\$/,
}

class CreditCard

def initialize(number)
@number = []
# split credit card number and store in array
number.scan(/\d/){|c| @number.push c.to_i}

# Check Provider Infos
@provider = "Unknown"
PROVIDERINFO.each_pair {|k, v| @provider = k if
@number.join.match(v) }
end

def luhn_passed?
sum = 0
@number.reverse.each_with_index do |num, i|
# double the nummer if necessary and subtract 9 if the result
# consists of 2 numbers (here same as summing up both numbers)
num = num * 2 - ((num > 4) ? 9 : 0) if i % 2 == 1
sum += num
end
sum % 10 == 0
end

def to_s
"Creditcard number #{@number}\n" +
"  Provider: #{self.provider}\n" +
"  Luhn Algorithm #{'not ' unless self.luhn_passed?}passed"
end
end

puts CreditCard.new(ARGV.join)

Regards,

Dennis Frommknecht

```