pub enum Algorithm {
STACK = 0,
MATRIX = 1,
}
pub fn zigzag_conversion(s: String, n_rows: i32, alg: Option<Algorithm>) -> String {
match alg.unwrap_or(Algorithm::STACK) {
Algorithm::MATRIX => convert_s1(s, n_rows as usize),
Algorithm::STACK => convert_s2(s, n_rows),
}
}
#[cfg(test)]
#[test]
fn test_zigzag_conversion() {
assert!(zigzag_conversion(String::from("PAPAL"), 1, None) == String::from("PAPAL"));
}
#[allow(unused_assignments)]
fn convert_s1(s: String, n_cols: usize) -> String {
let mut cur_row = 0u16;
let mut cur_col = 0u16;
let mut n_rows = 1;
let mut arr = vec![0u8; n_cols * 1000];
let mut direction = 0; let mut conv_idx = 0usize;
while conv_idx < s.len() {
arr[cur_row as usize * n_cols + cur_col as usize] = s.as_bytes()[conv_idx];
conv_idx += 1;
if cur_col == 0 {
if n_cols > 1 {
if direction == 1 {
direction = 0;
}
cur_col += 1;
} else {
cur_row += 1;
n_rows += 1;
}
} else {
if direction == 0 {
if cur_col < n_cols as u16 - 1 {
cur_col += 1;
} else {
direction = 1;
cur_col -= 1;
cur_row += 1;
n_rows += 1;
}
} else {
cur_col -= 1;
cur_row += 1;
n_rows += 1;
}
}
}
conv_idx = 0;
let mut output = vec![0u8; s.len()];
cur_row = 0;
cur_col = 0;
let mut str_idx = 0;
while conv_idx < s.len() {
str_idx = cur_row as usize * n_cols + cur_col as usize;
if arr[str_idx] != 0u8 {
output[conv_idx] = arr[str_idx];
conv_idx += 1;
}
if cur_row < n_rows - 1 {
cur_row += 1;
} else {
cur_row = 0;
cur_col += 1;
}
}
String::from_utf8(output.to_vec()).unwrap()
}
#[cfg(test)]
#[test]
fn test_conversion_s1() {
assert!(convert_s1(String::from("PAPAL"), 1) == String::from("PAPAL"));
}
fn convert_s2(s: String, num_rows: i32) -> String {
let mut rows = vec![String::new(); num_rows as usize];
let mut cur_row: i32 = 0;
let mut go_down: bool = true;
for val in s.bytes() {
rows[cur_row as usize].push(val as char);
if !go_down && cur_row == 0 {
go_down = true;
} else if go_down && cur_row == num_rows - 1 {
go_down = false;
}
if go_down {
cur_row += 1;
} else {
cur_row -= 1;
}
cur_row = i32::min(num_rows - 1, cur_row);
cur_row = i32::max(0, cur_row);
}
rows.join("").to_string()
}
#[cfg(test)]
#[test]
fn test_conversion_s2() {
assert!(convert_s2(String::from("PAPAL"), 2) == String::from("PPLAA"));
}