#include #include #include #include #include typedef unsigned char byte; #define MAX_SIZE 100 #define MAX_SIZE_D8 ((MAX_SIZE+7)/8) struct Piece { int size; int min; int max; bool pos[MAX_SIZE]; void init(int p, int s) { min = p; max = p + s; for (int i = 0; i < MAX_SIZE; i++) pos[i] = min <= i && i < max; } }; struct Pieces { int nr; Piece pieces[MAX_SIZE]; void add(int v) { pieces[nr++].size = v; } void init(int size) { int sum = 0; for (int i = 0; i < nr; i++) sum += pieces[i].size; int left = size - (sum + nr - 1); if (left < 0) left = 0; int p = 0; for (int i = 0; i < nr; i++) { pieces[i].init(p, left+1); p += pieces[i].size + 1; } } }; int n; int m; int nm; #define UNKNOWN '?' #define FULL '*' #define EMPTY '_' struct Clues { Pieces row[MAX_SIZE]; Pieces col[MAX_SIZE]; }; void read_line(FILE* f, char *line, bool &more) { if (fgets(line, 299, f) == 0) { more = false; return; } if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0'; more = true; } bool read_clues(char *fn, Clues &clues) { FILE* f = fopen(fn, "rt"); char line[300]; bool more; read_line(f, line, more); while (more && strncmp(line, "width ", 6) != 0) read_line(f, line, more); if (!more) { fclose(f); return false; } m = atoi(line+6); read_line(f, line, more); while (more && strncmp(line, "height ", 7) != 0) read_line(f, line, more); if (!more) { fclose(f); return false; } n = atoi(line+7); read_line(f, line, more); while (more && strcmp(line, "rows") != 0) read_line(f, line, more); if (!more) { fclose(f); return false; } for (int i = 0; i < n; i++) { read_line(f, line, more); if (!more) { fclose(f); return false; } clues.row[i].nr = 0; int sum = 0; if (strcmp(line, "0") != 0) { char *s = line; while (*s != '\0') { int v = 0; for (; isdigit(*s); s++) v = 10 * v + *s - '0'; for(; *s == ',' || *s == ' '; s++) ; clues.row[i].add(v); } } clues.row[i].init(m); } read_line(f, line, more); while (more && strcmp(line, "columns") != 0) read_line(f, line, more); if (!more) { fclose(f); return false; } for (int i = 0; i < m; i++) { read_line(f, line, more); if (!more) { fclose(f); return false; } clues.col[i].nr = 0; int k = 0; if (strcmp(line, "0") != 0) { char *s = line; while (*s != '\0') { int v = 0; for (; isdigit(*s); s++) v = 10 * v + *s - '0'; for(; *s == ',' || *s == ' '; s++) ; clues.col[i].add(v); } } clues.col[i].init(n); } nm = n * m; fclose(f); return true; } class PiecesCombinationsIterator { public: PiecesCombinationsIterator(const Pieces& pieces, int size) : _pieces(pieces), _size(size) { for (int i = 0; i < _pieces.nr; i++) positions[i] = _pieces.pieces[i].min; _more = true; } bool more() { return _more; } void next() { for (int i = 0; i < _pieces.nr; i++) { const Piece& p = _pieces.pieces[i]; int end = p.max; if (i+1 < _pieces.nr) { int j = positions[i+1] - p.size; if (j < end) end = j; } for (int j = positions[i]+1; j < end; j++) if (p.pos[j]) { positions[i] = j; return; } positions[i] = p.min; } _more = false; } int positions[MAX_SIZE]; private: const Pieces& _pieces; int _size; bool _more; }; Clues clues; int main(int argc, char *argv[]) { if (argc != 2) { printf("%s \n", argv[0]); return 0; } if (!read_clues(argv[1], clues)) { printf("\n\nread error\n"); return 0; } for (int row_nr = 0; row_nr < n; row_nr++) { const Pieces& pieces = clues.row[row_nr]; for (PiecesCombinationsIterator it(pieces, m); it.more(); it.next()) { int values[MAX_SIZE]; int j = 0; for (int i = 0; i < pieces.nr; i++) { int begin = it.positions[i]; int end = begin + pieces.pieces[i].size; for (; j < begin; j++) values[j] = 0; for (; j < end; j++) values[j] = 1; } for (; j < m; j++) values[j] = 0; for (int i = 0; i < n; i++) printf("%c", (i == row_nr) ? '1' : '0'); for (int i = 0; i < m; i++) printf("0"); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) printf("%c", (i == row_nr && values[j] == 1) ? '1' : '0'); printf(" row %2d: ", row_nr+1); for (int i = 0; i < m; i++) printf("%d", values[i]); for (int j = 0; j < pieces.nr; j++) { const Piece& p = pieces.pieces[j]; printf(" %d", p.size); } printf("\n"); } } for (int col_nr = 0; col_nr < m; col_nr++) { const Pieces& pieces = clues.col[col_nr]; for (PiecesCombinationsIterator it(pieces, n); it.more(); it.next()) { int values[MAX_SIZE]; int j = 0; for (int i = 0; i < pieces.nr; i++) { int begin = it.positions[i]; int end = begin + pieces.pieces[i].size; for (; j < begin; j++) values[j] = 0; for (; j < end; j++) values[j] = 1; } for (; j < n; j++) values[j] = 0; for (int i = 0; i < n; i++) printf("0"); for (int i = 0; i < m; i++) printf("%c", (i == col_nr) ? '1' : '0'); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) printf("%c", (j == col_nr && values[i] == 0) ? '1' : '0'); printf(" col %2d: ", col_nr+1); for (int i = 0; i < n; i++) printf("%d", values[i]); for (int j = 0; j < pieces.nr; j++) { const Piece& p = pieces.pieces[j]; printf(" %d", p.size); } printf("\n"); } } return 0; }