From: Daniel Martin on 2 May 2007 16:18 Just one minor nit: Christian Neukirchen <chneukirchen(a)gmail.com> writes: > 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 You do know that (e*f > 9 ? e*f-9 : e*f) is equivalent to e*f%9, right? So that makes this method: 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 } %10).zero? end (I still like my short version better, but too each his own) -- s=%q( Daniel Martin -- martin(a)snowplow.org puts "s=%q(#{s})",s.to_a[1] ) puts "s=%q(#{s})",s.to_a[1]
From: James Edward Gray II on 2 May 2007 16:27 On May 2, 2007, at 3:18 PM, Daniel Martin wrote: > Just one minor nit: > > Christian Neukirchen <chneukirchen(a)gmail.com> writes: > >> 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 > > You do know that (e*f > 9 ? e*f-9 : e*f) is equivalent to e*f%9, > right? >> (0..9).map { |n| n * 2 % 9 } => [0, 2, 4, 6, 8, 1, 3, 5, 7, 0] >> (0..9).map { |n| n * 2 > 9 ? n * 2 - 9 : n * 2 } => [0, 2, 4, 6, 8, 1, 3, 5, 7, 9] James Edward Gray II
From: Paul Novak on 2 May 2007 21:47 Thank you James for another fun quiz. My solution is a more verbose version of the metaprogramming-based routing used in why's excellent camping. But instead of regexen matching urls to controller classes, here they are matching card numbers to the card classes. What I like about this approach is that you can add more card patterns just by adding more classes with the appropriate regexen, and you can override validation or other functionality as needed. Regards, Paul. # cardvalidator.rb # require 'metaid' module Card @cards=[] def Card.Base *u c = @cards Class.new { meta_def(:patterns){u} meta_def(:validity){|x|Card.validity(x)} meta_def(:inherited){|x|c<<x} } end def Card.validate cardnum @cards.map { |k| k.patterns.map { |x| if cardnum =~ /^#{x}\/?$/ return [k.name.upcase, k.validity(cardnum)].join( " ") end } } raise "Unexpected Card Number pattern: '#{cardnum}'" end def Card.sum_of_digits s s.split("").inject(0){|sum,x|sum + Integer(x)} end def Card.luhnSum s temp = "" r = 0..s.size a = s.split("").reverse r.each do |i| if i%2==1 x = (Integer(a[i])*2).to_s else x = a[i] end temp << x.to_s end sum_of_digits temp end def Card.validity cardnum if (Card.luhnSum(cardnum) % 10)==0 return "Valid" else return "Invalid" end end end # patterns will be tested for match in order defined class Visa < Card.Base /4[0-9]{12,15}/ end class Amex < Card.Base /3[4,7][0-9]{13}/ end class Mastercard < Card.Base /5[1-5][0-9]{13}/ end class Discover < Card.Base /6011[0-9]{12}/ end # catch-all class Unknown < Card.Base /.+/ end p Card.validate(ARGV[0])
From: Rick DeNatale on 3 May 2007 09:55 I came to this quiz late, but came up with the following, before reading the solution, which uses String.tr to do the double and sum instead of an array. require 'enumerator' def luhn(string) string.scan(/./).reverse.enum_for(:each_with_index).inject(0) do |sum, (digit, index)| digit = digit.tr('0123456789', '0246813579') if index % 2 == 1 sum += digit.to_i end # % 10 == 0 end After seeing the neat use of each_slice instead of each_with_index def luhn(string) string.scan(/./).reverse.enum_for(:each_slice, 2).inject(0) do |sum, (d1, d2)| sum += d1.to_i + (d2||'0').tr('0123456789', '0246813579').to_i end % 10 == 0 end No need to define any extra Enumerator methods. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/
From: anansi on 3 May 2007 10:11
> Ruby Quiz will now take a one week break. Work has been rough this week and I > need some down time. I'll be back next week, rested, and with new quizzes... Means that: no quiz tomorrow ?!? -- greets ( ) ( /\ .-"""-. /\ //\\/ ,,, \//\\ |/\| ,;;;;;, |/\| //\\\;-"""-;///\\ // \/ . \/ \\ (| ,-_| \ | / |_-, |) //`__\.-.-./__`\\ // /.-(() ())-.\ \\ (\ |) '---' (| /) ` (| |) ` jgs \) (/ one must still have chaos in oneself to be able to give birth to a dancing star |