Instruens Fabulam
Difficulty: Hard

*Instruens Fabulam means drawing a chart (or table) in Latin. That's what you will do for this problem.*

The input consists of one or more table descriptions, followed by a line whose first character is `'*'`, which signals the end of the input. Each description begins with a header line containing one or more characters that define the number and alignment of columns in the table. Each character in the header line is either `'<'`, `'='`, or `'>'`, and indicates a left-justified, centered, or right-justified column. Following the header are at least two and at most 21 data lines that contain the entries for each row. Each data line consists of one or more nonempty entries separated by an ampersand (`'&'`), where the number of entries is equal to the number of columns defined in the header line. The first data line contains entries for the column titles, and the remaining data lines contain entries for the body of the table. Spaces may appear within an entry, but never at the beginning or end of an entry. The characters `'<'`, `'='`, `'>'`, `'&'`, and `'*'` will not appear in the input except where indicated above.

For each table description, output the table using the exact format shown in the examples. Note that:

* The total width of the table will never exceed 79 characters (not counting end-of-line).
* Dashes ('-') are used to draw horizontal lines, not underscores ('_'). 'At' signs ('@') appear at each of the four outer corners. Plus signs ('+') appear at intersections within the line separating the title from the body.
* The largest entry in a column is always separated from the enclosing bars ('|') by exactly one space.
* If a centered entry cannot be exactly centered within a column, the extra space goes on the right of the entry.


**Example Input:**

	<>=>
	TITLE&VERSION&OPERATING SYSTEM&PRICE
	Slug Farm&2.0&FreeBSD&49.99
	Figs of Doom&1.7&Linux&9.98
	Smiley Goes to Happy Town&11.0&Windows&129.25
	Wheelbarrow Motocross&1.0&BeOS&34.97
	>
	What is the answer?
	42
	<>
	Tweedledum&Tweedledee
	"Knock, knock."&"Who's there?"
	"Boo."&"Boo who?"
	"Don't cry, it's only me."&(groan)
	*
    
**Expected Output:**

	@-----------------------------------------------------------------@
	| TITLE                     | VERSION | OPERATING SYSTEM |  PRICE |
	|---------------------------+---------+------------------+--------|
	| Slug Farm                 |     2.0 |     FreeBSD      |  49.99 |
	| Figs of Doom              |     1.7 |      Linux       |   9.98 |
	| Smiley Goes to Happy Town |    11.0 |     Windows      | 129.25 |
	| Wheelbarrow Motocross     |     1.0 |       BeOS       |  34.97 |
	@-----------------------------------------------------------------@
	@---------------------@
	| What is the answer? |
	|---------------------|
	|                  42 |
	@---------------------@
	@---------------------------------------------@
	| Tweedledum                 |     Tweedledee |
	|----------------------------+----------------|	
	| "Knock, knock."            | "Who's there?" |
	| "Boo."                     |     "Boo who?" |
	| "Don't cry, it's only me." |        (groan) |
	@---------------------------------------------@

Input Format:

Output Format:

Sample Input:

Sample Output:

Python 3 starter code:


Reference solution (C++):
	#include <stdio.h>
	#include <stdlib.h>
	#include <string.h>

	#define LEFT   '<'
	#define RIGHT  '>'
	#define CENTER '='

	enum {MAX_ROWS = 21, MAX_COLS = 19};
	enum {HEADER, ROW, END};

	FILE *in;
	FILE *out;

	int rows;                           /* number of rows in the table */
	int columns;                        /* number of columns in the table */

	char align[MAX_COLS + 1];           /* alignment of each column */
	int  max_width[MAX_COLS];           /* maximum width of column */

	char *entry[MAX_ROWS][MAX_COLS];    /* text of each entry */
	int width[MAX_ROWS][MAX_COLS];      /* width of each entry */

	char line[80 + 1];                  /* the last line read from the file */
	int line_type;                      /* HEADER, ROW, or END */



	int read_line(void)
	{
    fgets(line, sizeof(line), in);
    line[strlen(line) - 1] = '\0';
    
    if (line[0] == '*')
        line_type = END;
    else if (line[0]==LEFT || line[0]==RIGHT || line[0]==CENTER)
        line_type = HEADER;
    else
        line_type = ROW;
    
    return line_type;
	}



	void process_header(void)
	{
    int c;
    
    columns = strlen(line);
    strcpy(align, line);
    
    for (c = 0; c < columns; ++c)
        max_width[c] = 0;
	}



	void read_rows(void)
	{
    rows = 0;
    
    while (read_line() == ROW) {
        char *s;
        int c = 0;
                
        for (s = strtok(line, "&"); s != NULL; s = strtok(NULL, "&")) {
            int n = strlen(s);
            
            entry[rows][c] = strdup(s);
            width[rows][c] = n;
            
            if (n > max_width[c]) max_width[c] = n;
            
            ++c;
        }
        
        ++rows;
    }
	}



	void print_char(int ch, int n) 
	{
    int i;
    
    for (i = 0; i < n; ++i) fputc(ch, out);
	}



	void print_row(int r)
	{	
    int c;
    
    for (c = 0; c < columns; ++c) {
        int n = width[r][c];
        int pad = max_width[c] - n;
        
        fprintf(out, "| ");
        switch (align[c]) {
            case LEFT:
                fprintf(out, "%s", entry[r][c]);
                print_char(' ', pad);
                break;
            case RIGHT:
                print_char(' ', pad);
                fprintf(out, "%s", entry[r][c]);
                break;
            case CENTER:
                print_char(' ', pad / 2);
                fprintf(out, "%s", entry[r][c]);
                print_char(' ', pad - (pad/2));
        }
        fprintf(out, " ");
    }
    
    fprintf(out, "|\n");
	}



	void print_separator(int outer_char, int inner_char)
	{
    int c;
    
    print_char(outer_char, 1);
    print_char('-', max_width[0] + 2);
    
    for (c = 1; c < columns; ++c) {
        print_char(inner_char, 1);
        print_char('-', max_width[c] + 2);
    }
    
    print_char(outer_char, 1);
    fputc('\n', out);
	}



	int main(void)
	{
    in = fopen("fab.in", "r");
    out = fopen("fab.out", "w");
    
    read_line();
    while (line_type != END) {
        int r;
        
        process_header();
        read_rows();
        
        print_separator('@', '-');
        print_row(0);
        print_separator('|', '+');
        
        for (r = 1; r < rows; ++r) print_row(r);
        
        print_separator('@', '-');
    }
        
    fclose(in);
    fclose(out);
    
    return 0;
	}