Created
April 13, 2019 23:22
-
-
Save Diti/6edc7dd5f8a0a1308b8f935cdefb580d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::error::Error; | |
use std::io::{prelude::*, stdin}; | |
type AsciiArtResult<T> = Result<T, Box<Error>>; | |
#[derive(Debug, Default, PartialEq)] | |
struct AsciiArtData { | |
alphabet_rows: Vec<String>, | |
letter_width: u8, | |
letter_height: u8, | |
sentence: String, | |
} | |
impl AsciiArtData { | |
fn from(reader: impl BufRead) -> AsciiArtResult<Self> { | |
let mut input_lines = reader.lines().map(|l| l.unwrap()); | |
let w: u8 = input_lines | |
.next() | |
.expect("Cannot read letter width") | |
.trim() | |
.parse() | |
.expect("Cannot parse letter width"); | |
let h: u8 = input_lines | |
.next() | |
.expect("Cannot read letter height") | |
.trim() | |
.parse() | |
.expect("Cannot parse letter height"); | |
let txt: String = input_lines | |
.next() | |
.expect("Cannot read sentence") | |
.trim_end() | |
.to_uppercase() | |
.parse() | |
.expect("Cannot parse sentence"); | |
let rows: Vec<String> = input_lines | |
.take(h as usize) | |
.map(|x| x.trim_end().to_owned()) | |
.collect::<Vec<String>>(); | |
Ok(Self { | |
letter_width: w, | |
letter_height: h, | |
sentence: txt, | |
alphabet_rows: rows, | |
}) | |
} | |
fn process(self) -> String { | |
let mut text_out = String::new(); | |
for row in self.alphabet_rows { | |
// FIXME: For some reason, first character of first row is already consumed | |
for c in self.sentence.chars() { | |
let letter_width = self.letter_width as usize; | |
let idx_start = if c.is_ascii_uppercase() { | |
(c as usize - 'A' as usize) | |
} else { | |
26 | |
} * letter_width; | |
let substring = unsafe { row.get_unchecked(idx_start..(idx_start + letter_width)) }; | |
text_out.push_str(substring); | |
} | |
text_out.push('\n') | |
} | |
text_out | |
} | |
} | |
// Try with "E", "MANHATTAN", "ManhAtTan", "M@NH@TT@N" | |
#[test] | |
fn letters_4x5_with_only_f() { | |
let input = b"4\n5\nE | |
# ## ## ## ### ### ## # # ### ## # # # # # ### # ## # ## ## ### # # # # # # # # # # ### ### \n\ | |
# # # # # # # # # # # # # # # # # ### # # # # # # # # # # # # # # # # # # # # # # # # \n\ | |
### ## # # # ## ## # # ### # # ## # ### # # # # ## # # ## # # # # # # ### # # # ## \n\ | |
# # # # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # # # ### # # # # \n\ | |
# # ## ## ## ### # ## # # ### # # # ### # # # # # # # # # ## # ### # # # # # # ### # "; | |
let expected = "### \n\ | |
# \n\ | |
## \n\ | |
# \n\ | |
### \n"; | |
let actual = AsciiArtData::from(&input[..]).unwrap().process(); | |
println!("{}", actual); | |
assert_eq!(expected, actual); | |
} | |
#[test] | |
fn letters_4x5_with_uppercase_manhattan() { | |
let input = b"4\n5\nMANHATTAN | |
# ## ## ## ### ### ## # # ### ## # # # # # ### # ## # ## ## ### # # # # # # # # # # ### ### \n\ | |
# # # # # # # # # # # # # # # # # ### # # # # # # # # # # # # # # # # # # # # # # # # \n\ | |
### ## # # # ## ## # # ### # # ## # ### # # # # ## # # ## # # # # # # ### # # # ## \n\ | |
# # # # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # # # ### # # # # \n\ | |
# # ## ## ## ### # ## # # ### # # # ### # # # # # # # # # ## # ### # # # # # # ### # "; | |
let expected = "# # # ### # # # ### ### # ### \n\ | |
### # # # # # # # # # # # # # # \n\ | |
### ### # # ### ### # # ### # # \n\ | |
# # # # # # # # # # # # # # # # \n\ | |
# # # # # # # # # # # # # # # # \n"; | |
let actual = AsciiArtData::from(&input[..]).unwrap().process(); | |
println!("{}", actual); | |
assert_eq!(expected, actual); | |
} | |
fn main() { | |
let stdin = stdin(); | |
match AsciiArtData::from(stdin.lock()) { | |
Ok(data) => println!("{}", data.process()), | |
Err(err) => { | |
eprintln!("Input error: {}", err); | |
std::process::exit(1); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment