Skip to content

Instantly share code, notes, and snippets.

@sferik
Forked from JoshCheek/1_class_refactored_solution.rb
Last active September 7, 2015 20:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sferik/4170cfab7fb6e574147c to your computer and use it in GitHub Desktop.
Save sferik/4170cfab7fb6e574147c to your computer and use it in GitHub Desktop.
Checking the Credits, y'all!
def valid?(card_number)
digits = card_number
.split("")
.map { |number| number.to_i }
numbers = []
digits.each_with_index do |digit, index|
if index.even?
numbers << digit * 2
else
numbers << digit
end
end
summed_digits = []
numbers.each do |number|
if number > 9
# sum of the digits
summed_digits << 1 + number - 10
else
summed_digits << number
end
end
# add them all together
sum = summed_digits.reduce(:+)
valid = (0 == sum % 10)
valid
end
if valid?("4929735477250543")
puts "The number is valid!"
else
puts "The number is invalid!"
end
# valid
['5541808923795240', '4024007136512380', '6011797668867828']
.map { |number| valid?(number) } # => [true, true, true]
# invalid
['5541801923795240', '4024007106512380', '6011797668868728']
.map { |number| valid?(number) } # => [false, false, false]
# >> The number is valid!
def valid?(card_number)
identifier = card_number.reverse.chars.map(&:to_i)
with_doubles = identifier.map.with_index { |n, i| i.even? ? n : n*2 }
single_digits = with_doubles.map { |n| n > 9 ? n.to_s.chars.map(&:to_i).inject(0, :+) : n }
sum = single_digits.inject(0, :+)
mod_10 = sum % 10
valid = mod_10 == 0
valid
end
# valid
['79927398713', '5541808923795240', '4024007136512380', '6011797668867828']
.map { |num| valid? num } # => [true, true, true, true]
# invalid
['5541801923795240', '4024007106512380', '6011797668868728']
.map { |num| valid? num } # => [false, false, false]
# process the example
if valid? "4929735477250543"
puts "The number is valid!"
else
puts "The number is invalid!"
end
# >> The number is valid!
# split across lines more than I otherwise would so that we can see how the data gets transformed as it progresses
# not saying this is best, just where I wound up :)
# I tend to prefer chains of transformations a lot more than most people :P
def valid?(card_number)
sum = card_number # => "4929735477250543"
.reverse # => "3450527745379294"
.chars # => ["3", "4", "5", "0", "5", "2", "7", "7", "4", "5", "3", "7", "9", "2", "9", "4"]
.map { |char| char.to_i } # => [3, 4, 5, 0, 5, 2, 7, 7, 4, 5, 3, 7, 9, 2, 9, 4]
.map.with_index { |n, i| maybe_double n, i } # => [3, 8, 5, 0, 5, 4, 7, 14, 4, 10, 3, 14, 9, 4, 9, 8]
.map { |n| sum_digits n } # => [3, 8, 5, 0, 5, 4, 7, 5, 4, 1, 3, 5, 9, 4, 9, 8]
.inject(0, :+) # => 80
0 == sum % 10 # => true
end
def sum_digits(number)
number.to_s # => "3", "8", "5", "0", "5", "4", "7", "14", "4", "10", "3", "14", "9", "4", "9", "8"
.chars # => ["3"], ["8"], ["5"], ["0"], ["5"], ["4"], ["7"], ["1", "4"], ["4"], ["1", "0"], ["3"], ["1", "4"], ["9"], ["4"], ["9"], ["8"]
.map { |digit| digit.to_i } # => [3], [8], [5], [0], [5], [4], [7], [1, 4], [4], [1, 0], [3], [1, 4], [9], [4], [9], [8]
.inject(0, :+) # => 3, 8, 5, 0, 5, 4, 7, 5, 4, 1, 3, 5, 9, 4, 9, 8
end
def maybe_double(number, index)
if index.even?
number
else
number * 2
end
end
# # valid
# ['79927398713', '5541808923795240', '4024007136512380', '6011797668867828']
# .map { |num| valid? num } # => [true, true, true, true]
#
# # invalid
# ['5541801923795240', '4024007106512380', '6011797668868728']
# .map { |num| valid? num } # => [false, false, false]
# process the example
if valid? "4929735477250543"
puts "The number is valid!"
else
puts "The number is invalid!"
end
# >> The number is valid!
# I took your philosophy of method chaining to its logic conclusion,
# removing the local variable `sum` from the `valid?` method.
# I was able to remove both instances of .map { |char| char.to_i }
# by doing the the integer conversion in the subsequent step, saving
# both time and space. I also reversed the conditional statement in
# `maybe_double`, since I think it makes it clearer when it doubles.
def valid?(card_number)
card_number # => "4929735477250543"
.reverse # => "3450527745379294"
.chars # => ["3", "4", "5", "0", "5", "2", "7", "7", "4", "5", "3", "7", "9", "2", "9", "4"]
.map.with_index { |n, i| maybe_double(n.to_i, i) } # => [3, 8, 5, 0, 5, 4, 7, 14, 4, 10, 3, 14, 9, 4, 9, 8]
.inject { |s, n| s + sum_digits(n) } # => 80
.modulo(10) # => 0
.zero? # => true
end
def sum_digits(number)
number # => 3, 8, 5, 0, 5, 4, 7, 14, 4, 10, 3, 14, 9, 4, 9, 8
.to_s # => "3", "8", "5", "0", "5", "4", "7", "14", "4", "10", "3", "14", "9", "4", "9", "8"
.chars # => ["3"], ["8"], ["5"], ["0"], ["5"], ["4"], ["7"], ["1", "4"], ["4"], ["1", "0"], ["3"], ["1", "4"], ["9"], ["4"], ["9"], ["8"]
.inject(0) { |s, n| s + n.to_i } # => 3, 8, 5, 0, 5, 4, 7, 5, 4, 1, 3, 5, 9, 4, 9, 8
end
def maybe_double(number, index)
if index.odd?
number * 2
else
number
end
end
# # valid
# ['79927398713', '5541808923795240', '4024007136512380', '6011797668867828']
# .map { |num| valid? num } # => [true, true, true, true]
#
# # invalid
# ['5541801923795240', '4024007106512380', '6011797668868728']
# .map { |num| valid? num } # => [false, false, false]
# process the example
if valid? "4929735477250543"
puts "The number is valid!"
else
puts "The number is invalid!"
end
# >> The number is valid!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment