#include #include #include #include #include #include typedef int (*fc) (int*, int); fc fi, fo; int mot[1000000], rr[1000000], code[1000], mot2[1000000]; int i, j, s, k, size, x, nb, mnb, pos, a_o, a_i, lim, l, *z, pp = 3; char mode[20]; void date(){ fflush(stdout); system("date \"+\%d/\%m/\%Y \%H/\%M/\%S\""); } int eq(int *g, int *d, int l){ for(; l--; ) if(g[l] != d[l]) return 0; return 1; } int neq(int *g, int *d, int l){ for(; l--; ) if(g[l] == d[l]) return 0; return 1; }//*/ int req(int *g, int *d, int l){ int x = 0; for(; l--; x++) if(g[l] != d[x]) return 0; return 1; }//*/ int ueq(int *g, int *d, int l){ return eq(g, d, l) || req(g, d, l); }//*/ int ceil32(int a, int b){ return (a+b-1)/b; } int rep(int *m, int i, int n, int d, int plus, int lon){ int x, y; for(; (x = ceil32(lon*n+plus, d)) <= i+1; lon++){ for(y = i-lon; (y >= 0) && (m[y] == m[y+lon]); y--); if(i-y >= x) return 0; } return 1; }//*/ int sqf(int *m, int i){ return rep(m, i, 2, 1, 0, 1); }//*/ int rt3(int *m, int i){ return rep(m, i, 7, 4, 1, 1); }//*/ int rt4(int *m, int i){ return rep(m, i, 7, 5, 1, 1); }//*/ int rt5(int *m, int i){ return rep(m, i, 5, 4, 1, 1); }//*/ int rt6(int *m, int i){ return rep(m, i, 6, 5, 1, 1); }//*/ int rt7(int *m, int i){ return rep(m, i, 7, 6, 1, 1); }//*/ int forb(int *m, int i, char *ch){ int a, x, l = i+1; x = strlen(ch); if(l < x) return 0; for(a = 0; a < x && m[l-x+a] == ch[a]-'0'; a++); return a == x; } int forb3(int *m, int i, char *ch){ int a, v, x, l = i+1; x = strlen(ch); if(l < x) return 0; v = (ch[0]-m[l-x])%3; for(a = 1; a < x && (ch[a]-m[l-x+a])%3 == v; a++); return a == x; } int forb2(int *m, int i, char *ch){ int a, x, l = i+1; x = strlen(ch); if(l < x) return 0; for(a = 0; a < x && m[l-x+a] != ch[x-1-a]-'0'; a++); if(a == x) return 1; for(a = 0; a < x && m[l-x+a] == ch[x-1-a]-'0'; a++); if(a == x) return 1; for(a = 0; a < x && m[l-x+a] != ch[a]-'0'; a++); if(a == x) return 1; for(a = 0; a < x && m[l-x+a] == ch[a]-'0'; a++); return a == x; } int contains(int *m, int i, char *ch){ int j = strlen(ch)-1; for(; j <= i; j++) if(forb(m, j, ch)) return 1; return 0; } int rev2(int *m, int i){//avoiding abcbUa · cbUabUc · bR int a, b, c, d, l = i+1, w = 11; if(l >= w) for(a = 0; a <= l-w ; a++) if(req(m+a, m+l-w, w)) return 0; if(!rep(m, i, 22, 15, 1, 85)) return 0; for(a = 1; 2*a+3 <= l && a <= 140; a++) for(b = 1; 2*a+2*b+1 <= l && b < w; b++) for(c = 1; 2*a+2*b+c <= l && c <= 140; c++) if(eq(m+l-2*a-2*b-c, m+l-a, a) && ueq(m+l-a-2*b-c, m+l-a-b, b)) for(d = 0; a+2*b+2*c+d <= l; d++) if(eq(m+l-c-d, m+l-a-b-c, c) && ueq(m+l-b-c-d, m+l-a-b, b) && eq(m+l-a-b-c-d, m+l-a-b-c, a) && ueq(m+l-a-2*b-c-d, m+l-a-b, b) && eq(m+l-a-2*b-2*c-d, m+l-a-b-c, c)) return 0; return 1; }//*/ int rev3(int *m, int i){//avoiding abca · bcUab · cR int a, b, c, d, e, l = i+1, w = 4; if(l >= w) for(a = 0; a <= l-w ; a++) if(req(m+a, m+l-w, w)) return 0; if(!rep(m, i, 131, 90, 1, 28)) return 0; for(a = 1; 2*a+2 <= l && a <= 32; a++) for(c = 1; 2*a+1+c <= l && c < w; c++) for(e = 0; c+e <= l; e++) if(req(m+l-c-e, m+l-a-c, c)) for(b = 1; 2*a+b+c <= l && a+b <= 32; b++) if(eq(m+l-2*a-b-c, m+l-a, a)) for(d = 0; a+2*b+c+d <= l; d++) if(ueq(m+l-a-b-c-d, m+l-a-c, c) && eq(m+l-a-b-d, m+l-a-2*b-c, a+b) && eq(m+l-a-2*b-c-d, m+l-b-d, b)) return 0; return 1; }//*/ int phik(int *m, int i){ int a, l = i+1, k = size-3;// This is the k of the formula \phi_k. if(!i) return 1; if(m[i] == m[i-1]) return 0; if(forb(m, i, "10")) return 0; if(forb(m, i, "21")) return 0; if(forb(m, i, "31")) return 0; if(forb(m, i, "41")) return 0; if(forb(m, i, "02")) return 0;// the allowed factors of length 2 are if(forb(m, i, "03")) return 0;// 01 12 13 14 20 30 40 23 34 42 if(forb(m, i, "04")) return 0; if(forb(m, i, "32")) return 0; if(forb(m, i, "43")) return 0; if(forb(m, i, "24")) return 0; for(a = 1; 2*a+k <= l; a++) if(eq(m+l-2*a-k, m+l-a, a)) return 0; return 1; }//*/ int ok(){ if(mnb < nb) {printf("nb=%d ", mnb = nb); date("");} /*for(k = 0; k < size; k++) if(mot[k+(nb-2)*size] > mot[k+(nb-1)*size]) break; else if(mot[k+(nb-2)*size] < mot[k+(nb-1)*size]){ i -= size; return 0;}//*/ for(*code = x = 0; ;) if(!fi(code, x)){ ici: while(code[x] == nb-1) if(!x--) return 1; code[x]++; }else{ s = nb-1-code[x];//optimized version //s = code[x];//old version for(k = 0; k < size; k++){ mot2[pos = k+x*size] = mot[k+s*size]; if(x && !fo(mot2, pos)) return 0; } if(x == lim-1) goto ici; else code[++x] = 0; } } int other(){ if(fo == phik) return 1; //if(size >= 6 && i+1 >= 3*size && eq(mot+size, mot+2*size, size)){ printf("oh1! i=%d\n", i); for(l = 0; l <= i; l++) printf("%d", mot[l]); printf("\n"); } //if(i%size < 2 && mot[i]) return 0; if(i >= size) for(k = i-i%size; k <= i; k++) if(mot[k] < mot[k-size]) break; else if(mot[k] > mot[k-size]){ i -= i%size+1; return 0; } for(k = 0; k <= i%size; k++) mot2[size+k] = mot[i-i%size+k]; for(k = 0; k < i/size-1; k++){ for(j = 0; j < size; j++) mot2[j] = mot[k*size+j]; if(!fo(mot2, size+i%size)) return 0; } //if(size >= 6 && i+1 >= 3*size && eq(mot+size, mot+2*size, size)){ printf("oh2! i=%d\n", i); for(l = 0; l <= i; l++) printf("%d", mot[l]); printf("\n"); exit(0); } return 1; } int A(){ for(i = 0; i < size; i++) mot[i] = 0; mnb = nb = 0; printf("%s size=%d a_i=%d a_o=%d lim=%d ", mode, size, a_i, a_o, lim); date(""); for(*mot = i = 0; ;) if(!fo(mot, i) || !other()){ here: while(mot[i] == a_o-1) if(!i--) return 1; //if(nb && i < 3) return 1;//optimisation au cas par cas mot[i]++; }else if((!((i+1)%size)) && ((nb = (i+1)/size) > 1)) if(!ok()) goto here; else if(nb == a_i) break; else goto there; else there: mot[++i] = 0; for(x = 0; x < a_i; x++, printf("\n")) for(k = 0; k < size; k++) printf("%d", mot[k+x*size]); printf("OK %s size=%d lim=%d ", mode, size, lim); date(""); return 0; } void usage(){ printf("Usage: gen_r fo a_i a_o size lim\n"); exit(0); } int main(int ac, char **av){ if(ac != 6) usage(); sprintf(mode, "%s", av[1]); a_i = ac > 2 ? atoi(av[2]) : 5; switch(a_i){ //case 2: fi = tt5m; break; //case 3: fi = sqf; break; //case 3: fi = tm3; break; case 3: fi = rt3; break; //case 4: fi = m4; break; case 4: fi = rt4; break; case 5: fi = rt5; break; case 6: fi = rt6; break; case 7: fi = rt7; break; } if(!strcmp(mode, "rev2")) fo = rev2; else if(!strcmp(mode, "rev3")) fo = rev3; else if(!strcmp(mode, "phik")) fo = phik; else usage(); a_o = ac > 3 ? atoi(av[3]) : 3; size = ac > 4 ? atoi(av[4]) : 1; lim = ac > 5 ? atoi(av[5]) : 10; for(; A() && size < 450; size++); }