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[37]\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
   attr_reader :provider, :number

   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