Spartan solution (along with its obscure sister below)
usage: ruby quiz122.rb <credit card number with no
dashes or spaces>
example: ruby quiz122.rb 341275084937123
some variables
user_input = $*[0]
sum_is_valid = card_is_known = false
sum = 0
the limited database
db = {
3.410**14…3.51014-1 => “AMEX”,
3.7*1014…3.810**14-1 => “AMEX”,
6.0111015…6.012*1015-1 => “Discover”,
5.110**15…5.61015-1 => “MasterCard”,
4*1012…510**12-1 => “Visa”,
41015…5*1015-1 => “Visa”,
}
check the database
number = user_input.to_i
type = ‘unknown’
db.each { |key,value| type = value if key === number }
card_is_known ||= type != ‘unknown’
ugly way to code the Luhn algorithm
1. initialize sum
2. reverse the supplied string
3. turn the string into an array with one digit per
index
4. turn the individual digits into integers
5. sum everything up …
5a. add the digit to the sum if the array index is
odd
5b. add the digits making up twice the value of the
digit if the array index is even
6. test 2 is valid if the sum is divisible by 10
(user_input.reverse.scan(/\d/).map! { |digit|
digit.to_i }).each_with_index { |digit,index| sum += (
index % 2 == 0 ? digit : digit.divmod(5)[1] * 2 +
digit.divmod(5)[0] ) }
puts sum
sum_is_valid ||= sum % 10 == 0
print results
card_is_known = (card_is_known ? “is” : “is not”)
sum_is_valid = (sum_is_valid ? “is” : “is not”)
puts “The card #{card_is_known} known.”
puts “The card type is #{type}.”
puts “The card number sum #{sum_is_valid} valid.”
Solution, obscure version
preliminary data
sum=known=false;type=’’;t=0
db = {
3.410**14…3.51014-1 => “AMEX”,
3.7*1014…3.810**14-1 => “AMEX”,
6.0111015…6.012*1015-1 => “Discover”,
5.110**15…5.61015-1 => “MasterCard”,
4*1012…510**12-1 => “Visa”,
41015…5*1015-1 => “Visa”,
}
check stuff
db.each { |k,v| type=v if
k===$[0].to_i};known||=type!=’’
($[0].reverse.scan(/\d/).map!{|d|d.to_i}).each_with_index{|d,i|t+=(i%2==0
? d : d.divmod(5)[1]*2+d.divmod(5)[0])};sum||=t%10==0
cryptically print results
puts “Known: #{known}\nType: #{type}\nValid sum: #{sum}”