-1

i am trying to find if array has 2 digits number and if i find one i want to add the two digit and make it single. then add all the numbers in array to come up with a a sum. here is my code so far. and also i am a noob and learning

    class Imei 
    attr_accessor :Imei, :split_total1, :split_total2



    def initialize(imei)
        @imei = imei.to_i
        @split_total1 = []
        @split_total2 = []
    end

    def check_two_digit(num)
        if num.to_s.length == 2
            num = num.to_s.split(//).partition.with_index{|_,i| i.odd?}
            num.each do |a, b|
                a.to_i + b.to_i
            end
        else
            num.to_i
        end
    end



    def check_imei
        if @imei.to_s.length == 15
            split1, split2 = @imei.to_s.split(//).partition.with_index{|_, i| i.odd?}
            split1.each do |a|
                @split_total1 << check_two_digit(a.to_i * 2)
            end
            split2.pop
            split2.each do |a|
                @split_total2 << a.to_i
            end

        else
            puts "IMEI NUMBER INVALID"
        end
    end


end



imei = Imei.new(123456789102222)

imei.check_imei

puts imei.split_total1.inspect
puts imei.split_total2.inspect
suyesh
  • 530
  • 7
  • 23
  • What is the difficulty you have encountered? What does not work? – Uri Agassi Mar 02 '14 at 18:20
  • i take input of 15 digit imei, i divide into 2, fo example if its imei= [1,2,3,4,5,6,7,8,9,0], i do imei1=[2,4,6,8,0] and imei2=[1,3,5,7,9]. (ps nothing to do with odd or even). and i take imei1 and mutiply each digit in imei1 by 2 for example imei1 will be [2,8,12,16,0]. then i want to find the 12,16(two digits) in imei1 and then make them 1 + 2 (3) and 1 + 6 (7). so in the end i want to have imei1=[4,8,3,7,0]. then i want to add up everything inside imei1 and imei2 like imei1 = 4 + 8 + 3 + 7 + 0, and imei2 = 1 + 3 + 5 + 7 + 9. then add imei1 and imei2 and get a result. – suyesh Mar 02 '14 at 18:30
  • @suyeshb I am guessing you intend to write the luhn 10 algorithm, read it up on wikipedia http://en.wikipedia.org/wiki/Luhn_algorithm – bjhaid Mar 02 '14 at 18:47
  • thats exactly what i am trying to do. but the question is about ruby code. i want to do it in ruby. and the above code is how far i have come. – suyesh Mar 02 '14 at 18:48
  • @suyeshb I posted the one I wrote a while ago, you can learn from it – bjhaid Mar 02 '14 at 18:53
  • See also [this SO question](http://stackoverflow.com/questions/19011969/luhn-algorithm-returning-true-for-a-false-credit-card). – Cary Swoveland Mar 02 '14 at 19:02

3 Answers3

0

Find below the Luhn Algorithm I wrote in ruby

def luhn_10_valid? imei
  digits = imei.reverse.chars.map(&:to_i)
  digits.each_with_index.inject(0) do |sum, (digit, i)|
    digit *= 2 if i.odd?
    digit -= 9 if digit > 9
    sum += digit
  end  % 10 == 0
end
bjhaid
  • 9,592
  • 2
  • 37
  • 47
0

For Luhn algorithm I really like the divmod method, which simplifies things

array.reverse.each_slice(2).map { |x, y|
  y ||= 0
  [x, (y * 2).divmod(10)]
}.flatten.inject(:+) % 10 == 0 
xlembouras
  • 8,215
  • 4
  • 33
  • 42
0

If a contains only non-negative integers, this is one Ruby-like way to compute the sum:

a.reduce(0) {|t,i| t + (((10..99).cover? i) ? i.divmod(10).reduce(:+) : i )} 

Explanation:

If i => 46, (10..99).cover?(46) => true, 46.divmod(10) => [4,6], [4,6].reduce(:+) => 10. Recall that reduce is aka inject. [4,6]reduce(:+) has the same result as (but,technically, is not 'equivalent to'):

[4,6].reduce { |u,j| u+j }

The zero initial value is needed for the first reduce, as

   a[46].reduce {|t,i| t+(((10..99).cover? i) ? i.divmod(10).reduce(:+):i)} 
      #=> 46

which is incorrect.

If a instead contains string representations of integers and/or the integers may be negative, let me know and I'll change my answer accordingly.

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100