l7kyu/
fundamentals.rs

1//!
2//! Modules categorized by Codewars labels - 7kyu *** Fundamentals ***
3//!
4
5use shared::kata::*;
6
7fn substitute(c: char) -> char {
8    match c {
9        'G' => 'A',
10        'D' => 'E',
11        'R' => 'Y',
12        'P' => 'O',
13        'L' => 'U',
14        'K' => 'I',
15        'g' => 'a',
16        'd' => 'e',
17        'r' => 'y',
18        'p' => 'o',
19        'l' => 'u',
20        'k' => 'i',
21        'A' => 'G',
22        'E' => 'D',
23        'Y' => 'R',
24        'O' => 'P',
25        'U' => 'L',
26        'I' => 'K',
27        'a' => 'g',
28        'e' => 'd',
29        'y' => 'r',
30        'o' => 'p',
31        'u' => 'l',
32        'i' => 'k',
33        _ => c,
34    }
35}
36
37/// The GADERYPOLUKI is a simple substitution cipher used in scouting to
38/// encipher messages. The encryption is based on short, easy to remember key.
39/// The key is written as paired letters, which are in the cipher simple
40/// replacement. The most frequently used key is "GA-DE-RY-PO-LU-KI".
41/// Your task is to help scouts to encrypt and decrypt thier messages.
42/// Write the Encipher and Decipher functions.
43/// # Example
44/// ``` encipher("ABCD") ``` <br>
45/// returns "GBCE"
46pub fn encipher(text: &str) -> String {
47    let kata = Kata {
48        level: Level::L7kyu,
49        tags: vec![Tag::Fundamentals, Tag::Ciphers, Tag::Cryptography],
50        description: String::from("GA-DE-RY-PO-LU-KI cipher"),
51    };
52
53    println!(
54        "Level: {:?}, Tags: {:?}, Description: {}",
55        kata.level, kata.tags, kata.description
56    );
57
58    let enciphered: String = text.chars().map(substitute).collect();
59    enciphered
60}
61
62/// The GADERYPOLUKI is a simple substitution cipher used in scouting to
63/// encipher messages. Write the decrypt function.
64/// # Example
65/// ``` decipher("GBCE") ``` <br>
66/// returns "ABCD"
67pub fn decipher(text: &str) -> String {
68    let kata = Kata {
69        level: Level::L7kyu,
70        tags: vec![Tag::Fundamentals, Tag::Ciphers, Tag::Cryptography],
71        description: String::from("GA-DE-RY-PO-LU-KI cipher"),
72    };
73
74    println!(
75        "Level: {:?}, Tags: {:?}, Description: {}",
76        kata.level, kata.tags, kata.description
77    );
78
79    let deciphered: String = text.chars().map(substitute).collect();
80    deciphered
81}
82
83fn substitute_num(c: char) -> i32 {
84    if c.is_ascii_alphabetic() {
85        (c.to_ascii_uppercase() as i32) - ('A' as i32) + 1
86    } else {
87        0
88    }
89}
90
91/// Digital Cypher assigns to each letter of the alphabet a unique number.
92/// Instead of letters in encrypted word we write the corresponding number.
93/// Then we add to each obtained digit consecutive digits from the key.
94/// Write a function that accepts string and key number and returns an
95/// array of integers.
96/// Write the Encipher function.
97/// # Example
98/// ``` encipher("scout",1939) ``` <br>
99/// returns [ 20, 12, 18, 30, 21]
100pub fn digital_encipher(msg: String, n: i32) -> Vec<i32> {
101    let kata = Kata {
102        level: Level::L7kyu,
103        tags: vec![Tag::Fundamentals, Tag::Ciphers, Tag::Cryptography],
104        description: String::from("Digital cipher"),
105    };
106
107    println!(
108        "Level: {:?}, Tags: {:?}, Description: {}",
109        kata.level, kata.tags, kata.description
110    );
111
112    let nums: Vec<i32> = msg.chars().map(substitute_num).collect();
113
114    let n_str = n.to_string();
115    let n_digits: Vec<i32> = n_str
116        .chars()
117        .map(|c| c.to_digit(10).unwrap() as i32)
118        .collect();
119
120    nums.into_iter()
121        .enumerate()
122        .map(|(i, v)| v + n_digits[i % n_digits.len()])
123        .collect()
124}