[SOLUTION] [QUIZ] Checking Credit Cards (#122)

Here is my submission. My first version was a bit shorter and more concise, where I had embedded the allowed lengths into the regex. I already had it written before the topic of 12 digits starting with 4 came up. So, upon James' first decision to call that an invalid Visa, I refactored and left it that way.

cheers,
brian

if ARGV.size == 0
  puts "You must supply a credit card number to be checked."
  abort
end

input = ARGV.join

class CardCompany
  class << self
    def is_issuer_of?(data)
      data =~ self::ValidRegex
    end
       def valid_card?(data)
      return false if invalid_length?(data)
           reversed = data.reverse
      sum = 0
           1.step(reversed.length - 1, 2) do |i|
        digit = reversed[i..i].to_i
        if digit < 5
          sum += digit * 2
        else
          sum += ((digit * 2) % 10) + 1
        end end
           0.step(reversed.length - 1, 2) do |i|
        sum += reversed[i..i].to_i
      end
           sum % 10 == 0
    end
       def invalid_length?(data)
      return false if self::ValidLengths.empty?
      for length in self::ValidLengths
        return false if data.size == length
      end
      true
    end
  end
end

class AmexCardCo < CardCompany
  ValidRegex = /^3[47]\d+$/
  ValidLengths = [15]
  Name = 'AMEX'
end

class DiscoCardCo < CardCompany
  ValidRegex = /^6011\d+$/
  ValidLengths = [16]
  Name = 'Discover'
end

class MasterCardCo < CardCompany
  ValidRegex = /^5[1-5]\d+$/
  ValidLengths = [16]
  Name = 'MasterCard'
end

class VisaCardCo < CardCompany
  ValidRegex = /^4\d+$/
  ValidLengths = [13, 16]
  Name = 'Visa'
end

class UnknownCardCo < CardCompany
  ValidRegex = /^\d+$/
  ValidLengths = []
  Name = 'Unknown'
end

SYSTEMS = [ AmexCardCo, DiscoCardCo, MasterCardCo, VisaCardCo, UnknownCardCo ]

for system in SYSTEMS
  if system.is_issuer_of?(input)
    found = true
    valid = system.valid_card?(input)
    puts "#{system::Name} #{valid ? 'Valid' : 'Invalid'}"
    break
  end
end

puts "Invalid input" if !found