Day 2 Afternoon Exercises

Luhn Algorithm

(back to exercise)

// Copyright 2022 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ANCHOR: luhn pub fn luhn(cc_number: &str) -> bool { // ANCHOR_END: luhn let mut digits_seen = 0; let mut sum = 0; for (i, ch) in cc_number.chars().rev().filter(|&ch| ch != ' ').enumerate() { match ch.to_digit(10) { Some(d) => { sum += if i % 2 == 1 { let dd = d * 2; dd / 10 + dd % 10 } else { d }; digits_seen += 1; } None => return false, } } if digits_seen < 2 { return false; } sum % 10 == 0 } fn main() { let cc_number = "1 0"; println!( "Is {} a valid credit card number? {}", cc_number, if luhn(cc_number) { "yes" } else { "no" } ); } // ANCHOR: unit-tests #[test] fn test_non_digit_cc_number() { assert!(!luhn("foo")); } #[test] fn test_empty_cc_number() { assert!(!luhn("")); assert!(!luhn(" ")); assert!(!luhn(" ")); assert!(!luhn(" ")); } #[test] fn test_single_digit_cc_number() { assert!(!luhn("0")); } #[test] fn test_two_digit_cc_number() { assert!(luhn(" 0 0 ")); } #[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")); } // ANCHOR_END: unit-tests

Strings and Iterators

(back to exercise)

#![allow(unused)] fn main() { // Copyright 2022 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ANCHOR: prefix_matches pub fn prefix_matches(prefix: &str, request_path: &str) -> bool { // ANCHOR_END: prefix_matches let mut prefixes = prefix.split('/'); let request_paths = request_path .split('/') .map(|p| Some(p)) .chain(std::iter::once(None)); for (prefix, request_path) in prefixes.zip(request_paths) { match request_path { Some(request_path) => { if (prefix != "*") && (prefix != request_path) { return false; } } None => return false, } } true } // ANCHOR: unit-tests #[test] fn test_matches_without_wildcard() { assert!(prefix_matches("/v1/publishers", "/v1/publishers")); assert!(prefix_matches("/v1/publishers", "/v1/publishers/abc-123")); assert!(prefix_matches("/v1/publishers", "/v1/publishers/abc/books")); assert!(!prefix_matches("/v1/publishers", "/v1")); assert!(!prefix_matches("/v1/publishers", "/v1/publishersBooks")); assert!(!prefix_matches("/v1/publishers", "/v1/parent/publishers")); } #[test] fn test_matches_with_wildcard() { assert!(prefix_matches( "/v1/publishers/*/books", "/v1/publishers/foo/books" )); assert!(prefix_matches( "/v1/publishers/*/books", "/v1/publishers/bar/books" )); assert!(prefix_matches( "/v1/publishers/*/books", "/v1/publishers/foo/books/book1" )); assert!(!prefix_matches("/v1/publishers/*/books", "/v1/publishers")); assert!(!prefix_matches( "/v1/publishers/*/books", "/v1/publishers/foo/booksByAuthor" )); } // ANCHOR_END: unit-tests }