/// Build the character sequence for a given row.
/// The row index is expressed as a signed distance from the center:
/// i = -(n-1) .. (n-1)
/// We convert that into how many characters appear in the row,
/// then build the descending and ascending sides.
fn build_row(n: usize, dist: isize) -> String {
// Distance from the center row
let d = dist.abs() as usize;
// Number of characters on each side before mirroring
let count = n - d;
// Build descending side: e.g., e d c ...
let mut chars = Vec::with_capacity(count * 2 - 1);
for j in 0..count {
let ch = (b'a' + (n - 1 - j) as u8) as char;
chars.push(ch);
}
// Build ascending side: e.g., ... c d e
for j in (0..count - 1).rev() {
let ch = (b'a' + (n - 1 - j) as u8) as char;
chars.push(ch);
}
// Insert hyphens between characters
let mut row = String::new();
for (i, ch) in chars.iter().enumerate() {
if i > 0 {
row.push('-');
}
row.push(*ch);
}
row
}
/// Build the full rangoli as a vector of centered lines.
fn build_rangoli(n: usize) -> Vec<String> {
let total_width = 4 * n - 3;
let mut lines = Vec::new();
// Loop from -(n-1) to +(n-1) to handle symmetry
for i in -(n as isize - 1)..=(n as isize - 1) {
let row = build_row(n, i);
// Compute padding for centering
let padding = total_width.saturating_sub(row.len());
let side = padding / 2;
// Construct final line
let mut line = String::new();
line.push_str(&"-".repeat(side));
line.push_str(&row);
line.push_str(&"-".repeat(side));
lines.push(line);
}
lines
}
fn main() {
let n = 5; // Change this to generate other sizes
for line in build_rangoli(n) {
println!("{}", line);
}
}
/*
run:
--------e--------
------e-d-e------
----e-d-c-d-e----
--e-d-c-b-c-d-e--
e-d-c-b-a-b-c-d-e
--e-d-c-b-c-d-e--
----e-d-c-d-e----
------e-d-e------
--------e--------
*/