[ 簡単な説明 ]
「イラストロジック」と呼ばれるパズルを解くプログラム例です。 縦・横の各行に対して、連続して塗りつぶす桝目の数とその並びだけを情報として与え、イラストを完成させます。 本プログラムでは、データはテキストファイルで入力します。グラフィックスはPC98専用ルーチンです。 なお、本プログラムは、C++ で作成されています。 |
1 2 |
1 1 |
1 1 |
4 |
1 |
|
1 1 | ■ | ■ | |||
1 1 | ■ | ■ | |||
1 1 | ■ | ■ | |||
5 | ■ | ■ | ■ | ■ | ■ |
1 | ■ |
/* illust.cpp */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <conio.h> #include <graphics.h> #define SETCHECK /* set1(), set0() on */ typedef char * pchar; typedef int * pint; /* data print out flag routine or process */ /*#define TEST /* test mode */ /*#define DEBUG /* main */ /*#define DEBUG1 /* runcheck process */ /*#define DEBUG2 /* runcheck */ /*#define DEBUG4 /* shrinkmask */ /*#define DEBUG6 /* allcheck (detail) */ /*#define DEBUG11 /* run10 */ /*#define DEBUG13 /* allcheck */ const int buf_size = 256; void wait(char *message); void error(void); void usage(char *s); void monx(char *mask); void mony(char *mask); void getdata(int **run, int *n, FILE *fin); void memover(void); void matprint(int *mat, int n, char *title); int checkmask(char *mask); int calrest(int *run, int m, int n); void memset_allcheck(int m); void memfree_allcheck(void); void allcheck(int *run, char *mask, int m, int n); void rest0(int *run, char *mask, int n); int inccheck(int *sp, int n); int incsp1(int *sp, int totalsp, int n, int i); char *newchar(int n); int *newint(int n); int **newpint(int n); char **newpchar(int n); void runcheck(int *run, char *mask, int m, int n); void run10(int *run, char *mask, int m, int n); void shrinkmask(int *run, char *mask, int m, int n, int *newrun, char *newmask, int *set, int *mm, int *nn); void remake(char *mask, char *mask1, int *set, int m); int leftfind(char *mask, char *pattern); #ifdef SETCHECK void set1(char *mask); void set0(char *mask); #endif char title[40]; char *buf; int *tmp; int *xx, *yy, xms, yms; int errflag = 1, errset = 0; int main(int argc, char *argv[]) { #ifdef TEST int runf[20] = {2, 8, 6, 12, 10, 15, 2}; char maskf[100] = "....011111111011111100111111111111..11111111..0111111111111111011"; int mf = 65, nf = 7; memset_allcheck(mf); allcheck(runf, maskf, mf, nf); printf("maskf=%s\n", maskf); exit(0); #endif int i, j, k; int cflag = 0, dflag = 0, gflag = 1, lflag = 0, mflag = 0, pflag = 0; int rflag = 1, tflag = 0, wflag = 0; if(argc < 2) usage(argv[0]); k = 1; while(*(argv[k]) == '-') { char *p = argv[k] + 1; while(*p) { if(*p == 'p') pflag = 1; else if(*p == 'c') cflag = 1; else if(*p == 't') tflag = 1; else if(*p == 'l') lflag = 1; else if(*p == 'g') gflag = 0; else if(*p == 'm') mflag = 1; else if(*p == 'w') wflag = 1; else if(*p == 'r') rflag = 0; else if(*p == 'd') dflag = 1; else { fprintf(stderr, "Illegal option !!\n"); usage(argv[0]); } p++; } k++; } buf = newchar(buf_size); FILE *fin = fopen(argv[k], "rt"); if(fin == NULL) { strcpy(buf, argv[k]); strcat(buf, ".ill"); fin = fopen(buf, "rt"); if(fin == NULL) { fprintf(stderr, "Error : file(%s) can't open.\n", argv[k]); exit(-1); } } FILE *fdata; if(dflag) { char *p = strchr(argv[k], '.'); if(p != argv[k]) *p = '\0'; strcpy(buf, argv[k]); strcat(buf, ".dat"); fdata = fopen(buf, "r"); if(fdata != NULL) { fprintf(stderr, "Error : file(%s) is already exist.\n", buf); exit(-1); } fdata = fopen(buf, "wt"); } fgets(title, 40, fin); int M = atoi(title); /* 横升目数 */ if(M == 0) { title[strlen(title) - 1] = '\0'; fgets(buf, buf_size, fin); M = atoi(buf); } else title[0] = '\0'; fgets(buf, buf_size, fin); int N = atoi(buf); /* 縦升目数 */ if(cflag) { i = M; M = N; N = i; } int m = (M >= N)? M: N; int *xn = newint(M); int *yn = newint(N); int **xrun = newpint(M); int **yrun = newpint(N); tmp = newint(m / 2 + 1); if(cflag) { for(i = 0; i < N; i++) getdata(yrun + i, yn + i, fin); for(i = 0; i < M; i++) getdata(xrun + i, xn + i, fin); } else { for(i = 0; i < M; i++) getdata(xrun + i, xn + i, fin); for(i = 0; i < N; i++) getdata(yrun + i, yn + i, fin); } delete tmp; fclose(fin); delete buf; if(pflag) { for(i = 0; i < M; i++) { printf("< x run %3d >", i); matprint(xrun[i], xn[i], ""); } for(i = 0; i < N; i++) { printf("< y run %3d >", i); matprint(yrun[i], yn[i], ""); } putchar('\n'); } /* チェックサム */ int sum = 0; for(i = 0; i < M; i++) for(j = xn[i] - 1; j >= 0;) sum += xrun[i][j--]; for(i = 0; i < N; i++) for(j = yn[i] - 1; j >= 0;) sum -= yrun[i][j--]; if(sum) { fprintf(stderr, "チェックサムエラー sum=%d\n", sum); exit(-3); } if(lflag) { int *pw, **ps = xrun, **pe = xrun + M - 1; while(ps < pe) { pw = *ps; *ps++ = *pe; *pe-- = pw; } i = 0; j = M - 1; while(i < j) { k = xn[i]; xn[i++] = xn[j]; xn[j--] = k; } for(i = 0; i < N; i++) { if(yn[i] < 2) continue; j = 0; k = yn[i] - 1; while(j < k) { int w = yrun[i][j]; yrun[i][j++] = yrun[i][k]; yrun[i][k--] = w; } } } if(tflag) { int *pw, **ps = yrun, **pe = yrun + N - 1; while(ps < pe) { pw = *ps; *ps++ = *pe; *pe-- = pw; } i = 0; j = N - 1; while(i < j) { k = yn[i]; yn[i++] = yn[j]; yn[j--] = k; } for(i = 0; i < M; i++) { if(xn[i] < 2) continue; j = 0; k = xn[i] - 1; while(j < k) { int w = xrun[i][j]; xrun[i][j++] = xrun[i][k]; xrun[i][k--] = w; } } } char **mat_mask = newpchar(M); char *mask = newchar(m); int *xchange = newint(N); int *ychange = newint(M); for(i = M - 1; i >= 0;) { char *p = mat_mask[i--] = newchar(N); j = N; while(j--) *p++ = '.'; *p = '\0'; } #ifdef DEBUG printf("No.: xn : xrun\n"); for(j = 0; j < M; j++) { printf("%2d : %2d", j, xn[j]); matprint(xrun[j], xn[j], ""); } printf("No.: yn : yrun\n"); for(j = 0; j < N; j++) { printf("%2d : %2d", j, yn[j]); matprint(yrun[j], yn[j], ""); } #endif int x, y, xm, ym, xmm, ymm, step; int gdriver = PC98, gmode = PC98C16; initgraph(&gdriver, &gmode, ""); int ecode = graphresult(); if(ecode != grOk) { fprintf(stderr , "Error : Graphics cannot initialize\n"); fprintf(stderr , " error message [ %s ]\n", grapherrormsg(ecode)); exit(1); } if(gflag) { step = 627 / (M + 1); if(step > 371 / (N + 1)) step = 371 / (N + 1); int step5 = step * 5; xx = newint(M); yy = newint(N); for(i = 0, x = step / 2; i < M; i++, x += step) xx[i] = x; for(i = 0, y = step / 2; i < N; i++, y += step) yy[i] = y; xm = step * M; ym = step * N; setcolor(WHITE); setlinestyle(SOLID_LINE, 0, NORM_WIDTH); for(x = xm; x >= 0; x -= step) line(x, 0, x, ym); for(y = ym; y >= 0; y -= step) line(0, y, xm, y); for(x = 1; x <= xm + 1; x += step5) line(x, 0, x, ym + 1); for(y = 1; y <= ym + 1; y += step5) line(0, y, xm + 1, y); xm += 6; ym += 6; if(mflag) { if((xmm = xm + step + 6) > 639) xmm = 639; if((ymm = ym + step + 6) > 383) xmm = 383; for(x = step * M; x >= 0; x -= step) line(x, ymm - step, x, ymm); for(x = step * M + 1; x >= 1; x -= step5) line(x, ymm - step, x, ymm); line(0, ymm - step, step * M, ymm - step); line(0, ymm, step * M, ymm); for(y = step * N; y >= 0; y -= step) line(xmm - step, y, xmm, y); for(y = step * N + 1; y >= 1; y -= step5) line(xmm - step, y, xmm, y); line(xmm - step, 0, xmm - step, step * N); line(xmm, 0, xmm, step * N); xms = xmm - step / 2; yms = ymm - step / 2; setfillstyle(SOLID_FILL, WHITE); } } memset_allcheck(m); char *monmask; if(gflag && wflag) monmask = newchar(m); char *pcc, **smask; int icc, ncc = 0; long count = 0; for(i = M - 1; i >= 0;) ychange[i--] = 1; for(int firstflag = 1; ; firstflag = 0) { int contflag = 0; for(j = 0; j < M; j++) { if(ychange[j] == 0) continue; count++; if(gflag) { x = xx[j]; setcolor(WHITE); circle(x, ym, 4); } strcpy(mask, mat_mask[j]); #ifdef DEBUG printf("\n<xcheck in of %2d> ", j); matprint(xrun[j], xn[j], "run"); #endif if(mflag) { gotoxy(1, 25); clreol(); for(i = 0; i < xn[j];) cprintf("%d ", xrun[j][i++]); if(gflag == 0) { gotoxy(1, 24); clreol(); cprintf("%s", mask); } else if(wflag) strcpy(monmask, mask); else monx(mask); } if(pflag) printf("x%3d in : %s\n", j, mask); allcheck(xrun[j], mask, N, xn[j]); if(pflag) printf(" out : %s\n", mask); if(gflag && rflag) { if(wflag) { if(mflag) monx(monmask); wait("Do it yourself!"); } for(i = 0; i < N; i++) { if(mat_mask[j][i] != (k = mask[i])) { mat_mask[j][i] = xchange[i] = contflag = k; if(k == '1') setfillstyle(SOLID_FILL, YELLOW); else setfillstyle(CLOSE_DOT_FILL, YELLOW); floodfill(x, yy[i], WHITE); } } if(mflag) monx(mask); } else { for(i = 0; i < N; i++) if(mat_mask[j][i] != mask[i]) mat_mask[j][i] = xchange[i] = contflag = mask[i]; } if(gflag) { setcolor(BLACK); circle(x, ym, 4); } if(wflag) wait("Hit any key!!"); } if(firstflag) for(i = N - 1; i >= 0;) xchange[i--] = 1; for(i = M - 1; i >= 0;) ychange[i--] = 0; for(j = 0; j < N; j++) { if(xchange[j] == 0) continue; count++; if(gflag) { y = yy[j]; setcolor(WHITE); circle(xm, y, 4); } for(i = 0; i < M; i++) mask[i] = mat_mask[i][j]; mask[M] = '\0'; #ifdef DEBUG printf("\n<ycheck in of %2d> ", j); matprint(yrun[j], yn[j], "run"); #endif if(mflag) { gotoxy(1, 25); clreol(); for(i = 0; i < yn[j];) cprintf("%d ", yrun[j][i++]); if(gflag == 0) { gotoxy(1, 24); clreol(); cprintf("%s", mask); } else if(wflag) strcpy(monmask, mask); else mony(mask); } if(pflag) printf("y%3d in : %s\n", j, mask); allcheck(yrun[j], mask, M, yn[j]); if(pflag) printf(" out : %s\n", mask); if(gflag && rflag) { if(wflag) { if(mflag) mony(monmask); wait("Do it yourself!"); } for(i = 0; i < M; i++) { if(mat_mask[i][j] != (k = mask[i])) { mat_mask[i][j] = ychange[i] = contflag = k; if(k == '1') setfillstyle(SOLID_FILL, YELLOW); else setfillstyle(CLOSE_DOT_FILL, YELLOW); floodfill(xx[i], y, WHITE); } } if(mflag) mony(mask); } else { for(i = 0; i < M; i++) if(mat_mask[i][j] != mask[i]) mat_mask[i][j] = ychange[i] = contflag = mask[i]; } if(gflag) { setcolor(BLACK); circle(xm, y, 4); } if(wflag) wait("Hit any key!!"); } errloop: if(errflag && contflag == 0) { for(i = 0; i < M; i++) if(strchr(mat_mask[i], '.')) break; if(i == M) break; icc = i; errflag = errset = 0; smask = newpchar(M); for(i = 0; i < M; i++) { smask[i] = newchar(N); strcpy(smask[i], mat_mask[i]); } } if(errflag == 0) { if(ncc == 0) { ncc = 1; pcc = strchr(mat_mask[icc], '.'); *pcc = ychange[icc] = '1'; setfillstyle(SOLID_FILL, YELLOW); floodfill(xx[icc], yy[pcc - mat_mask[icc]], WHITE); } else { if(errset == 1) { for(i = 0; i < M; i++) strcpy(mat_mask[i], smask[i]); *pcc = ychange[icc] = '0'; errset = 0; setfillstyle(CLOSE_DOT_FILL, YELLOW); floodfill(xx[icc], yy[pcc - mat_mask[icc]], WHITE); } else if(contflag == 0) { ncc = 0; errflag = 1; goto errloop; } } } for(i = N - 1; i >= 0;) xchange[i--] = 0; } memfree_allcheck(); if(rflag == 0) { for(i = 0; i < M; i++) { char *p = mat_mask[i]; j = 0; while(*p) { if(*p++ == '1') setfillstyle(SOLID_FILL, YELLOW); else setfillstyle(CLOSE_DOT_FILL, YELLOW); floodfill(xx[i], yy[j++], WHITE); } } } if(mflag && gflag) { setviewport(0, ymm - step, step * M + 1, ymm, 1); clearviewport(); setviewport(xmm - step, 0, xmm, step * N + 1, 1); clearviewport(); } gotoxy(1, 24); clreol(); gotoxy(1, 25); clreol(); fprintf(stderr, "Complete ! Cycle = %ld", count); if(title[0] != '\0') fprintf(stderr, " Title:%s", title); if(dflag) { fprintf(fdata, "%s\n%d\n%d\n", title, M, N); for(i = 0; i < M; i++) fprintf(fdata, "%s\n", mat_mask[i]); fclose(fdata); fprintf(stderr, "\nData output complete."); } return 0; } void wait(char *message) { int x = 80 - strlen(message); gotoxy(x, 25); clreol(); fprintf(stderr, "%s", message); while(!kbhit()) ; getch(); gotoxy(x, 25); clreol(); } void error(void) { if(errflag) { fprintf(stderr, "Error : Illegal data. Cannot make up puzzle.\n"); exit(-1); } errset = 1; } void usage(char *s) { fprintf(stderr, "Usage : %s [ -pctlgmwrd ] < .ill file name >\n", s); fprintf(stderr, " -p : Print data flag\n"); fprintf(stderr, " -c : Change axis flag\n"); fprintf(stderr, " -t : change Top to bottom flag\n"); fprintf(stderr, " -l : change Left to right flag\n"); fprintf(stderr, " -g : Graphics off flag\n"); fprintf(stderr, " -m : Monitor flag\n"); fprintf(stderr, " -w : Wait mode(Press any key when continue)\n"); fprintf(stderr, " -r : Result only\n"); fprintf(stderr, " -d : Data set flag\n"); exit(0); } int style[4] = {SOLID_FILL, SOLID_FILL, CLOSE_DOT_FILL, SOLID_FILL}; int color[4] = {BLACK, YELLOW, YELLOW, YELLOW}; void monx(char *mask) { char *p = mask; int *q = yy; while(*p) { int c = *p++ - '.'; setfillstyle(style[c], color[c]); floodfill(xms, *q++, WHITE); } setfillstyle(SOLID_FILL, WHITE); } void mony(char *mask) { char *p = mask; int *q = xx; while(*p) { int c = *p++ - '.'; setfillstyle(style[c], color[c]); floodfill(*q++, yms, WHITE); } setfillstyle(SOLID_FILL, WHITE); } void getdata(int **run, int *n, FILE *fin) { fgets(buf, buf_size, fin); char *p = buf; *n = 0; int j = 0; for(;;) { if((tmp[j++] = atoi(p++)) == 0) break; (*n)++; do { if(*p == '\n' || *p == '\0') { if((*run = newint(*n)) == NULL) return; for(j = 0; j < *n; j++) *(*run + j) = tmp[j]; return; } } while(*p++ != ' '); while(*p == ' ') p++; } } void memover(void) { fprintf(stderr, "Error : out of memory.\n"); exit(-2); } void matprint(int *mat, int n, char *header) { printf("%s : ", header); int *p = mat; while(n--) printf("%2d ", *p++); putchar('\n'); } int checkmask(char *mask) { char *p = mask; while(*p) if(*p++ == '.') return 0; return 1; } #ifdef SETCHECK void set1(char *mask) { if(*mask == '0') error(); *mask = '1'; } void set0(char *mask) { if(*mask == '1') error(); *mask = '0'; } #endif int calrest(int *run, int m, int n) { int rest = m - n + 1; while(n--) rest -= run[n]; return (rest >= 0)? rest: -1; } int *runs, *sets, *sp, *srun, *codein, *fix; char *masks, *masks1, *masks2, *xelement, *code, *zero; void memset_allcheck(int m) { sets = newint(m); codein = newint(m); fix = newint(m); masks = newchar(m); masks1 = newchar(m); masks2 = newchar(m); xelement = newchar(m); code = newchar(m); zero = newchar(m); m /= 2; runs = newint(m++); sp = newint(m); srun = newint(m); } void memfree_allcheck(void) { delete runs; delete sets; delete codein; delete fix; delete sp; delete srun; delete masks; delete masks1; delete masks2; delete xelement; delete code; delete zero; } void allcheck(int *run1, char *mask1, int mm, int nn) { if(errflag == 0 && errset == 1) return; int i, j, k, m, n; #ifdef DEBUG13 long count = 0; printf("< allcheck in > m=%d, n=%d\n", mm, nn); printf("mask : %s\n", mask1); matprint(run1, nn, "run"); #endif if(nn == 0) { char *p = mask1; while(*p) *p++ = '0'; #ifdef DEBUG13 printf("< allcheck out >\nmask : %s\n", mask1); #endif return; } if(checkmask(mask1)) { #ifdef DEBUG13 printf("< allcheck out >\nmask : %s\n", mask1); #endif return; } do { strcpy(masks1, mask1); runcheck(run1, mask1, mm, nn); } while(strcmp(masks1, mask1)); for(;;) { shrinkmask(run1, mask1, mm, nn, runs, masks, sets, &m, &n); strcpy(masks1, masks); do { strcpy(masks2, masks); runcheck(runs, masks, m, n); } while(strcmp(masks2, masks)); if(strcmp(masks1, masks) == 0) break; remake(mask1, masks, sets, m); } /* runcheck(run1, mask1, mm, nn); for(;;) { shrinkmask(run1, mask1, mm, nn, runs, masks, sets, &m, &n); strcpy(masks1, masks); runcheck(runs, masks, m, n); if(strcmp(masks1, masks) == 0) break; remake(mask1, masks, sets, m); } */ if(checkmask(masks)) { remake(mask1, masks, sets, m); #ifdef DEBUG13 printf("< allcheck out >\nmask : %s\n", mask1); #endif return; } int sp0 = 0; for(i = 0; i < runs[0]; i++) if(masks[i] == '0') break; if(i < runs[0]) { sp0 += (i + 1); while(masks[++i] == '0') sp0++; } int rest = calrest(runs, m, n); if(sp0 > rest) { remake(mask1, masks, sets, m); #ifdef DEBUG13 printf("< allcheck out >\nmask : %s\n", mask1); #endif return; } int m1 = m - 1, n1 = n - 1; xelement[m] = code[0] = code[m] = zero[m] = '\0'; srun[0] = 0; for(i = 1; i <= n; i++) srun[i] = srun[i - 1] + runs[i - 1]; int nfix = 0, ncode = 0; for(i = 0; i < m; i++) { zero[i] = '0'; if(masks[i] != '.') fix[nfix++] = i; else codein[ncode++] = i; } int startfix = 0; int lastcode = codein[ncode - 1]; #ifdef DEBUG6 printf("mask : %s\n\nnfix = %d, ncode = %d\n", masks, nfix, ncode); matprint(fix, nfix, "fix"); matprint(codein, ncode, "codein"); #endif sp[0] = sp0; sp[n] = rest - sp0; int totalsp = rest + n - 1; for(i = 1; i < n; i++) sp[i] = 1; #ifdef DEBUG6 matprint(sp, n + 1, "sp"); printf("totalsp = %d\n"); #endif int flag = 0; for(;;) { #ifdef DEBUG13 count++; #endif strcpy(xelement, zero); char *p = xelement; for(i = 0; i < n;) { p += sp[i]; k = runs[i++]; while(k--) *p++ = '1'; } int unmatch = m; for(i = startfix; i < nfix;) { j = fix[i++]; if(masks[j] != xelement[j]) { unmatch = j; break; } } #ifdef DEBUG6 matprint(sp, n + 1, "sp"); printf("mask : %s\n", masks); printf("xelement : %s unmatch=%d\n", xelement, unmatch); #endif if(unmatch == m) { if(flag == 0) { flag = 1; strcpy(code, xelement); } else { int *p = codein, *q = codein; while(ncode--) { j = *q++; if(code[j] != xelement[j]) code[j] = '.'; else *p++ = j; } if((ncode = p - codein) == 0) break; lastcode = codein[ncode - 1]; } #ifdef DEBUG6 printf("code : %s\n", code); #endif } if(sp[n] == 0) { i = n1; j = m1; do { j -= (runs[i] + 1); if(i <= 0) break; } while(sp[i--] == 1); do { if(lastcode <= j) break; if(code[lastcode] != '.') { #ifdef SETCHECK if(code[lastcode] == '1') set1(masks + lastcode); else set0(masks + lastcode); #else masks[lastcode] = code[lastcode]; #endif fix[nfix++] = lastcode; } ncode--; lastcode = codein[ncode - 1]; } while(ncode > 0); if(ncode == 0) break; } #ifdef DEBUG6 printf("* sp[] increment process * "); #endif int check; if(unmatch == m) { #ifdef DEBUG6 printf("(matched case)\n"); #endif if((i = inccheck(sp, n)) < 0) break; check = lastcode; } else { #ifdef DEBUG6 printf("(unmatched case)\n"); #endif for(i = 0, j = 0; i < n; i++) if((j += (sp[i] + runs[i])) > unmatch) break; if(xelement[unmatch] == '0') i--; check = unmatch; } #ifdef DEBUG6 printf("change = %d\n", i); #endif k = srun[i] + sp[i]; for(j = i - 1; j >= 0;) k += sp[j--]; while(k > check) { #ifdef DEBUG6 printf("change point=%d, lastcode=%d\n", k, lastcode); #endif if(--i < 0) goto ret; k -= (sp[i + 1] + runs[i]); } if(incsp1(sp, totalsp, n, i) == 0) break; #ifdef DEBUG6 matprint(sp, n + 1, "new sp"); #endif if(sp0 != sp[0]) { sp0 = sp[0]; do { if((k = fix[startfix]) >= sp0) break; if(masks[k] == '1') goto ret; } while(++startfix < nfix); if(k == sp0 && masks[k] == '0') { do { sp0++; } while(masks[sp0] == '0'); if((sp[n] = rest - sp0) < 0) break; sp[0] = sp0; for(int i = 1; i < n; i++) sp[i] = 1; } } #ifdef DEBUG6 putchar('\n'); #endif } ret: #ifdef DEBUG13 printf("* allcheck last process flag=%d\n", flag); printf("mask : %s\ncode : %s\n", masks, code); #endif /* if(flag) strcpy(masks, code);*/ if(flag) { #ifdef SETCHECK i = 0; do { if (code[i] == '1') set1(masks + i); else if(code[i] == '0') set0(masks + i); } while(++i < m); #else strcpy(masks, code); #endif } remake(mask1, masks, sets, m); #ifdef DEBUG13 printf("< allcheck out >\nmask : %s\n", mask1); printf("number of loop = %ld\n", count); #endif return; } void rest0(int *run, char *mask, int n) { char *p = mask; int *q = run; #ifdef SETCHECK if(n == 0) while(*p) set0(p++); #else if(n == 0) while(*p) *p++ = '0'; #endif else { for(int i = 0; i < n; i++) { #ifdef SETCHECK int j = *q++; while(j--) set1(p++); if(i == n - 1) break; set0(p++); #else int j = *q++; while(j--) *p++ = '1'; if(i == n - 1) break; *p++ = '0'; #endif } } } int inccheck(int *sp, int n) { if(sp[n] > 0) return n - 1; if(n == 1) return -1; while(--n) if(sp[n] != 1) return n - 1; return -1; } int incsp1(int *sp, int totalsp, int n, int i) { sp[i]++; for(int j = i + 1; j < n;) sp[j++] = 1; for(j = 0; j < n;) totalsp -= sp[j++]; if((sp[n] = totalsp) >= 0) return 1; if(--i < 0) return 0; for(;;) { sp[i]++; totalsp += (sp[i + 1] - 2); sp[i + 1] = 1; if((sp[n] = totalsp) >= 0) return 1; if(--i < 0) return 0; } } char *newchar(int n) { char *p = new char[n + 1]; if(p == NULL) memover(); *(p + n) = '\0'; return p; } int *newint(int n) { if(n == 0) return NULL; int *p = new int[n]; if(p == NULL) memover(); return p; } int **newpint(int n) { int **p = new pint[n]; if(p == NULL) memover(); return p; } char **newpchar(int n) { char **p = new pchar[n]; if(p == NULL) memover(); return p; } #ifdef DEBUG2 int runcycle = 0; #define po_() printf("< runcheck out : cycle %d >\nmask : %s\n", runcycle--, mask); #else #define po_() #endif #ifdef DEBUG1 #define ps_(a) printf("runcheck process - %d start\nmask : %s\n", a, mask); #define pe_(a) printf("runcheck process - %d end\nmask : %s\n", a, mask); #else #define ps_(a) #define pe_(a) #endif void runcheck(int *run, char *mask, int m, int n) { if(errflag == 0 && errset == 1) return; #ifdef DEBUG2 printf("<runcheck in : cycle %d > m=%d n=%d\n", ++runcycle, m, n); printf("mask : %s\n", mask); matprint(run, n, "run"); #endif int m1 = m - 1, n1 = n - 1; if(n < 0 || m <= 0 || checkmask(mask)) { po_(); return; } int run0 = run[0]; if(n == 0 || run0 == 0) { ps_(1); char *p = mask; while(m--) *p++ = '0'; pe_(1); po_(); return; } int rest = calrest(run, m, n); if(rest == 0) { ps_(2); rest0(run, mask, n); pe_(2); po_(); return; } for(int i = 0; i < n;) if(run[i++] > rest) break; if(i < n) { ps_(3); i = 0; int j, nrun = 0; for(;;) { if((j = run[nrun] - rest) > 0) { int k = rest; while(k--) i++; #ifdef SETCHECK while(j--) set1(mask + i++); #else while(j--) mask[i++] = '1'; #endif } else { int k = run[nrun]; while(k--) i++; } if(nrun++ == n1) break; i++; } pe_(3); } if(run0 != 1 && mask[run0] == '0' && mask[run0 - 1] == '1') { ps_(4); #ifdef SETCHECK for(i = run0 - 2; i >= 0;) set1(mask + i--); #else for(i = run0 - 2; i >= 0;) mask[i--] = '1'; #endif pe_(4); } int runn1 = run[n1]; if(runn1 != 1 && mask[m1 - runn1] == '0' && mask[m - runn1] == '1') { ps_(5); #ifdef SETCHECK for(i = runn1 - 2; i >= 0;) set1(mask + m1 - i--); #else for(i = runn1 - 2; i >= 0;) mask[m1 - i--] = '1'; #endif pe_(5); } if(mask[run0] == '1') { ps_(6); #ifdef SETCHECK set0(mask); #else mask[0] = '0'; #endif pe_(6); } if(mask[m1 - runn1] == '1') { ps_(7); #ifdef SETCHECK set0(mask + m1); #else mask[m1] = '0'; #endif pe_(7); } if(run0 > 1) { ps_(8); for(i = run0 - 1; i > 0; i--) { if(mask[i] == '0') { #ifdef SETCHECK for(i--; i >= 0;) set0(mask + i--); #else for(i--; i >= 0;) mask[i--] = '0'; #endif break; } } pe_(8); ps_(9); for(i = run0 - 1; i > 0; i--) { if(mask[i] == '1') { #ifdef SETCHECK for(i++; i < run0;) set1(mask + i++); #else for(i++; i < run0;) mask[i++] = '1'; #endif break; } } pe_(9); } if(runn1 > 1) { ps_(10); for(i = m - runn1; i < m1; i++) { if(mask[i] == '0') { #ifdef SETCHECK for(i++; i < m;) set0(mask + i++); #else for(i++; i < m;) mask[i++] = '0'; #endif break; } } pe_(10); ps_(11); for(i = m - runn1; i < m1; i++) { if(mask[i] == '1') { #ifdef SETCHECK for(i--; i >= m - runn1;) set1(mask + i--); #else for(i--; i >= m - runn1;) mask[i--] = '1'; #endif break; } } pe_(11); } if(mask[0] == '0') { ps_(12); i = 1; m--; while(mask[i] == '0') { i++; m--; } runcheck(run, mask + i, m, n); pe_(12); po_(); return; } if(mask[m1] == '0') { ps_(13); m--; while(mask[m - 1] == '0') m--; mask[m] = '\0'; runcheck(run, mask, m, n); mask[m] = '0'; pe_(13); po_(); return; } if(mask[0] == '1') { ps_(14); #ifdef SETCHECK for(i = 1; i < run0;) set1(mask + i++); set0(mask + i); #else for(i = 1; i < run0;) mask[i++] = '1'; mask[i] = '0'; #endif i++; runcheck(run + 1, mask + i, m - i, n1); pe_(14); po_(); return; } if(mask[m1] == '1') { ps_(15); #ifdef SETCHECK for(i = 1; i < runn1;) set1(mask + m1 - i++); int k = m1 - i++; set0(mask + k); #else for(i = 1; i < runn1;) mask[m1 - i++] = '1'; k = m1 - i++; mask[k] = '0'; #endif mask[k] = '\0'; runcheck(run, mask, m - i, n1); mask[k] = '0'; pe_(15); po_(); return; } if(mask[1] == '1') { ps_(16); #ifdef SETCHECK if(mask[run0 + 1] == '1') { set1(mask); set0(mask + run0); } for(i = 2; i < run0;) set1(mask + i++); #else if(mask[run0 + 1] == '1') { mask[0] = '1'; mask[run0] = '0'; } for(i = 2; i < run0;) mask[i++] = '1'; #endif i++; runcheck(run + 1, mask + i, m - i, n1); pe_(16); po_(); return; } if(mask[m - 2] == '1') { ps_(17); if(mask[m1 - runn1 - 1] == '1') { #ifdef SETCHECK set1(mask + m1); set0(mask + m1 - runn1); #else mask[m1] = '1'; mask[m1 - runn1] = '0'; #endif } #ifdef SETCHECK for(i = 2; i < runn1;) set1(mask + m1 - i++); #else for(i = 2; i < runn1;) mask[m1 - i++] = '1'; #endif i++; m -= i; int j = mask[m]; mask[m] = '\0'; runcheck(run, mask, m, n1); mask[m] = j; pe_(17); po_(); return; } ps_(18); char *mask1 = newchar(m + 1); for(int nrun = 2; nrun < n; nrun++) { int maxrun = run0, j = run0 + 1, k; for(i = 1; i < nrun; i++) { if(maxrun < run[i]) maxrun = run[i]; j += (run[i] + 1); } char *pattern = newchar(maxrun + 3), *p = pattern; *p++ = '.'; for(i = maxrun; i--;) *p++ = '1'; *p++ = '.'; *p = '\0'; strcpy(mask1, mask); mask1[j] = '\0'; while((k = leftfind(mask1, pattern)) >= 0) { #ifdef SETCHECK set0(mask + k); set0(mask + k + maxrun + 1); #else mask[k] = '0'; mask[k + maxrun + 1] = '0'; #endif mask1[k] = mask1[k + maxrun + 1] = '0'; } delete pattern; } pe_(18); ps_(19); for(nrun = 2; nrun < n; nrun++) { int maxrun = runn1, j = runn1 + 1, k; for(i = 1; i < nrun; i++) { if(maxrun < run[n1 - i]) maxrun = run[n1 - i]; j += (run[n1 - i] + 1); } char *pattern = newchar(maxrun + 3), *p = pattern; *p++ = '.'; for(i = maxrun; i--;) *p++ = '1'; *p++ = '.'; *p = '\0'; for(i = 0; i < j; i++) mask1[i] = mask[m1 - i]; mask1[j] = '\0'; while((k = leftfind(mask1, pattern)) >= 0) { #ifdef SETCHECK set0(mask + m1 - k); set0(mask + m1 - k - maxrun - 1); #else mask[m1 - k] = '0'; mask[m1 - k - maxrun - 1] = '0'; #endif mask1[k] = mask1[k + maxrun + 1] = '0'; } delete pattern; } delete mask1; pe_(19); if(strchr(mask, '1') || strchr(mask, '0')) { int maxrun = run0, minrun = run0; for(i = 1; i < n; i++) { if(run[i] > maxrun) maxrun = run[i]; else if(run[i] < minrun) minrun = run[i]; } if(strchr(mask, '1')) { ps_(20); int j = 0; for(i = 0; i < m; i++) { if(mask[i] != '1') j = 0; else if(++j == maxrun) { i++; #ifdef SETCHECK if(i < m) set0(mask + i); if((j = i - maxrun - 1) >= 0) set0(mask + j); #else if(i < m) mask[i] = '0'; if((j = i - maxrun - 1) >= 0) mask[j] = '0'; #endif j = 0; } } pe_(20); } if(strchr(mask, '0')) { ps_(21); if(minrun > 1) { char *pattern = newchar(minrun + 3), *p; for(i = 1; i < minrun; i++) { p = pattern; *p++ = '0'; for(int j = i; j--;) *p++ = '.'; *p++ = '0'; *p = '\0'; while((j = leftfind(mask, pattern)) >= 0) { p = mask + j + 1; int k = i; #ifdef SETCHECK while(k--) set0(p++); #else while(k--) *p++ = '0'; #endif } } delete pattern; } pe_(21); } } ps_(22); run10(run, mask, m, n); pe_(22); ps_(23); mask1 = newchar(m + 1); int j = n1, *run1 = newint(n); char *p = mask1 + m1, *q = mask; while(*q) *p-- = *q++; mask1[m] = '\0'; for(i = 0; i < n;) run1[i++] = run[j--]; run10(run1, mask1, m, n); p = mask1 + m1; q = mask; do { #ifdef SETCHECK if (*p == '1') set1(q); else if(*p == '0') set0(q); #else if (*p == '1') *q = '1'; else if(*p == '0') *q = '0'; #endif p--; } while(*(++q)); delete mask1; delete run1; pe_(23); ps_(24); for(nrun = 1; nrun < n; nrun++) { int maxrun = 0, k; i = rest; for(int j = nrun - 1; j >= 0; j--) { if(maxrun < run[j]) maxrun = run[j]; if((i -= (run[j] + 1)) < 0) break; } for(i = 0, k = 0; i < nrun; i++) k += (run[i] + 1); i = 0; while(mask[k + i] == '1') i++; if(i) { #ifdef SETCHECK if(i == maxrun) set0(mask + k - 1); #else if(i == maxrun) mask[k - 1] = '0'; #endif } else { for(i = 1; i <= run[nrun]; i++) if(mask[k + i] == '1') break; if(i <= run[nrun]) { j = k + i; i = 1; while(mask[j + i] == '1') i++; if(maxrun < run[nrun]) maxrun = run[nrun]; if(i == maxrun) { #ifdef SETCHECK set0(mask + j - 1); set0(mask + j + i); #else mask[j - 1] = mask[j + i] = '0'; #endif } } } } pe_(24); ps_(25); for(nrun = n - 2; nrun >= 0; nrun--) { int maxrun = 0, k; i = rest; for(int j = nrun + 1; j < n; j++) { if(maxrun < run[j]) maxrun = run[j]; if((i -= (run[j] + 1)) < 0) break; } for(i = n1, k = m1; i > nrun; i--) k -= (run[i] + 1); i = 0; while(k - i >= 0 && mask[k - i] == '1') i++; if(i) { #ifdef SETCHECK if(i == maxrun) set0(mask + k + 1); #else if(i == maxrun) mask[k + 1] = '0'; #endif } else { for(i = 1; i <= run[nrun]; i++) if(mask[k - i] == '1') break; if(i <= run[nrun]) { j = k - i; i = 1; while(mask[j - i] == '1') i++; if(maxrun < run[nrun]) maxrun = run[nrun]; if(i == maxrun) { #ifdef SETCHECK set0(mask + j + 1); set0(mask + j - i); #else mask[j + 1] = mask[j - i] = '0'; #endif } } } } pe_(25); po_(); return; } void run10(int *run, char *mask, int m, int n) { int i, j; #ifdef DEBUG11 printf("< run10 in > m=%d, n=%d\nmask : %s\n", m, n, mask); matprint(run, n, "run"); #endif int k = 0; while((i = leftfind(mask + k, "10")) >= 0) { k += i; int nrun = 1; for(int ii = k - 1; ii >= 0 && mask[ii] == '1'; ii--) nrun++; k++; int flag = 0, minrun = m; for(i = 0, j = run[i]; ; i++) { if(nrun <= run[i] && j <= k) { flag++; if(minrun > run[i]) minrun = run[i]; } if(i == n - 1) break; j += (run[i + 1] + 1); } #ifdef DEBUG11 printf("k=%d, nrun=%d, minrun=%d, flag=%d\n", k, nrun, minrun, flag); #endif #ifdef SETCHECK for(i = 0; i < minrun - nrun; i++) set1(mask + ii--); if(flag == 1) set0(mask + ii); #else for(i = 0; i < minrun - nrun; i++) mask[ii--] = '1'; if(flag == 1) mask[ii] = '0'; #endif } #ifdef DEBUG11 printf("< run10 out >\nmask : %s\n", mask); #endif } void shrinkmask(int *run, char *mask, int m, int n, int *newrun, char *newmask, int *set, int *mm, int *nn) { #ifdef DEBUG4 printf("< shrinkmask in > m=%d,n=%d\nmask : %s\n", m, n, mask); matprint(run, n, "run"); #endif int i = 0, mm1 = m, nn1 = n, startrun = 0; do { while(mask[i] == '0') { i++; mm1--; } if(mask[i] == '.') break; do { mm1--; } while(mask[++i] == '1'); startrun++; if(mask[i] == '0') { i++; mm1--; } } while(--nn1 != 0); int startmask = m - mm1; #ifdef DEBUG4 printf("startmask=%d, startrun=%d, mm1=%d, nn1=%d\n", startmask, startrun, mm1, nn1); #endif if(nn1) { i = m - 1; do { while(mask[i] == '0') { i--; mm1--; } if(mask[i] == '.') break; do { mm1--; } while(mask[--i] == '1'); if(mask[i] == '0') { i--; mm1--; } } while(--nn1 != 0); } #ifdef DEBUG4 printf("mm1=%d, nn1=%d\n", mm1, nn1); #endif if(leftfind(mask + startmask, "00") == -1) { #ifdef DEBUG4 printf("*** Not find '00' code ***\n"); #endif strcpy(newmask, mask + startmask); newmask[mm1] = '\0'; for(i = 0; i < mm1;) set[i++] = startmask++; } else { #ifdef DEBUG4 printf("*** Find '00' code ***\n"); #endif int j = startmask, k = 1, inew = 0, nset = 0; m = mm1; for(i = 0; i < m; i++) { if(k || mask[j] != '0') { newmask[inew++] = mask[j]; // set[nset++] = j; set[nset++] = i + startmask; } else mm1--; // k = (mask[j++] != '0'); k = (mask[j++] != '0')? 1: 0; } newmask[inew] = '\0'; } for(i = 0; i < nn1;) newrun[i++] = run[startrun++]; #ifdef DEBUG4 printf("< shrinkmask out > mm=%d,nn=%d\n", mm1, nn1); printf("newmask : %s\n", newmask); matprint(newrun, nn1, "newrun"); matprint(set, mm1, "set"); #endif *mm = mm1; *nn = nn1; } void remake(char *mask, char *mask1, int *set, int m) { while(m--) { char c = mask1[m]; #ifdef SETCHECK if (c == '1') set1(mask + set[m]); else if(c == '0') set0(mask + set[m]); #else if (c == '1') mask[set[m]] = '1'; else if(c == '0') mask[set[m]] = '0'; #endif } } int leftfind(char *mask, char *pattern) { int m = strlen(mask); int mm = m - strlen(pattern) + 1; int i = 0; do { char *p = pattern; if(mask[i] != *p) i++; else { int j = i; do { if(*(++p) == '\0') return j; if(++i == m) return -1; } while(*p == mask[i]); } } while(i < mm); return -1; } |
能 50 55 6 1 8 2 1 1 5 4 2 5 4 9 2 1 5 6 2 4 7 3 7 17 3 5 5 4 6 10 3 4 6 2 2 2 4 1 3 1 5 8 1 2 3 5 2 3 1 6 13 3 4 2 2 6 1 14 3 4 2 2 5 1 18 4 6 1 1 5 1 18 3 5 2 1 4 1 20 2 3 1 6 19 3 1 8 1 1 7 3 1 7 1 2 4 3 5 2 7 1 1 11 7 1 2 2 1 1 23 2 1 3 1 1 11 3 2 5 1 8 7 4 3 5 1 11 12 3 8 8 2 11 4 1 3 |
3 1 13 8 3 3 4 2 8 4 1 1 1 2 1 2 9 1 3 2 2 2 1 1 8 13 11 2 1 1 1 29 3 2 1 2 1 1 12 10 3 1 1 1 2 5 11 1 1 2 1 3 10 1 2 6 4 7 2 5 5 1 2 3 6 7 1 4 7 4 8 1 35 2 1 2 10 16 1 1 3 3 11 18 1 2 6 13 4 10 8 2 17 17 1 1 8 5 2 15 5 5 2 10 3 2 1 3 4 4 10 7 1 15 10 4 30 3 27 2 27 1 28 1 6 |
3 2 2 2 1 4 2 3 3 1 3 2 2 2 2 1 2 1 2 4 3 3 2 2 3 5 3 2 1 2 1 5 4 16 3 1 1 7 4 10 8 1 2 10 2 9 8 2 2 1 12 2 2 9 7 2 2 9 4 2 9 7 4 8 4 1 8 7 4 7 5 1 7 7 4 7 5 2 7 7 4 7 6 3 6 4 2 3 1 3 6 4 6 3 1 3 1 3 6 12 2 1 3 1 3 6 3 8 1 2 2 1 3 5 1 9 1 1 2 1 2 5 4 6 1 1 2 1 2 5 3 6 1 1 2 1 2 5 1 7 1 1 3 1 1 1 6 1 8 2 2 2 4 6 5 2 2 2 2 4 8 5 3 3 1 2 4 8 |
2 3 3 1 3 5 5 3 5 4 1 3 4 4 8 5 1 3 4 4 7 5 2 4 4 4 6 3 4 6 4 4 4 2 6 6 5 5 2 6 3 6 13 2 5 1 8 14 2 6 2 1 7 14 4 1 4 21 3 2 21 1 2 2 1 1 19 1 2 2 1 6 3 9 2 1 1 2 3 2 3 7 2 2 2 2 1 2 2 3 5 2 2 5 1 1 1 1 8 5 4 2 1 1 2 3 1 2 8 1 1 1 2 4 1 1 4 1 1 3 3 7 2 12 3 1 5 3 4 3 14 1 3 3 1 5 3 9 5 1 1 3 4 1 4 8 4 1 1 1 3 4 9 4 2 1 1 4 6 4 5 1 2 2 3 8 9 4 1 4 13 10 1 6 11 4 |
オードリー・ヘップバーン 35 50 48 48 47 47 3 3 2 2 24 2 1 3 1 1 1 16 1 1 6 1 2 1 15 1 1 4 2 2 1 11 3 3 4 2 2 2 1 7 2 2 1 5 1 1 3 1 6 3 2 7 1 1 5 1 8 2 1 4 3 2 1 3 3 1 2 5 5 1 1 2 1 4 3 2 2 1 2 5 2 1 1 2 3 1 1 5 1 1 1 2 3 1 3 2 2 2 2 1 2 3 1 1 3 2 1 1 3 3 1 2 1 2 6 2 2 3 1 |
1 3 3 2 3 1 1 3 1 1 1 3 2 1 1 2 3 2 3 2 1 3 1 2 3 1 1 1 2 1 1 4 4 1 1 1 2 1 1 1 1 4 4 1 3 1 2 3 4 3 1 1 3 2 1 3 2 2 8 3 2 2 1 8 3 2 5 2 8 1 12 1 6 1 13 3 12 3 4 1 11 1 1 17 2 1 4 2 1 7 1 2 22 11 5 2 2 19 1 13 2 22 47 8 1 1 2 14 6 1 1 2 2 11 5 1 2 1 2 1 1 2 7 4 1 5 1 1 1 2 8 5 5 8 1 3 3 7 7 4 1 1 4 |
5 15 2 1 4 4 18 2 1 3 4 9 1 1 7 1 3 4 4 1 1 4 4 6 7 3 5 5 2 4 6 2 4 8 1 4 8 1 4 7 1 4 10 4 7 5 7 3 1 9 5 2 1 1 4 3 4 1 2 1 1 4 2 1 1 4 2 3 1 5 4 1 1 4 2 1 1 1 6 2 2 1 2 1 2 1 5 1 1 1 2 2 5 1 2 5 1 3 3 5 2 1 4 |
5 1 1 5 6 1 1 1 5 7 2 1 3 1 1 5 12 4 4 7 7 2 2 1 1 1 7 8 11 1 8 9 2 2 1 9 8 1 7 1 10 9 1 5 1 3 7 11 3 7 11 3 7 12 4 7 13 5 6 12 10 6 11 9 6 8 1 5 5 7 1 5 5 2 1 2 4 1 1 2 1 2 3 4 5 3 1 1 4 3 1 2 |