Last active
September 8, 2015 05:48
-
-
Save JoshCheek/9452278ca64879b82795 to your computer and use it in GitHub Desktop.
Checking the Credits, y'all!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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