Prog 2 első verseny megoldásai

Utolsó módosítás: 2008. november 14.

Itt van egy-egy megoldás az első verseny feladataira. Ezek persze nem feltétlenül a legszebb vagy legegyszerűbb megoldások.

Tartalomjegyzék

csütörtök reggel 0. feladat (z0f0): lyukak kitöltése jobbra

A feladat kiírása; megoldás letöltése: z0f0.c.

#include <stdio.h>
#include <stdlib.h>

int
main(void) {
	int k, last, cur;
	last = -1;
	for (k = 0; k < 14; k++) {
		if (1 != scanf("%d", &cur))
			exit(1);
		if (0 != cur)
			last = cur;
		printf("%d%c", last, 13 == k ? '\n' : ' ');
	}
	return 0;
}

csütörtök reggel 1. feladat (z0f1): körlevél több soros mezővel

A feladat kiírása; megoldás letöltése: z0f1.c.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void
die(char *msg) {
	fprintf(stderr, "%s\n", msg);
	exit(1);
}

#define TEMPLATE_MAXLEN 10100
char
template[TEMPLATE_MAXLEN];

void
read_template(void) {
	int stop = 0;
	size_t pos = 0;
	while (!stop) {
		if (
			TEMPLATE_MAXLEN - pos < 2 ||
			!fgets(template + pos, TEMPLATE_MAXLEN - pos, stdin)
		)
			die("error reading template");
		if ('$' == template[pos])
			stop = 1;
		else
			pos += strlen(template + pos);
	}
}

#define LINE_MAXLEN 4010
char
line[LINE_MAXLEN];

int
more_mail(void) {
	int i;
	if (!fgets(line, LINE_MAXLEN, stdin))
		die("error reading record head");
	if (1 != sscanf(line, "%d", &i))
		die("error: record head has wrong format");
	return i;
}

void
process_mail(int wt) {
	size_t pos;
	size_t len;
	int cnt_mmark = 0;
	int k;
	for (pos = 0; '$' != template[pos]; pos++) {
		if ('@' == template[pos]) {
			pos++;
			if ('i' == template[pos]) {
				if (!fgets(line, LINE_MAXLEN, stdin))
					die("error reading record body");
				len = strlen(line);
				line[len - 1] = 0;
				fputs(line, stdout);
			} else if ('m' == template[pos] && '\n' == template[pos + 1]) {
				cnt_mmark++;
				for (k = 0; k < wt; k++) {
					if (!fgets(line, LINE_MAXLEN, stdin))
						die("error reading record body");
					fputs(line, stdout);
				}
				pos++;
			} else
				die("error: field marker has wrong format");
		} else
			putchar(template[pos]);
	}
	if (1 != cnt_mmark)
		die("exactly one m marker required in the template");
}

int
main(void) {
	int wt;
	read_template();
	while ((wt = more_mail()))
		process_mail(wt);
	return 0;
}

csütörtök reggel 2. feladat (z0f2): csempézés

A feladat kiírása; megoldás letöltése: z0f2.c.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void
die(char *msg) {
	fprintf(stderr, "%s\n", msg);
	exit(1);
}

char
mirror_char(char *key, char c) {
	while (key[0] && key[1]) {
		if (c == key[0])
			return key[1];
		if (c == key[1])
			return key[0];
		key += 2;
	}
	return c;
}

#define TEMPLATE_MAXHEIGHT 20
#define TEMPLATE_MAXWIDTH 20
#define STRIP_MAXWIDTH (2 + TEMPLATE_MAXWIDTH * 10)

int 
template_height,
template_width;
char
template[TEMPLATE_MAXHEIGHT][TEMPLATE_MAXWIDTH];
int
num_copies,
copy_mode,
num_vert_copies,
vert_copy_mode;
char
mirrored[TEMPLATE_MAXHEIGHT][TEMPLATE_MAXWIDTH];
char
strip[TEMPLATE_MAXHEIGHT][STRIP_MAXWIDTH],
strip_vert_mirrored[TEMPLATE_MAXHEIGHT][STRIP_MAXWIDTH];



void
read_template(void) {
	char line[TEMPLATE_MAXWIDTH + 5];
	int r;
	for (r = 0; r < template_height; r++) {
		if (!fgets(line, TEMPLATE_MAXWIDTH + 5, stdin))
			die("eof or error reading template line");
		if (template_width != strlen(line) - 1) 
			die("template line length wrong");
		memcpy(template[r], line, template_width);
	}
}

void
mirror_template(void) {
	int r, c;
	for (r = 0; r < template_height; r++) {
		for (c = 0; c < template_width; c++)
			mirrored[r][c] = mirror_char("()<>[]\\/", template[r][template_width - c - 1]);
	}
}

void
output_strip(void) {
	int row, copy;
	char *p; int l; char *out;
	for (row = 0; row < template_height; row++) {
		out = strip[row];
		for (copy = 0; copy < num_copies; copy++) {
			if (0 == copy % 2 || 0 == copy_mode) {
				p = template[row]; l = template_width;
			} else if (2 == copy_mode) {
				p = mirrored[row] + 1; l = template_width - 1;
			} else {
				p = mirrored[row]; l = template_width;
			}
			memcpy(out, p, l);
			out += l;
		}
		*out++ = '\n'; *out++ = 0;
	}
}

void
mirror_strip(void) {
	int r, c;
	for (r = 0; r < template_height; r++) {
		for (c = 0; strip[r][c]; c++) {
			strip_vert_mirrored[r][c] = mirror_char(",'\\/", strip[r][c]);
		}
	}
}

void
output_all(void) {
	int copy, row;
	for (copy = 0; copy < num_vert_copies; copy++) {
		if (0 == copy % 2 || 0 == vert_copy_mode) {
			for (row = 0; row < template_height; row++)
				fputs(strip[row], stdout);
		} else if (2 == vert_copy_mode) {
			for (row = template_height - 2; 0 <= row; row--)
				fputs(strip_vert_mirrored[row], stdout);
		} else {
			for (row = template_height - 1; 0 <= row; row--)
				fputs(strip_vert_mirrored[row], stdout);
		}
	}
}

int
main(void) {
	char line[500];
	if (!fgets(line, sizeof(line), stdin))
		die("error reading parameters");
	if (6 != sscanf(line, "%d%d%d%d%d%d", 
		&template_height, &template_width, &num_copies, &copy_mode, &num_vert_copies, &vert_copy_mode
	))
		die("error parsing parameters");
	if (
		TEMPLATE_MAXHEIGHT < template_height || template_height < 0 ||
		TEMPLATE_MAXWIDTH < template_width || template_width < 0 ||
		2 < copy_mode || copy_mode < 0
	)
		die("invalid parameters");
	read_template();
	mirror_template();
	output_strip();
	mirror_strip();
	output_all();
	return 0;
}

csütörtök reggel 3. feladat (z0f3): algebrai kifejezések kirajzolása faktoriálissal

A feladat kiírása; megoldás letöltése: z0f3.c.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int
max(int x, int y) {
	return x < y ? y : x;
}

#define PLANBUF_LEN 512

#define PREC_ATOM 0
#define PREC_POWER 2
#define PREC_QUOTIENT 3
#define PREC_PRODUCT 4
#define PREC_SUM 5
#define PREC_FACTOR 6

struct
plan {
	int width;
	int height;
	int depth;
	int prec;
	int head;
	const struct plan *lhs;
	const struct plan *rhs;
} planbuf[PLANBUF_LEN];
int
plancnt;

void
init(void) {
	plancnt = 0;
}

struct plan *
allocplan(void) {
	struct plan *r;
	r = planbuf + plancnt++;
	if (PLANBUF_LEN < plancnt)
		exit(1);
	r->lhs = r->rhs = 0;
	r->prec = r->head = -1;
	r->width = r->height = r->depth = 32767;
	return r;
}

const struct plan *
parenthisize(const struct plan *l) {
	struct plan *p;
	p = allocplan();
	p->head = '(';
	p->lhs = l;
	p->width = l->width + 2;
	p->height = l->height;
	p->depth = l->depth;
	p->prec = PREC_ATOM;
	return p;
}

const struct plan *
layout(const char **formulap) {
	struct plan *p;
	char head;
	const struct plan *l, *r;
	p = allocplan();
	p->head = head = *(*formulap)++;
	if (isdigit(head) || islower(head)) {
		p->width = 1;
		p->height = 1;
		p->depth = 0;
		p->prec = PREC_ATOM;
	} else {
		l = layout(formulap);
		if ('!' == head) {
			if (PREC_POWER <= l->prec)
				l = parenthisize(l);
			p->width = l->width + 1;
			p->height = l->height;
			p->depth = l->depth;
			p->prec = PREC_ATOM;
		} else {
			r = layout(formulap);
			if ('^' == head) {
				if (PREC_POWER <= l->prec)
					l = parenthisize(l);
				p->width = l->width + r->width;
				p->height = l->height + r->depth + r->height;
				p->depth = l->depth;
				p->prec = PREC_POWER;
			} else if ('/' == head) {
				p->width = 2 + max(l->width, r->width);
				p->height = 1 + l->height + l->depth;
				p->depth = r->height + r->depth;
				p->prec = PREC_QUOTIENT;
			} else if ('*' == head) {
				if (PREC_PRODUCT < l->prec)
					l = parenthisize(l);
				if (PREC_PRODUCT <= r->prec)
					r = parenthisize(r);
				p->width = 1 + l->width + r->width;
				p->height = max(l->height, r->height);
				p->depth = max(l->depth, r->depth);
				p->prec = PREC_PRODUCT;
			} else if ('+' == head || '-' == head) {
				if (PREC_SUM <= r->prec)
					r = parenthisize(r);
				p->width = 3 + l->width + r->width;
				p->height = max(l->height, r->height);
				p->depth = max(l->depth, r->depth);
				p->prec = PREC_SUM;
			} else 
				exit(1);
			p->rhs = r;
		}
		p->lhs = l;
	}
	return p;
}

#define PAPER_WIDTH 500
#define PAPER_HEIGHT 100

char
paper[PAPER_HEIGHT][PAPER_WIDTH];
int
box_height, box_width;

void
erase(const struct plan *p) {
	int r, c;
	box_height = p->height + p->depth;
	box_width = p->width;
	if (PAPER_HEIGHT < box_height || PAPER_WIDTH < box_width)
		exit(1);
	for (r = 0; r < box_height; r++)
		for (c = 0; c < box_width; c++)
			paper[r][c] = ' ';
}

void
output(void) {
	int r, w, c;
	for (r = 0; r < box_height; r++) {
		w = box_width;
		while (' ' == paper[r][w - 1])
			w--;
		for (c = 0; c < w; c++)
			putchar(paper[r][c]);
		putchar('\n');
	}
	putchar('\n');
}

void
paint(const struct plan *p, int row, int col) {
	int r, c;
	int head;
	if (
		row - p->height + 1 < 0 || 
		box_height < row + p->depth ||
		col < 0 ||
		box_width < col + p->width
	)
		exit(1);
	head = p->head;
	switch (head) {
		case '(':
			for (r = row - p->height + 1; r <= row + p->depth; r++) {
				paper[r][col] = '(';
				paper[r][col + p->width - 1] = ')';
			}
			paint(p->lhs, row, 1 + col);
			break;
		case '!':
			paint(p->lhs, row, col);
			paper[row][col + p->lhs->width] = '!';
			break;
		case '^':
			paint(p->lhs, row, col);
			paint(p->rhs, row - p->lhs->height - p->rhs->depth, col + p->lhs->width);
			break;
		case '/':
			for (c = col; c < col + p->width; c++)
				paper[row][c] = '-';
			paint(p->lhs, row - 1 - p->lhs->depth, col + (p->width - p->lhs->width)/2);
			paint(p->rhs, row + p->rhs->height, col + (p->width - p->rhs->width)/2);
			break;
		case '*':
			paint(p->lhs, row, col);
			paint(p->rhs, row, 1 + col + p->lhs->width);
			break;
		case '+': case '-':
			paint(p->lhs, row, col);
			paper[row][1 + col + p->lhs->width] = head;
			paint(p->rhs, row, 3 + col + p->lhs->width);
			break;
		default:
			if (isdigit(head) || islower(head))
				paper[row][col] = head;
			else
				exit(1);
			break;
	}
}

void
paint_main(const struct plan *p) {
	paint(p, p->height - 1, 0);
}

#define FORMULA_LEN 512

int
main(void) {
	char formulabuf[FORMULA_LEN];
	const struct plan *p;
	const char *formula;
	while (fgets(formulabuf, FORMULA_LEN, stdin)) {
		formula = formulabuf;
		init();
		p = layout(&formula);
		if ('\n' != *formula)
			exit(1);
		erase(p);
		paint_main(p);
		output();
	}
	return 0;
}

csütörtök délután 0. feladat (z1f0): felváltott előjelű összeg

A feladat kiírása; megoldás letöltése: z1f0.c.

#include <stdio.h>
#include <stdlib.h>

int
main(void) {
	int k, e0, e1, sum;
	sum = 0;
	for (k = 0; k < 7; k++) {
		if (2 != scanf("%d%d", &e0, &e1))
			exit(1);
		sum = sum + e0 - e1;
	}
	printf("%d\n", sum);
	return 0;
}

csütörtök délután 1. feladat (z1f1): körlevél több változattal

A feladat kiírása; megoldás letöltése: z1f1.c.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void
die(char *msg) {
	fprintf(stderr, "%s\n", msg);
	exit(1);
}

#define TEMPLATE_MAXLEN 10100
char
template[TEMPLATE_MAXLEN];

void
read_template(void) {
	int stop = 0;
	size_t pos = 0;
	while (!stop) {
		if (
			TEMPLATE_MAXLEN - pos < 2 ||
			!fgets(template + pos, TEMPLATE_MAXLEN - pos, stdin)
		)
			die("error reading template");
		if ('$' == template[pos])
			stop = 1;
		else
			pos += strlen(template + pos);
	}
}

#define LINE_MAXLEN 4010
char
line[LINE_MAXLEN];

int
more_mail(void) {
	int i;
	if (!fgets(line, LINE_MAXLEN, stdin))
		die("error reading record head");
	if (1 != sscanf(line, "%d", &i))
		die("error: record head has wrong format");
	return i;
}

void
process_mail(int weight) {
	size_t pos;
	size_t len;
	int state, branch;
	state = -1; branch = -99;
	for (pos = 0; '$' != template[pos]; pos++) {
		if ('@' == template[pos]) {
			pos++;
			if ('i' == template[pos]) {
				if (state || weight == branch) {
					if (!fgets(line, LINE_MAXLEN, stdin))
						die("error reading record body");
					len = strlen(line);
					line[len - 1] = 0;
					fputs(line, stdout);
				}
			} else if ('s' == template[pos]) {
				if (-1 != state)
					die("error: multiple select case markers");
				state = 0; branch = 1;
			} else if ('c' == template[pos]) {
				if (0 != state)
					die("error: case marker outside select");
				branch++;
			} else if ('e' == template[pos]) {
				if (0 != state)
					die("error: end select marker outside select");
				state = 1;
			} else
				die("error: field marker has wrong format");
		} else {
			if (state || weight == branch)
				putchar(template[pos]);
		}
	}
}

int
main(void) {
	int wt;
	read_template();
	while ((wt = more_mail()))
		process_mail(wt);
	return 0;
}

csütörtök délután 2. feladat (z1f2): szobafoglalás

A feladat kiírása; megoldás letöltése: z1f2.c.

#include <stdio.h>
#include <stdlib.h>

#define NUM_DAYS 60

int
main(void) {
	int reserve1[NUM_DAYS], reserve2[NUM_DAYS];
	int num_rooms1, num_rooms2, num_calls;
	int first, last, need1, need2;
	int r, d, ok;
	for (d = 0; d < NUM_DAYS; d++) {
		reserve1[d] = 0; reserve2[d] = 0;
	}
	if (3 != scanf("%d%d%d", &num_rooms1, &num_rooms2, &num_calls))
		exit(1);
	for (r = 0; r < num_calls; r++) {
		if (4 != scanf("%d%d%d%d", &first, &last, &need1, &need2))
			exit(1);
		if (first < 0 || last < first || NUM_DAYS <= last || need1 < 0 || need2 < 0)
			exit(1);
		ok = 1;
		for (d = first; d <= last; d++) {
			if (num_rooms1 < reserve1[d] + need1 || num_rooms2 < reserve2[d] + need2)
				ok = 0;
		}
		if (ok) {
			for (d = first; d <= last; d++) {
				reserve1[d] += need1; reserve2[d] += need2;
			}
			printf("1\n");
		} else {
			printf("0\n");
		}
	}
	return 0;
}

csütörtök délután 3. feladat (z1f3): algebrai kifejezések kirajzolása binomiális együtthatóval

A feladat kiírása; megoldás letöltése: z1f3.c.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int
max(int x, int y) {
	return x < y ? y : x;
}

#define PLANBUF_LEN 512

#define PREC_ATOM 0
#define PREC_POWER 2
#define PREC_QUOTIENT 3
#define PREC_PRODUCT 4
#define PREC_SUM 5

struct
plan {
	int width;
	int height;
	int depth;
	int prec;
	int head;
	const struct plan *lhs;
	const struct plan *rhs;
} planbuf[PLANBUF_LEN];
int
plancnt;

void
init(void) {
	plancnt = 0;
}

struct plan *
allocplan(void) {
	struct plan *r;
	r = planbuf + plancnt++;
	if (PLANBUF_LEN < plancnt)
		exit(1);
	r->lhs = r->rhs = 0;
	r->prec = r->head = -1;
	r->width = r->height = r->depth = 32767;
	return r;
}

const struct plan *
parenthisize(const struct plan *l) {
	struct plan *p;
	p = allocplan();
	p->head = '(';
	p->lhs = l;
	p->width = l->width + 2;
	p->height = l->height;
	p->depth = l->depth;
	p->prec = PREC_ATOM;
	return p;
}

const struct plan *
layout(const char **formulap) {
	struct plan *p;
	char head;
	const struct plan *l, *r;
	p = allocplan();
	p->head = head = *(*formulap)++;
	if (isdigit(head) || islower(head)) {
		p->width = 1;
		p->height = 1;
		p->depth = 0;
		p->prec = PREC_ATOM;
	} else {
		l = layout(formulap);
		r = layout(formulap);
		if ('?' == head) {
			p->width = 2 + max(l->width, r->width);
			p->height = 1 + l->height + l->depth;
			p->depth = r->height + r->depth;
			p->prec = PREC_ATOM;
		} else if ('^' == head) {
			if (PREC_POWER <= l->prec)
				l = parenthisize(l);
			p->width = l->width + r->width;
			p->height = l->height + r->depth + r->height;
			p->depth = l->depth;
			p->prec = PREC_POWER;
		} else if ('/' == head) {
			p->width = 2 + max(l->width, r->width);
			p->height = 1 + l->height + l->depth;
			p->depth = r->height + r->depth;
			p->prec = PREC_QUOTIENT;
		} else if ('*' == head) {
			if (PREC_PRODUCT < l->prec)
				l = parenthisize(l);
			if (PREC_PRODUCT <= r->prec)
				r = parenthisize(r);
			p->width = 1 + l->width + r->width;
			p->height = max(l->height, r->height);
			p->depth = max(l->depth, r->depth);
			p->prec = PREC_PRODUCT;
		} else if ('+' == head || '-' == head) {
			if (PREC_SUM <= r->prec)
				r = parenthisize(r);
			p->width = 3 + l->width + r->width;
			p->height = max(l->height, r->height);
			p->depth = max(l->depth, r->depth);
			p->prec = PREC_SUM;
		} else 
			exit(1);
		p->lhs = l;
		p->rhs = r;
	}
	return p;
}

#define PAPER_WIDTH 500
#define PAPER_HEIGHT 100

char
paper[PAPER_HEIGHT][PAPER_WIDTH];
int
box_height, box_width;

void
erase(const struct plan *p) {
	int r, c;
	box_height = p->height + p->depth;
	box_width = p->width;
	if (PAPER_HEIGHT < box_height || PAPER_WIDTH < box_width)
		exit(1);
	for (r = 0; r < box_height; r++)
		for (c = 0; c < box_width; c++)
			paper[r][c] = ' ';
}

void
output(void) {
	int r, w, c;
	for (r = 0; r < box_height; r++) {
		w = box_width;
		while (' ' == paper[r][w - 1])
			w--;
		for (c = 0; c < w; c++)
			putchar(paper[r][c]);
		putchar('\n');
	}
	putchar('\n');
}

void
paint(const struct plan *p, int row, int col) {
	int r, c;
	int head;
	if (
		row - p->height + 1 < 0 || 
		box_height < row + p->depth ||
		col < 0 ||
		box_width < col + p->width
	)
		exit(1);
	head = p->head;
	switch (head) {
		case '(':
			for (r = row - p->height + 1; r <= row + p->depth; r++) {
				paper[r][col] = '(';
				paper[r][col + p->width - 1] = ')';
			}
			paint(p->lhs, row, 1 + col);
			break;
		case '?':
			for (r = row - p->height + 1; r <= row + p->depth; r++) {
				paper[r][col] = '(';
				paper[r][col + p->width - 1] = ')';
			}
			paint(p->lhs, row - 1 - p->lhs->depth, col + (p->width - p->lhs->width)/2);
			paint(p->rhs, row + p->rhs->height, col + (p->width - p->rhs->width)/2);
			break;
		case '^':
			paint(p->lhs, row, col);
			paint(p->rhs, row - p->lhs->height - p->rhs->depth, col + p->lhs->width);
			break;
		case '/':
			for (c = col; c < col + p->width; c++)
				paper[row][c] = '-';
			paint(p->lhs, row - 1 - p->lhs->depth, col + (p->width - p->lhs->width)/2);
			paint(p->rhs, row + p->rhs->height, col + (p->width - p->rhs->width)/2);
			break;
		case '*':
			paint(p->lhs, row, col);
			paint(p->rhs, row, 1 + col + p->lhs->width);
			break;
		case '+': case '-':
			paint(p->lhs, row, col);
			paper[row][1 + col + p->lhs->width] = head;
			paint(p->rhs, row, 3 + col + p->lhs->width);
			break;
		default:
			if (isdigit(head) || islower(head))
				paper[row][col] = head;
			else
				exit(1);
			break;
	}
}

void
paint_main(const struct plan *p) {
	paint(p, p->height - 1, 0);
}

#define FORMULA_LEN 512

int
main(void) {
	char formulabuf[FORMULA_LEN];
	const struct plan *p;
	const char *formula;
	while (fgets(formulabuf, FORMULA_LEN, stdin)) {
		formula = formulabuf;
		init();
		p = layout(&formula);
		if ('\n' != *formula)
			exit(1);
		erase(p);
		paint_main(p);
		output();
	}
	return 0;
}

péntek reggel 0. feladat (z2f0): lefele lépések száma

A feladat kiírása; megoldás letöltése: z2f0.c.

#include <stdio.h>
#include <stdlib.h>

int
main(void) {
	int k, last, cur, out;
	last = 0;
	out = 0;
	for (k = 0; k < 14; k++) {
		if (1 != scanf("%d", &cur))
			exit(1);
		if (0 < k && cur < last)
			out++;
		last = cur;
	}
	printf("%d\n", out);
	return 0;
}

péntek reggel 1. feladat (z2f1): körlevél hosszú vonallal

A feladat kiírása; megoldás letöltése: z2f1.c.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void
die(char *msg) {
	fprintf(stderr, "%s\n", msg);
	exit(1);
}

#define TEMPLATE_MAXLEN 10100
char
template[TEMPLATE_MAXLEN];

void
read_template(void) {
	int stop = 0;
	size_t pos = 0;
	while (!stop) {
		if (
			TEMPLATE_MAXLEN - pos < 2 ||
			!fgets(template + pos, TEMPLATE_MAXLEN - pos, stdin)
		)
			die("error reading template");
		if ('$' == template[pos])
			stop = 1;
		else
			pos += strlen(template + pos);
	}
}

#define LINE_MAXLEN 4010
char
line[LINE_MAXLEN];

int
more_mail(void) {
	int i;
	if (!fgets(line, LINE_MAXLEN, stdin))
		die("error reading record head");
	if (1 != sscanf(line, "%d", &i))
		die("error: record head has wrong format");
	return i;
}

void
process_mail(int wt) {
	size_t pos;
	size_t len;
	int k;
	for (pos = 0; '$' != template[pos]; pos++) {
		if ('@' == template[pos]) {
			pos++;
			if ('i' == template[pos]) {
				if (!fgets(line, LINE_MAXLEN, stdin))
					die("error reading record body");
				len = strlen(line);
				line[len - 1] = 0;
				fputs(line, stdout);
			} else if ('h') {
				for (k = 0; k < wt; k++)
					putchar('-');
			} else
				die("error: field marker has wrong format");
		} else
			putchar(template[pos]);
	}
}

int
main(void) {
	int wt;
	read_template();
	while ((wt = more_mail()))
		process_mail(wt);
	return 0;
}

péntek reggel 2. feladat (z2f2): buszos átszállás

A feladat kiírása; megoldás letöltése: z2f2.c.

#include <stdio.h>
#include <stdlib.h>

#define MAX_TRAIN 50

void
printtime(int t) {
	printf("%02d:%02d", t/60, t%60);
}

int
scantime() {
	int hour, min;
	if (2 != scanf("%d:%d", &hour, &min))
		exit(1);
	return 60 * hour + min;
}

int
train0_depart[MAX_TRAIN],
train0_arrive[MAX_TRAIN];
int
train1_depart[MAX_TRAIN],
train1_arrive[MAX_TRAIN];

int
main(void) {
	int ntrains0, ntrains1, k;
	int leave_time, first_walk, board0_time, board1_time,
		latest_unboard0_time, latest_unboard1_time, second_walk, latest_arrive_time;
	if (1 != scanf("%d", &first_walk))
		exit(1);
	latest_arrive_time = scantime();
	if (1 != scanf("%d", &second_walk))
		exit(1);
	latest_unboard1_time = latest_arrive_time - second_walk;
	if (1 != scanf("%d", &ntrains0))
		exit(1);
	for (k = 0; k < ntrains0; k++) {
		train0_depart[k] = scantime();
		train0_arrive[k] = scantime();
	}
	if (1 != scanf("%d", &ntrains1))
		exit(1);
	for (k = 0; k < ntrains1; k++) {
		train1_depart[k] = scantime();
		train1_arrive[k] = scantime();
	}
	board1_time = -10000;
	for (k = 0; k < ntrains1; k++) {
		if (train1_arrive[k] <= latest_unboard1_time) {
			if (board1_time < train1_depart[k]) {
				board1_time = train1_depart[k];
			}
		}
	}
	latest_unboard0_time = board1_time;
	board0_time = -10000;
	for (k = 0; k < ntrains0; k++) {
		if (train0_arrive[k] <= latest_unboard0_time) {
			if (board0_time < train0_depart[k]) {
				board0_time = train0_depart[k];
			}
		}
	}
	leave_time = board0_time - first_walk;
	printtime(leave_time);
	printf("\n");
	return 0;
}

péntek reggel 3. feladat (z2f3): algebrai kifejezések kirajzolása: szebb hatványok

A feladat kiírása; megoldás letöltése: z2f3.c.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int
max(int x, int y) {
	return x < y ? y : x;
}

#define PLANBUF_LEN 512

#define PREC_ATOM 0
#define PREC_POWER 2
#define PREC_QUOTIENT 3
#define PREC_PRODUCT 4
#define PREC_SUM 5

struct
plan {
	int width;
	int height;
	int depth;
	int prec;
	int head;
	const struct plan *lhs;
	const struct plan *rhs;
} planbuf[PLANBUF_LEN];
int
plancnt;

void
init(void) {
	plancnt = 0;
}

struct plan *
allocplan(void) {
	struct plan *r;
	r = planbuf + plancnt++;
	if (PLANBUF_LEN < plancnt)
		exit(1);
	r->lhs = r->rhs = 0;
	r->prec = r->head = -1;
	r->width = r->height = r->depth = 32767;
	return r;
}

const struct plan *
parenthisize(const struct plan *l) {
	struct plan *p;
	p = allocplan();
	p->head = '(';
	p->lhs = l;
	p->width = l->width + 2;
	p->height = l->height;
	p->depth = l->depth;
	p->prec = PREC_ATOM;
	return p;
}

const struct plan *
layout(const char **formulap) {
	struct plan *p;
	char head;
	const struct plan *l, *r;
	p = allocplan();
	p->head = head = *(*formulap)++;
	if (isdigit(head) || islower(head)) {
		p->width = 1;
		p->height = 1;
		p->depth = 0;
		p->prec = PREC_ATOM;
	} else {
		l = layout(formulap);
		r = layout(formulap);
		if ('^' == head) {
			if (PREC_POWER <= l->prec)
				l = parenthisize(l);
			p->width = l->width + r->width;
			p->height = max(l->height, 1 + r->depth + r->height);
			p->depth = l->depth;
			p->prec = PREC_POWER;
		} else if ('/' == head) {
			p->width = 2 + max(l->width, r->width);
			p->height = 1 + l->height + l->depth;
			p->depth = r->height + r->depth;
			p->prec = PREC_QUOTIENT;
		} else if ('*' == head) {
			if (PREC_PRODUCT < l->prec)
				l = parenthisize(l);
			if (PREC_PRODUCT <= r->prec)
				r = parenthisize(r);
			p->width = 1 + l->width + r->width;
			p->height = max(l->height, r->height);
			p->depth = max(l->depth, r->depth);
			p->prec = PREC_PRODUCT;
		} else if ('+' == head || '-' == head) {
			if (PREC_SUM <= r->prec)
				r = parenthisize(r);
			p->width = 3 + l->width + r->width;
			p->height = max(l->height, r->height);
			p->depth = max(l->depth, r->depth);
			p->prec = PREC_SUM;
		} else 
			exit(1);
		p->lhs = l;
		p->rhs = r;
	}
	return p;
}

#define PAPER_WIDTH 500
#define PAPER_HEIGHT 100

char
paper[PAPER_HEIGHT][PAPER_WIDTH];
int
box_height, box_width;

void
erase(const struct plan *p) {
	int r, c;
	box_height = p->height + p->depth;
	box_width = p->width;
	if (PAPER_HEIGHT < box_height || PAPER_WIDTH < box_width)
		exit(1);
	for (r = 0; r < box_height; r++)
		for (c = 0; c < box_width; c++)
			paper[r][c] = ' ';
}

void
output(void) {
	int r, w, c;
	for (r = 0; r < box_height; r++) {
		w = box_width;
		while (' ' == paper[r][w - 1])
			w--;
		for (c = 0; c < w; c++)
			putchar(paper[r][c]);
		putchar('\n');
	}
	putchar('\n');
}

void
paint(const struct plan *p, int row, int col) {
	int r, c;
	int head;
	if (
		row - p->height + 1 < 0 || 
		box_height < row + p->depth ||
		col < 0 ||
		box_width < col + p->width
	)
		exit(1);
	head = p->head;
	switch (head) {
		case '(':
			for (r = row - p->height + 1; r <= row + p->depth; r++) {
				paper[r][col] = '(';
				paper[r][col + p->width - 1] = ')';
			}
			paint(p->lhs, row, 1 + col);
			break;
		case '^':
			paint(p->lhs, row, col);
			paint(p->rhs, row - max(p->lhs->height - p->rhs->height, 1 + p->rhs->depth), col + p->lhs->width);
			break;
		case '/':
			for (c = col; c < col + p->width; c++)
				paper[row][c] = '-';
			paint(p->lhs, row - 1 - p->lhs->depth, col + (p->width - p->lhs->width)/2);
			paint(p->rhs, row + p->rhs->height, col + (p->width - p->rhs->width)/2);
			break;
		case '*':
			paint(p->lhs, row, col);
			paint(p->rhs, row, 1 + col + p->lhs->width);
			break;
		case '+': case '-':
			paint(p->lhs, row, col);
			paper[row][1 + col + p->lhs->width] = head;
			paint(p->rhs, row, 3 + col + p->lhs->width);
			break;
		default:
			if (isdigit(head) || islower(head))
				paper[row][col] = head;
			else
				exit(1);
			break;
	}
}

void
paint_main(const struct plan *p) {
	paint(p, p->height - 1, 0);
}

#define FORMULA_LEN 512

int
main(void) {
	char formulabuf[FORMULA_LEN];
	const struct plan *p;
	const char *formula;
	while (fgets(formulabuf, FORMULA_LEN, stdin)) {
		formula = formulabuf;
		init();
		p = layout(&formula);
		if ('\n' != *formula)
			exit(1);
		erase(p);
		paint_main(p);
		output();
	}
	return 0;
}