تمرین: الگوریتم Luhn

الگوریتم Luhn

الگوریتم Luhn برای اعتبارسنجی شماره‌های کارت اعتباری استفاده می‌شود. این الگوریتم یک رشته را به عنوان ورودی دریافت می‌کند و برای اعتبارسنجی شماره کارت اعتباری مراحل زیر را انجام می‌دهد:

  • Ignore all spaces. Reject numbers with fewer than two digits.

  • با حرکت از سمت راست رشته به چپ، هر دومین رقم را دوبل کنید: برای شماره 1234، 3 و 1 را دوبل می‌کنیم. برای شماره 98765، 6 و 8 را دوبل می‌کنیم.

  • پس از دوبل کردن یک عدد، اگر اون جفت خروجی بیش از 9 باشد، ارقام را جمع کنید. بنابراین، دوبل کردن 7 به 14 تبدیل می‌شود که به 1 + 4 = 5 تبدیل می‌شود.

  • تمام ارقام دو برابر نشده و دو برابر شده را جمع کنید.

  • اگر مجموع با ‍0 خاتمه یابد، شماره کارت اعتباری معتبر است.

کد ارائه شده یک پیاده‌سازی باگ از الگوریتم luhn را به همراه دو unit test پایه ارائه می‌کند که تأیید می‌کند بیشتر الگوریتم به درستی پیاده‌سازی شده است.

Copy the code below to https://play.rust-lang.org/ and write additional tests to uncover bugs in the provided implementation, fixing any bugs you find.

#![allow(unused)]
fn main() {
pub fn luhn(cc_number: &str) -> bool {
    let mut sum = 0;
    let mut double = false;

    for c in cc_number.chars().rev() {
        if let Some(digit) = c.to_digit(10) {
            if double {
                let double_digit = digit * 2;
                sum +=
                    if double_digit > 9 { double_digit - 9 } else { double_digit };
            } else {
                sum += digit;
            }
            double = !double;
        } else {
            continue;
        }
    }

    sum % 10 == 0
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_valid_cc_number() {
        assert!(luhn("4263 9826 4026 9299"));
        assert!(luhn("4539 3195 0343 6467"));
        assert!(luhn("7992 7398 713"));
    }

    #[test]
    fn test_invalid_cc_number() {
        assert!(!luhn("4223 9826 4026 9299"));
        assert!(!luhn("4539 3195 0343 6476"));
        assert!(!luhn("8273 1232 7352 0569"));
    }
}
}