rubyish 发表于 2017-09-06 04:01

v8:
1       1
2       13
3       108
4       639
5       2083
6       1900
7       293
8       3
----------------
COUNT = 26797
TEST= 5040
AVE   = 5.316865

real    0m6.763s

naive: 4.43s1       1
2       13
3       108
4       596
5       1668
6       1768
7       752
8       129
9       5
----------------
COUNT = 28024
TEST= 5040
AVE   = 5.560317

real    0m4.437s


code:
// gcc -Wall -march=native -Ofast -o bull bull.c

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

# define OK   0x40
# define get_a(A)   A >> 4
# define get_b(A)   0xF & A
# define copy(A, B) memcpy (A, B, 4)
# define move1(A)   ((1 << A) | (1 << A) | (1 << A) | (1 << A))
# define toInt(N)   1000 * N + 100 * N + 10 * N + N;
# define INIT(A)    for (int i = 0; i < 5040; i++) A = i;
# define AB(A, B)   XAYB
# define TEST 5040

typedef char kar;
typedef double dub;
typedef void voi;

kar XAYB;
int A_and_B;       // LOOK: sub genB
kar SPLIT;       // SPLIT = [ 0, 1, 2, 3 ]
int TOTO;
int MAYBE;      // [ 0 .. 5039 ]
int INDES;          // 4A: 0x40 == 64
int COUNT;          //
dub INFO;
int LEN_MAYBE;          // @MAYBE

voi init (voi);
voi test (voi);
voi genTOTO (int);
voi genIndes (voi);
voi genB (voi);
voi genAB (voi);
voi rehashMaybe (int, int);
int gimme (int);

/* ____________________ MAIN ____________________ */
int main (){
    init ();
    test ();
}

/* _____________________ SUB _____________________ */

voi test () {
    fprintf (stderr, "\rtest ");
    for (int v = 0; v < TEST; v++) {
      if (!(v % 100)) fprintf (stderr, "%6d\b\b\b\b\b\b", v);
      // printf ("%d\n", v + 1);
      INIT (MAYBE);
      int ans = v;
      int gue = 0;
      LEN_MAYBE = 5040;
      // printf ("_ [ %04d ]\n", TOTO);
      int x;
      for (x = 1; x < 10; x++) {
            int ab = AB (ans, gue);
            // int a= get_a (ab);
            // int b= get_b (ab);
            // printf ("%d [ %04d ] AB %d %d\n", x, TOTO, a, b);
            if (ab == OK) break;
            rehashMaybe (gue, ab);
            gue = gimme (x);
            // gue = MAYBE; /* NAIVE: FAST */

      }
      COUNT++;
    }

    int ave = 0;
    int tot = 0;
    puts ("FINISH");
    for (int i = 1; i < 15; i++) {
      if (!COUNT) continue;
      printf ("%d\t%d\n", i, COUNT);
      ave += i * COUNT;
      tot += COUNT;
    }

    if (tot != TEST) puts ("ERROR");
    puts ("----------------");
    printf ("COUNT = %d\n", ave);
    printf ("TEST= %d\n", TEST);
    printf ("AVE   = %f\n", ave / (dub)TEST);
} /* test */

voi init () {
    fprintf (stderr, "init..");
    genTOTO (0);
    genB ();
    genAB ();
    genIndes ();
    for (int i = 0; i < 1000; i++) INFO = i * log (i);
}

voi genTOTO (int lev){
    static kar num;
    static int I = 0;
    static int has;

    if (lev == 4) {
      int n = toInt (num);
      TOTO = n;
      copy (SPLIT, num);
      I++;
      return;
    }

    for (int i = 0; i <= 9; i++) {
      if (has) continue;
      has   = 1;
      num = i;
      genTOTO (lev + 1);
      has = 0;
    }
} /* genTOTO */

voi genB (){
// 0b1111000000 => bit(1): 9876, val = 960
// 0123:0b001111
// 0153:0b101011
// A & B: 0b001011 = 0b1011(=11), count(1) = 3, $A = 3
    for (int i = 0; i < 961; i++) {
      int count = 0;

      for (int j = 0; j < 10; j++) {
            if (i & (1 << j)) count++;
            if (count > 4) break;
      }
      A_and_B = count > 4 ? 0 : count;
    }
}

voi genAB (){
    for (int i = 0; i < 5040; i++) {
      kar *cha = SPLIT;
      int C1   = move1 (cha);

      for (int j = 0; j < 5040; j++) {
            kar *cha2 = SPLIT;
            int C2    = move1 (cha2);
            int A   = 0;
            for (int k = 0; k < 4; k++)
                if (cha == cha2) A++;
            int B = C1 & C2;
            B          = A_and_B - A;
            XAYB = (A << 4) | B;
      }
    }
}

inline
voi rehashMaybe (int gue, int ab){
    int I = 0;

    for (int i = 0; i < LEN_MAYBE; i++) {
      if (AB (MAYBE, gue) == ab)
            MAYBE = MAYBE;
    }
    LEN_MAYBE = I;
}

inline
int gimme (int lev){
    if (LEN_MAYBE == 1 || lev == 1) return MAYBE;
    int best = 0;
    dub max= 999999.0; // BIG NUM

    for (int i = 0; i < LEN_MAYBE; i++) {
      int test = { 0 };

      for (int j = 0; j < LEN_MAYBE; j++) {
            int ab= AB (MAYBE, MAYBE);
            int pos = INDES;
            test++;
      }

      dub toto = 0.0;
      for (int i = 0; i < 14; i++)
            if (test) toto += INFO];
      if (max > toto) max = toto, best = i;
    }
    return MAYBE;
} /* gimme */

voi genIndes (){
    int var[] = { 0, 5, 9, 12, 13 };

    // 0x40 = 4A0B = 64
    // INDES = var + 0 = 13
    for (int a = 0; a <= 4; a++) {
      for (int b = 0; b <= 4; b++) {
            if (a + b > 4) continue;
            int ab = (a << 4) | b;
            int i= var + b;
            INDES = i;
            // if (a == 3) break;   /* NO 3A1B */
      }
    }
}



523066680 发表于 2017-09-06 14:22

本帖最后由 523066680 于 2017-09-06 14:27 编辑

我写的C的版本,用比较直白的方式写,没有采用优化方案(还是用脚本方便)

包括 5040 次 printf ,耗时差不多1.2秒。
times: 28024, average: 5.560317
Clock: 1185
// 523066680 2017-08

#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, s, s, s)
typedef struct { int a, b; } AB;

int odi = 0;
int idx;
char (order);
int oindex;
int temparr;

void permute(char *elements, char *getstr, int len, int lv);
void guess_s( char *target, char *guess, AB *res );
void reduce( int *oindex, char *guess, AB *res );
void printstate( char *guess, AB *res, int n );

int main(int argc, char *argv[])
{
    char elements[] = "0123456789";
    char getstr;
    AB res;
   
    odi = 0;
    //生成所有组合到 order 数组(全局)
    permute(elements, getstr, strlen(elements), 0);

    char nums;
    char guess;
    int times = 0;

    //遍历所有5040种情况
    for (int mi = 0; mi < SIZE; mi++)
    {
      //初始化、重置索引数组(所有操作都是间接通过索引处理)
      for (int i = 0; i < SIZE; i++) oindex = i;

      //nums:目标数字,guess:猜测数字
      strncpy(nums, order, 4);
      strncpy(guess, "0123", 4);
      idx = SIZE;

      print_num(nums);

      while ( idx > 0 )
      {
            guess_s( nums, guess, &res );
            //printstate(guess, &res, idx);

            //筛选出相同反馈的排列
            reduce( oindex, guess, &res );
            //从筛选的子集中选第一个
            strncpy( guess, order[ oindex ], 4 );

            times++;
      }
    }

    printf("times: %d, average: %f\n", times, (float)times/5040.0);
    printf("Clock: %d\n", clock() );
    return 0;
}

void reduce( int *oindex, char *guess, AB *res )
{
    AB t;
    int ai = 0;

    for (int i = 0; i < idx; i++)
    {
      guess_s( guess, order[ oindex ], &t );
      if ( (t.a == res->a) &&
             (t.b == res->b) &&
            (strncmp(guess, order[ oindex ], 4) != 0 ) )//不全等
      {
            temparr = oindex;
            ai++;
      }
    }

    idx = ai;
    for (int i = 0; i < idx; i++) oindex = temparr;
}

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 = elements;

      for (int j = i; j < (len-1); j++)//popup one char
            tempele = elements;

      if ( lv < 4 )
            permute( tempele, getstr, len-1, lv+1 );
      else
      {
            strncpy( order, getstr, 4 );
            break;
      }
    }
}

void guess_s( char target, char guess, AB *res )
{
    char idx, in;
    res->a = 0;
    res->b = 0;

    for ( idx = 0; idx < 4; idx++ )
    {
      if ( target == guess )
            res->a++;
      else
            if ( strchr(target, guess) != 0 )
            {
                res->b++;
            }
    }
}

void printstate( char *guess, AB *res, int n )
{   
    char s;
    strncpy(s, guess, 4 );
    s = 0;
    printf("%s [%d%d] %d\n", s, res->a, res->b, n);
}

rubyish 发表于 2017-09-06 23:17

本帖最后由 rubyish 于 2017-09-06 19:19 编辑

回复 22# 523066680

Run le jici, faxian AVE jingran hui biandong? :em21::em21:
average:
6.275794
9.411508
2.425794

Xiugaile sub guess_s:

void guess_s (char target, char guess, AB *res){
    static char TAGRET0;// END = 0, for strchr

    memcpy (TAGRET0, target, 4);
    res->a = 0;
    res->b = 0;

    for (int i = 0; i < 4; i++) {
      if (target == guess) res->a++;
      else if (strchr (TAGRET0, guess)) res->b++;
    }
}

compile:
gcc -Wall -march=native -Ofast

time: 3.401s
times: 28024, average: 5.560317
Clock: 3398914

real    0m3.401s


Meiyou OPT de code jingrang hai kuaile OPT 1 miao!!
Zhe rang wo qile yixin, OPT shifou yijing useless le?

rubyish 发表于 2017-09-07 00:36

v9:
# add POWER

time: 0.7s
1       1
2       13
3       108
4       596
5       1668
6       1768
7       752
8       129
9       5
----------------
COUNT = 28024
TEST= 5040
AVE   = 5.560317

real    0m0.736s


1       1
2       13
3       108
4       639
5       2083
6       1900
7       293
8       3
----------------
COUNT = 26797
TEST= 5040
AVE   = 5.316865

real    0m4.433s

bull.c
// gcc -Wall -march=native -Ofast -o bull bull.c -lm

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

# define OK 0x40
# define get_a(A)   A >> 4
# define get_b(A)   0xF & A
# define copy(A, B) memcpy (A, B, 4)
# define move1(A)   ((1 << A) | (1 << A) | (1 << A) | (1 << A))
# define INIT(A)    for (int i = 0; i < 5040; i++) A = i;
# define AB(A, B)   (A < B ? XAYB : XAYB)
# define DATA(a)    TOTO, TOTO, TOTO, TOTO

# define TEST 5040

typedef char kar;
typedef double dub;
typedef void voi;

kar XAYB;
int A_and_B;       // LOOK: sub genB
kar TOTO;       // TOTO = [ 0, 1, 2, 3 ]
int MAYBE;      // [ 0 .. 5039 ]
int INDES;          // 4A: 0x40 == 64
int COUNT;          //
dub INFO;
int LEN_MAYBE;          // @MAYBE

voi init (voi);
voi test (voi);
voi genTOTO (int);
voi genIndes (voi);
voi genB (voi);
voi genAB (voi);
voi rehashMaybe (int, int);
int gimme (int);

/* ____________________ MAIN ____________________ */
int main (){
    init ();
    test ();
}

/* _____________________ SUB _____________________ */

voi test () {
    fprintf (stderr, "\rtest ");
    for (int v = 0; v < TEST; v++) {
      if (!(v % 100)) fprintf (stderr, "%6d\b\b\b\b\b\b", v);
      // printf ("%d\n", v + 1);
      INIT (MAYBE);
      int ans = v;
      int gue = 0;
      LEN_MAYBE = 5040;
      // printf ("_ [ %d%d%d%d ]\n", DATA (ans));
      int x;
      for (x = 1; x < 15; x++) {
            int ab = AB (ans, gue);
            // int a= get_a (ab);
            // int b= get_b (ab);
            // printf ("%d [ %d%d%d%d ] AB %d %d\n", x, DATA (gue), a, b);
            if (ab == OK) break;
            rehashMaybe (gue, ab);
            // gue = gimme (x);
            gue = MAYBE; /* NAIVE: FAST */

      }
      COUNT++;
    }

    int ave = 0;
    int tot = 0;
    puts ("FINISH");

    for (int i = 1; i < 15; i++) {
      if (!COUNT) continue;
      printf ("%d\t%d\n", i, COUNT);
      ave += i * COUNT;
      tot += COUNT;
    }

    if (tot != TEST) puts ("ERROR");
    puts ("----------------");
    printf ("COUNT = %d\n", ave);
    printf ("TEST= %d\n", TEST);
    printf ("AVE   = %f\n", ave / (dub)TEST);
} /* test */

voi init () {
    fprintf (stderr, "init...");
    genTOTO (0);
    genB ();
    genAB ();
    genIndes ();
    for (int i = 0; i < 1000; i++) INFO = i * log (i);
}

voi genTOTO (int lev){
    static kar num;
    static int I = 0;
    static int has;

    if (lev == 4) {
      copy (TOTO, num);
      I++;
      return;
    }

    for (int i = 0; i <= 9; i++) {
      if (has) continue;
      has   = 1;
      num = i;
      genTOTO (lev + 1);
      has = 0;
    }
} /* genTOTO */

voi genB (){
// 0b1111000000 => bit(1): 9876, val = 960
// 0123:0b001111
// 0153:0b101011
// A & B: 0b001011 = 0b1011(=11), count(1) = 3, $A = 3
    for (int i = 0; i < 961; i++) {
      int count = 0;

      for (int j = 0; j < 10; j++) {
            if (i & (1 << j)) count++;
            if (count > 4) break;
      }
      A_and_B = count > 4 ? 0 : count;
    }
}

voi genAB (){
    for (int i = 0; i < 5040; i++) {
      kar *cha = TOTO;
      int C1   = move1 (cha);

      for (int j = i; j < 5040; j++) {
            kar *cha2 = TOTO;
            int C2    = move1 (cha2);
            int A   = 0;
            for (int k = 0; k < 4; k++)
                if (cha == cha2) A++;
            int B = C1 & C2;
            B          = A_and_B - A;
            XAYB = (A << 4) | B;
      }
    }
}

inline
voi rehashMaybe (int gue, int ab){
    int I = 0;

    for (int i = 0; i < LEN_MAYBE; i++) {
      if (AB (MAYBE, gue) == ab)
            MAYBE = MAYBE;
    }
    LEN_MAYBE = I;
}

inline
int gimme (int lev){
    if (LEN_MAYBE == 1 || lev == 1) return MAYBE;
    int best = 0;
    dub min= 999999.0; // BIG NUM

    for (int i = 0; i < LEN_MAYBE; i++) {
      int test = { 0 };

      for (int j = 0; j < LEN_MAYBE; j++) {
            int ab= AB (MAYBE, MAYBE);
            int pos = INDES;
            test++;
      }

      dub toto = 0.0;
      for (int i = 0; i < 14; i++)
            if (test) toto += INFO];
      if (min > toto) min = toto, best = i;
    }
    return MAYBE;
} /* gimme */

voi genIndes (){
    int var[] = { 0, 5, 9, 12, 13 };

    // 0x40 = 4A0B = 64
    // INDES = var + 0 = 13
    for (int a = 0; a <= 4; a++) {
      for (int b = 0; b <= 4; b++) {
            if (a + b > 4) continue;
            int ab = (a << 4) | b;
            int i= var + b;
            INDES = i;
            // if (a == 3) break;   /* NO 3A1B */
      }
    }
}




523066680 发表于 2017-09-07 08:02

本帖最后由 523066680 于 2017-09-07 17:57 编辑

回复 23# rubyish

关于未优化比优化快一秒的问题,采用估值算法的程序增加了运算量,所以消耗可能更多。
要提高效率只有先生成结构树。可惜用C语言实现比较麻烦,所以用了perl

试了一下 Perl 内联C,跑完 5040种情况,0.087 秒(不含 print 耗时)
不使用内联C代码:0.4秒 (不含 print 耗时)

523066680 发表于 2017-09-08 00:09

回复 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, s, s, s)
typedef struct { int a, b; } AB;

int odi = 0;
int idx;
char (order);
int oindex;
int temparr;

void permute(char *elements, char *getstr, int len, int lv);
void bullscows( char target, char guess, 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;
    struct node *res;
    int count;
};

int mapindex = {
    {0,1, 2, 3, 4,},
    {5,6, 7, 8,-1,},
    {9, 10,11,-1,-1,},
    {12,-1,-1,-1,-1}
};

AB alltypes =
{
    {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 = (struct node *) malloc( sizeof( struct node ) );
      strcpy(pt->res->guess, "\0\0\0\0");
      pt->res->count = 0;
      for (int j = 0; j < 13; j++)
      {
            pt->res->res = 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, 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, fp, lv+1 );
      }
    }
}

void node_print(struct node *pt, int lv)
{
    for (int i = 0; i < 13 ; i++)
    {
      printf("[%d%d] %s\n", alltypes.a,alltypes.b,
            pt->res->guess);
    }
}

void tree_print(struct node *pt, int lv)
{
    if ( pt->guess != '\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.a, alltypes.b );
            tree_print( pt->res, lv+1 );   
      }
    }
}

void maketree( int *oindex, int osize, int lv, struct node *pt )
{
    char guess;

    int subset;
    int nsize;    //new_size

    node_alloc(pt);
    strncpy(guess, order], 4);

    for (int ti = 0; ti < 13; ti++)
    {
      //筛选出相同反馈的排列
      memset(subset, 0, SIZE);
      nsize = reduce( oindex, guess, &alltypes, subset, osize );

      if (nsize > 0)
      {
            node_value( pt->res, order] ) ;
            maketree( subset, nsize, lv+1, pt->res );
            pt->count++;
      }
    }
}

// ----------------end Tree node ------------------ //

int main(int argc, char *argv[] )
{
    char elements[] = "0123456789";
    char getstr; //临时缓冲区
    //生成所有组合到 order 数组(全局)
    permute(elements, getstr, strlen(elements), 0);

    //初始化、重置索引数组(筛选函数间接通过索引处理)
    for (int i = 0; i < SIZE; i++) oindex = 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;
    int count = 0;

    for (int m = 0; m < SIZE; m++ )
    {
      pt = &tree;
      strncpy(target, order, 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 ];
            if ( pt->guess == '\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 ], &t );
      if ( (t.a == res->a) &&
             (t.b == res->b) &&
            (strncmp(guess, order[ oindex ], 4) != 0 ) )//不全等
      {
            subset = oindex;
            idx++;
      }
    }

    return idx;
}

void bullscows( char target, char guess, AB *res )
{
    int idx;
    res->a = 0;
    res->b = 0;

    for ( idx = 0; idx < 4; idx++ )
    {
      if ( target == guess )
            res->a++;
      else
            if ( strchr(target, guess) != 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 = elements;

      for (int j = i; j < (len-1); j++)//popup one char
            tempele = elements;

      if ( lv < 4 )
            permute( tempele, getstr, len-1, lv+1 );
      else
      {
            strncpy( order, getstr, 4 );
            break;
      }
    }
}


rubyish 发表于 2017-09-08 00:18

回复 26# 523066680

v10: final version

time: 0.5s
1    1
2    13
3    108
4    596
5    1668
6    1768
7    752
8    129
9    5
----------------
COUNT = 28024
TEST= 5040
AVE   = 5.560317

real    0m0.515s


// gcc -Wall -march=native -Ofast -o bull bull.c -lm

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

# define OK 0x40
# define get_a(A)   A >> 4
# define get_b(A)   0xF & A
# define copy(A, B) memcpy (A, B, 4)
# define move1(A)   ((1 << A) | (1 << A) | (1 << A) | (1 << A))
# define INIT(A)    for (int i = 0; i < 5040; i++) A = i;
# define AB(A, B)   (A < B ? XAYB : XAYB)
# define DATA(a)    TOTO, TOTO, TOTO, TOTO

# define TEST 5040

typedef char kar;
typedef double dub;
typedef void voi;

kar XAYB;
int A_and_B;       // LOOK: sub genB
kar TOTO;       // TOTO = [ 0, 1, 2, 3 ]
int MAYBE;      // [ 0 .. 5039 ]
int INDES;          // 4A: 0x40 == 64
int COUNT;          //
dub INFO;
int MOVE;
int LEN_MAYBE;          // @MAYBE

voi init (voi);
voi test (voi);
voi genTOTO (int);
voi genIndes (voi);
voi genB (voi);
voi genAB (voi);
voi rehashMaybe (int, int);
int gimme (int);

/* ____________________ MAIN ____________________ */
int main (){
    init ();
    test ();
}

/* _____________________ SUB _____________________ */

voi test () {
    fprintf (stderr, "\rtest ");
    for (int v = 0; v < TEST; v++) {
      if (!(v % 100)) fprintf (stderr, "%6d\b\b\b\b\b\b", v);
      // printf ("%d\n", v + 1);
      INIT (MAYBE);
      int ans = v;
      int gue = 0;
      LEN_MAYBE = 5040;
      // printf ("_ [ %d%d%d%d ]\n", DATA (ans));
      int x;
      for (x = 1; x < 10; x++) {
            int ab = AB (ans, gue);
            // int a= get_a (ab);
            // int b= get_b (ab);
            // printf ("%d [ %d%d%d%d ] AB %d %d\n", x, DATA (gue), a, b);
            if (ab == OK) break;
            rehashMaybe (gue, ab);
            // gue = gimme (x);
            gue = MAYBE; /* NAIVE: FAST */

      }
      COUNT++;
    }

    int ave = 0;
    int tot = 0;
    puts ("FINISH");

    for (int i = 1; i < 15; i++) {
      if (!COUNT) continue;
      printf ("%d\t%d\n", i, COUNT);
      ave += i * COUNT;
      tot += COUNT;
    }

    if (tot != TEST) puts ("ERROR");
    puts ("----------------");
    printf ("COUNT = %d\n", ave);
    printf ("TEST= %d\n", TEST);
    printf ("AVE   = %f\n", ave / (dub)TEST);
} /* test */

voi init () {
    fprintf (stderr, "init...");
    genTOTO (0);
    genB ();
    genAB ();
    genIndes ();
    for (int i = 0; i < 1500; i++) INFO = i * log (i);
}

voi genTOTO (int lev){
    static kar num;
    static int I = 0;
    static int has;

    if (lev == 4) {
      copy (TOTO, num);
      MOVE = move1 (num);
      I++;
      return;
    }

    for (int i = 0; i <= 9; i++) {
      if (has) continue;
      has   = 1;
      num = i;
      genTOTO (lev + 1);
      has = 0;
    }
} /* genTOTO */

voi genB (){
    for (int i = 0; i < 961; i++) {
      int count = 0;

      for (int j = 0; j < 10; j++) {
            if (i & (1 << j)) count++;
            if (count > 4) break;
      }
      A_and_B = count > 4 ? 0 : count;
    }
}

voi genAB (){
    for (int i = 0; i < 5040; i++) {
      kar *cha = TOTO;
      int C1   = MOVE;
      for (int j = i; j < 5040; j++) {
            kar *cha2 = TOTO;
            int C2    = MOVE;
            int A   = 0;
            for (int k = 0; k < 4; k++)
                if (cha == cha2) A++;
            int B = A_and_B - A;
            XAYB = (A << 4) | B;
      }
    }
}

inline
voi rehashMaybe (int gue, int ab){
    int I = 0;

    for (int i = 0; i < LEN_MAYBE; i++) {
      if (AB (MAYBE, gue) == ab)
            MAYBE = MAYBE;
    }
    LEN_MAYBE = I;
}

inline
int gimme (int lev){
    if (LEN_MAYBE == 1 || lev == 1) return MAYBE;
    int best = 0;
    dub max= 999999.0; // BIG NUM

    for (int i = 0; i < LEN_MAYBE; i++) {
      int test = { 0 };

      for (int j = 0; j < LEN_MAYBE; j++) {
            int ab= AB (MAYBE, MAYBE);
            int pos = INDES;
            test++;
      }

      dub toto = 0.0;
      for (int i = 0; i < 14; i++)
            if (test) toto += INFO];
      if (max > toto) max = toto, best = i;
    }
    return MAYBE;
} /* gimme */

voi genIndes (){
    int var[] = { 0, 5, 9, 12, 13 };

    for (int a = 0; a <= 4; a++) {
      for (int b = 0; b <= 4; b++) {
            if (a + b > 4) continue;
            int ab = (a << 4) | b;
            int i= var + b;
            INDES = i;
      }
    }
}




rubyish 发表于 2017-09-08 00:29

回复 26# 523066680

run de jieguo shi:

bash: line 1:3567 Segmentation fault      (core dumped)


Zhege banben youyisi. Keyi xuexi ruhe maketree.
3Q~~

rubyish 发表于 2017-09-08 02:30

本帖最后由 rubyish 于 2017-09-07 22:43 编辑

回复 26# 523066680


Intel(R) Atom(TM) CPU N280   @ 1.66GHz
make tree: 0.16s
Clock:162568, count: 28024, avg: 5.560

real    0m0.166s

load tree: 0.03s
Clock:36215, count: 28024, avg: 5.560

real    0m0.039s

Very very fast!! kanlai wode final haibuneng final.

Zhege code wo bixu zixide yuedu.
Tansuo ta ruci shensu de aomi.
3Q ~~


Zhe shi xiugai bullscows hanshu zhihou de jieguo.

Jiu wo de lijie?

void bullscows (char target, char guess, AB *res){
...
    if (strchr (target, guess) != 0) {

Zhelide strchr shi cuowude shiyong.
strchr de diyige canshu bixu shi string. yejiushi yi '\0' jiewei de char array.

You yige example:
http://clc-wiki.net/wiki/strchr
In standard C, this can be implemented as:

char *strchr(const char *s, int c)
{
    while (*s != (char)c)
      if (!*s++) return 0;
    return (char *)s;
}


Huoshi windows de strchr butongyu C biaozhun?

rubyish 发表于 2017-09-08 03:03

What is this?
char (order);

youhe butong?
char order;
页: 1 2 [3] 4
查看完整版本: [算法讨论]猜数字游戏 - Bulls and Cows