Skip to content

Commit

Permalink
Implement Luhn
Browse files Browse the repository at this point in the history
Closes exercism#237

This mostly follows the current test suite
(exercism/problem-specifications#491), with one change.

The final canonical test adds an alphabetical character to a known
invalid string and then asserts that it's still invalid.

Instead what the test should do is alter a known-valid string and show
that it is now invalid.

That's what I've done here. I'll also propose the change to canonical
test suite.
  • Loading branch information
whit0694 committed Jan 14, 2017
1 parent c0c6178 commit 3d70d54
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 0 deletions.
7 changes: 7 additions & 0 deletions exercises/luhn/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Generated by Cargo
# will have compiled files and executables
/target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
Cargo.lock
3 changes: 3 additions & 0 deletions exercises/luhn/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[package]
name = "luhn"
version = "0.0.0"
14 changes: 14 additions & 0 deletions exercises/luhn/example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pub fn is_valid(candidate: &str) -> bool {
if candidate.chars().any(|c| c.is_alphabetic()) || candidate.chars().count() == 1 {
return false;
}

candidate.chars()
.filter(|c| c.is_numeric())
.map(|c| c.to_digit(10).unwrap())
.rev()
.enumerate()
.map(|(index, digit)| if index % 2 == 0 { digit } else { digit * 2 })
.map(|digit| if digit > 10 { digit - 9 } else { digit })
.sum::<u32>() % 10 == 0
}
33 changes: 33 additions & 0 deletions exercises/luhn/tests/luhn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
extern crate luhn;

use luhn::*;

#[test]
fn single_digit_string_is_invalid() {
assert!(!is_valid("1"));
}

#[test]
fn single_zero_string_is_invalid() {
assert!(!is_valid("0"));
}

#[test]
fn valid_canadian_sin_is_valid() {
assert!(is_valid("046 454 286"));
}

#[test]
fn invalid_canadian_sin_is_invalid() {
assert!(!is_valid("046 454 287"));
}

#[test]
fn invalid_credit_card_is_invalid() {
assert!(!is_valid("8273 1232 7352 0569"));
}

#[test]
fn strings_that_contain_non_digits_are_invalid() {
assert!(!is_valid("046a 454 286"));
}

0 comments on commit 3d70d54

Please sign in to comment.