- 论坛徽章:
- 12
|
回复 24# rubyish
链表的版本来了(我已经把C忘光了,折腾了一整天……
写的很凌乱,加载和导出没有做详细的错误判断处理。
机制:
如果没有结构文件,会执行 maketree() 建立链表树,然后dump到 F:/struct.dat
如果找到结构文件会直接加载。
效率(CPU: i7-4790K):
print 不计入内,从文件加载,遍历所有情况,耗时 0.006秒
print 不计入内,重新建造树,遍历所有情况,耗时 0.050秒
- // Game - Bulls and Cows
- // Code By 523066680@163.com
- // zhuanlan.zhihu.com/PerlExample
- // 2017-09
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #define SIZE 10*9*8*7
- #define print_num(s) printf("%c%c%c%c\n", s[0], s[1], s[2], s[3])
- typedef struct { int a, b; } AB;
- int odi = 0;
- int idx;
- char (order[SIZE])[4];
- int oindex[SIZE];
- int temparr[SIZE];
- void permute(char *elements, char *getstr, int len, int lv);
- void bullscows( char target[4], char guess[4], AB *res );
- int reduce( int *oindex, char *guess, AB *res, int *subset, int osize );
- void printstate( char *guess, AB *res, int n );
- FILE* fp;
- struct node
- {
- char guess[5];
- struct node *res[13];
- int count;
- };
- int mapindex[4][5] = {
- {0, 1, 2, 3, 4,},
- {5, 6, 7, 8,-1,},
- {9, 10,11,-1,-1,},
- {12,-1,-1,-1,-1}
- };
- AB alltypes[13] =
- {
- {0,0},{0,1},{0,2},{0,3},{0,4},
- {1,0},{1,1},{1,2},{1,3},
- {2,0},{2,1},{2,2},
- {3,0}
- };
- // ---------------- about Tree node ------------------ //
- void node_value(struct node *pt, char *str)
- {
- strncpy( pt->guess, str, 4 );
- pt->count = 0;
- }
- void node_alloc(struct node *pt)
- {
- for (int i = 0; i < 13; i++)
- {
- pt->res[i] = (struct node *) malloc( sizeof( struct node ) );
- strcpy(pt->res[i]->guess, "\0\0\0\0");
- pt->res[i]->count = 0;
- for (int j = 0; j < 13; j++)
- {
- pt->res[i]->res[j] = NULL;
- }
- }
- }
- void load_tree( struct node *pt, FILE *fp, int lv )
- {
- fread(pt, sizeof(struct node), 1, fp);
- if ( pt->count > 0 && (! feof(fp) ) )
- {
- node_alloc( pt );
- for (int i = 0; i < 13; i++)
- {
- load_tree( pt->res[i], fp, lv+1 );
- }
- }
- }
- void dump_tree( struct node *pt, FILE *fp, int lv )
- {
- fwrite( pt, sizeof(struct node), 1, fp );
- if ( pt->count > 0 )
- {
- for (int i = 0; i < 13; i++)
- {
- dump_tree( pt->res[i], fp, lv+1 );
- }
- }
- }
- void node_print(struct node *pt, int lv)
- {
- for (int i = 0; i < 13 ; i++)
- {
- printf("[%d%d] %s\n", alltypes[i].a,alltypes[i].b,
- pt->res[i]->guess);
- }
- }
- void tree_print(struct node *pt, int lv)
- {
- if ( pt->guess[0] != '\0' )
- {
- for (int i = 0; i < lv; i++)
- printf(" ");
- printf("%s %d %d\n", pt->guess, pt->count, lv);
- }
- if ( pt->count > 0 )
- {
- for (int i = 0; i < 13 ; i++)
- {
- //printf("[%d%d]\n", alltypes[i].a, alltypes[i].b );
- tree_print( pt->res[i], lv+1 );
- }
- }
- }
- void maketree( int *oindex, int osize, int lv, struct node *pt )
- {
- char guess[5];
- int subset[SIZE];
- int nsize; //new_size
- node_alloc(pt);
- strncpy(guess, order[oindex[0]], 4);
- for (int ti = 0; ti < 13; ti++)
- {
- //筛选出相同反馈的排列
- memset(subset, 0, SIZE);
- nsize = reduce( oindex, guess, &alltypes[ti], subset, osize );
- if (nsize > 0)
- {
- node_value( pt->res[ti], order[subset[0]] ) ;
- maketree( subset, nsize, lv+1, pt->res[ti] );
- pt->count++;
- }
- }
- }
- // ---------------- end Tree node ------------------ //
- int main(int argc, char *argv[] )
- {
- char elements[] = "0123456789";
- char getstr[10]; //临时缓冲区
- //生成所有组合到 order 数组(全局)
- permute(elements, getstr, strlen(elements), 0);
- //初始化、重置索引数组(筛选函数间接通过索引处理)
- for (int i = 0; i < SIZE; i++) oindex[i] = i;
- struct node tree;
- FILE *fp;
- fp = fopen("F:/sturct.dat", "rb");
- if (fp)
- {
- load_tree( &tree, fp, 0 );
- }
- else
- {
- fp = fopen("F:/sturct.dat", "wb");
- node_value( &tree, (char *)"0123");
- maketree( oindex, SIZE, 0, &tree ); //index, size, level, pt
- dump_tree( &tree, fp, 0 );
- }
- fclose( fp );
- AB ab;
- struct node *pt;
- char target[4];
- int count = 0;
- for (int m = 0; m < SIZE; m++ )
- {
- pt = &tree;
- strncpy(target, order[m], 4);
- //print_num( target ); //显示目标数字
- while ( 1 )
- {
- bullscows( target, pt->guess, &ab );
- //printf("%s [%d%d]\n", pt->guess, ab.a, ab.b ); //显示当前情况
- count++;
- if (ab.a == 4) break;
- pt = pt->res[ mapindex[ab.a][ab.b] ];
- if ( pt->guess[0] == '\0' )
- {
- printf("Something wrong!");
- break;
- }
- }
- //printf("\n");
- }
-
- printf("Clock:%ld, count: %d, avg: %.3f\n",
- clock(), count, (float)count/((float)SIZE)
- );
- return 0;
- }
- int reduce( int *oindex, char *guess, AB *res, int *subset, int osize )
- {
- AB t;
- int idx = 0;
- for (int i = 0; i < osize; i++)
- {
- bullscows( guess, order[ oindex[i] ], &t );
- if ( (t.a == res->a) &&
- (t.b == res->b) &&
- (strncmp(guess, order[ oindex[i] ], 4) != 0 ) ) //不全等
- {
- subset[idx] = oindex[i];
- idx++;
- }
- }
- return idx;
- }
- void bullscows( char target[4], char guess[4], AB *res )
- {
- int idx;
- res->a = 0;
- res->b = 0;
- for ( idx = 0; idx < 4; idx++ )
- {
- if ( target[idx] == guess[idx] )
- res->a++;
- else
- if ( strchr(target, guess[idx]) != 0 )
- {
- res->b++;
- }
- }
- }
- void permute(char *elements, char *getstr, int len, int lv)
- {
- char *tempele = (char *)malloc( len * sizeof(char) );
- for ( int i = 0; i < len; i++)
- {
- strcpy( tempele, elements );
- getstr[lv] = elements[i];
- for (int j = i; j < (len-1); j++) //popup one char
- tempele[j] = elements[j+1];
- if ( lv < 4 )
- permute( tempele, getstr, len-1, lv+1 );
- else
- {
- strncpy( order[odi++], getstr, 4 );
- break;
- }
- }
- }
复制代码
|
评分
-
查看全部评分
|