use std::{collections::VecDeque, io};
fn read_next<'a, I>(iter: &mut I) -> usize
where
I: Iterator<Item = &'a str>,
{
iter.next()
.expect("invalid input")
.parse::<usize>()
.expect("invalid integer")
}
#[derive(Clone, PartialEq)]
enum Pixel {
Inside,
Outside,
LineV,
LineH,
Line45L,
Line45R,
Point,
}
fn draw_line(a: (usize, usize), b: (usize, usize), grid: &mut Vec<Vec<Pixel>>) {
if a.0 == b.0 {
// V-line
let range;
if a.1 > b.1 {
range = b.1 + 1..a.1;
} else {
range = a.1 + 1..b.1;
}
for y in range {
grid[y][b.0] = Pixel::LineV;
}
} else if a.1 == b.1 {
// H-line
let range;
if a.0 > b.0 {
range = b.0 + 1..a.0;
} else {
range = a.0 + 1..b.0;
}
for x in range {
grid[b.1][x] = Pixel::LineH;
}
} else if a.0 < b.0 {
if a.1 < b.1 {
// 45-L
for i in 1..(b.0 - a.0) {
grid[a.1 + i][a.0 + i] = Pixel::Line45L;
}
} else {
// 45-R
for i in 1..(b.0 - a.0) {
grid[a.1 - i][a.0 + i] = Pixel::Line45R;
}
}
} else {
// 45
if a.1 < b.1 {
// 45-R
for i in 1..(a.0 - b.0) {
grid[b.1 - i][b.0 + i] = Pixel::Line45R;
}
} else {
// 45-L
for i in 1..(a.0 - b.0) {
grid[b.1 + i][b.0 + i] = Pixel::Line45L;
}
}
}
}
fn flood_fill(
queue: &mut VecDeque<(usize, usize)>,
grid: &mut Vec<Vec<Pixel>>,
n: usize,
m: usize,
) {
while queue.len() > 0 {
let (x, y) = queue.pop_front().expect("tried filling with empty queue");
match grid[y][x] {
Pixel::Outside => grid[y][x] = Pixel::Inside,
_ => continue,
}
if y < n {
queue.push_back((x, y + 1));
}
if n > 0 {
queue.push_back((x, y - 1));
}
if x < m {
queue.push_back((x + 1, y));
}
if x > 0 {
queue.push_back((x - 1, y));
}
}
}
fn main() {
// Input
let mut nmk = String::new();
io::stdin()
.read_line(&mut nmk)
.expect("failed to read line");
let mut nmk = nmk.split_ascii_whitespace();
let n = read_next(&mut nmk);
let m = read_next(&mut nmk);
let k = read_next(&mut nmk);
let mut xys: Vec<(usize, usize)> = Vec::with_capacity(k); // Is this required?
let mut grid: Vec<Vec<Pixel>> = vec![vec![Pixel::Outside; m]; n];
// Lines
for i in 0..k {
let mut xy = String::new();
io::stdin().read_line(&mut xy).expect("failed to read line");
let mut xy = xy.split_ascii_whitespace();
let y = read_next(&mut xy) - 1;
let x = read_next(&mut xy) - 1;
let b = (x, y);
xys.push(b);
grid[y][x] = Pixel::Point;
if i > 0 {
let a = xys[i - 1];
draw_line(a, b, &mut grid);
}
}
draw_line(xys[xys.len() - 1], xys[0], &mut grid);
// Find a point inside the drawing and initiate flood fill
for y in 0..n {
let mut inside = false;
let mut potential_inside_point: (usize, usize) = (0, 0);
for x in 0..m {
let pixel = &grid[y][x];
if match pixel {
Pixel::Outside => false,
_ => true,
} {
inside = !inside;
} else if inside {
potential_inside_point = (x, y);
}
}
if potential_inside_point != (0, 0) && !inside {
flood_fill(&mut VecDeque::from([potential_inside_point]), &mut grid);
break;
}
}
// Print output
for line in grid {
for pixel in line {
match pixel {
Pixel::Inside => print!("#"),
Pixel::Outside => print!("."),
Pixel::LineH => print!("="),
Pixel::LineV => print!("|"),
Pixel::Line45L => print!("\\"),
Pixel::Line45R => print!("/"),
Pixel::Point => print!("*"),
}
}
println!();
}
}