9 changed files with 2589 additions and 0 deletions
@ -0,0 +1,8 @@ |
|||||||
|
[package] |
||||||
|
name = "pythonchallenge" |
||||||
|
version = "0.1.0" |
||||||
|
edition = "2021" |
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||||
|
|
||||||
|
[dependencies] |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
use pythonchallenge::cipher::caesar; |
||||||
|
|
||||||
|
// http://www.pythonchallenge.com/pc/def/map.html
|
||||||
|
|
||||||
|
const INPUT: &str = "g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj."; |
||||||
|
|
||||||
|
|
||||||
|
fn main() { |
||||||
|
println!("{}", caesar(INPUT, 2)); |
||||||
|
println!("{}", caesar("map", 2)) |
||||||
|
} |
||||||
@ -0,0 +1,50 @@ |
|||||||
|
fn ascii_char_step(ascii_char: u8, step: i32) -> u8 { |
||||||
|
const LOWER_A : u8 = 'a' as u8; |
||||||
|
const LOWER_Z : u8 = 'z' as u8; |
||||||
|
const UPPER_A : u8 = 'A' as u8; |
||||||
|
const UPPER_Z : u8 = 'Z' as u8; |
||||||
|
|
||||||
|
match ascii_char { |
||||||
|
LOWER_A..=LOWER_Z => { |
||||||
|
((ascii_char - LOWER_A) as i32 + step).rem_euclid(26) as u8 + LOWER_A |
||||||
|
} |
||||||
|
UPPER_A..=UPPER_Z => { |
||||||
|
((ascii_char - UPPER_A) as i32 + step).rem_euclid(26) as u8 + UPPER_A |
||||||
|
} |
||||||
|
_ => ascii_char |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/// Apply caser / shift cipher on a ASCII string
|
||||||
|
pub fn caesar(input: &str, step: i32) -> String { |
||||||
|
assert!(input.is_ascii(), "Only works for ASCII messages"); |
||||||
|
let modified_bytes = input.bytes().map(|c| {ascii_char_step(c, step)}).collect(); |
||||||
|
String::from_utf8(modified_bytes).unwrap() |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)] |
||||||
|
mod tests { |
||||||
|
use super::*; |
||||||
|
#[test] |
||||||
|
fn simple_test() { |
||||||
|
let input = "abcde"; |
||||||
|
assert_eq!(caesar(input, 1), "bcdef"); |
||||||
|
|
||||||
|
let input = "ABCDE"; |
||||||
|
assert_eq!(caesar(input, 3), "DEFGH"); |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
fn overflow() { |
||||||
|
let input = "xyzab"; |
||||||
|
assert_eq!(caesar(input, 2), "zabcd"); |
||||||
|
} |
||||||
|
|
||||||
|
#[test] |
||||||
|
fn negative_step() { |
||||||
|
let input = "DEFGH"; |
||||||
|
assert_eq!(caesar(input, -4), "ZABCD"); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,14 @@ |
|||||||
|
/// Strip away ASCII control characters and whitespaces
|
||||||
|
pub fn strip_cw(input: &str) -> String { |
||||||
|
input.chars().filter(|c| { !c.is_ascii_control() && !c.is_ascii_whitespace() }).collect() |
||||||
|
} |
||||||
|
|
||||||
|
#[cfg(test)] |
||||||
|
mod tests { |
||||||
|
use super::*; |
||||||
|
#[test] |
||||||
|
fn simple_test() { |
||||||
|
let input = "abc def ghi\njkl mno"; |
||||||
|
assert_eq!(strip_cw(input), "abcdefghijklmno"); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue