goroh_kun

GDD2011 Slide Puzzle

Sep 12th, 2011
2,624
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 21.38 KB | None | 0 0
  1. /*
  2.  * slide puzzle answer check & solver
  3.  *
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. #define MAX_STEP 2000
  11. #define MAX_ANS_STEP 2000
  12.  
  13. /* 枝を刈る基準になる葉の数 */
  14. #ifndef CUT_DETECT_NUM
  15. #define CUT_DETECT_NUM 20000
  16. #endif
  17.  
  18. /* 枝を刈ったあとに残す葉の数 */
  19. #ifndef CUT_REMAIN_NUM
  20. #define CUT_REMAIN_NUM 3000
  21. #endif
  22.  
  23. struct nodeT;
  24. typedef struct problemT
  25. {
  26.     int w;
  27.     int h;
  28.     char* data; // 現在のパターン
  29.     char* goal; // 解答のパターン
  30.     char* sequence; //シーケンス(存在すれば)
  31.     long long wall;
  32.     int* swap_data;
  33.     char posChar[0x100];
  34.     char valChar[36];
  35.     int* eval_data[36];
  36.     int found_answer;
  37.     int step_max_eval[MAX_STEP];
  38.     int cut_count;
  39.     int node_count;
  40.     int ans_max_eval;
  41.     int step_count[MAX_STEP];
  42.     int ans_step_count[MAX_ANS_STEP];
  43.     struct nodeT* step_p[MAX_STEP];
  44.     struct nodeT* ans_step_p[MAX_ANS_STEP];
  45.     struct problemT* next;
  46.     struct problemT* prev;
  47. } problemT;
  48.  
  49. typedef struct nodeT
  50. {
  51.     int current; // 現在の空白の位置
  52.     char* data; // 現在のパターン
  53.     struct nodeT* next; // 次のパターン
  54.     struct nodeT* prev; // どのパターンから生成されたか?
  55.     int evalvalue; // 評価値
  56.     char dir; // どの方向に空白が移動したか?
  57.     char flag; // フラグ
  58. } nodeT;
  59.  
  60. static const char dirChar[4] = {'L', 'R', 'U', 'D'};
  61. static const char revDir[4] = {1, 0, 3, 2};
  62.  
  63. enum {
  64.     FLAG_SKIP = 1,
  65.     FLAG_DELETE = 2
  66. };
  67.  
  68. static int dump_swap_data(problemT* p)
  69. {
  70.     int i, c;
  71.     c = 0;
  72.     for(i=0; i<(p->h * p->w); i++){
  73.         printf("%d: %d %d %d %d\n", i,
  74.             p->swap_data[c], p->swap_data[c+1],
  75.             p->swap_data[c+2], p->swap_data[c+3]);
  76.         c += 4;
  77.     }
  78. }
  79.  
  80. static void dump_problem(problemT* p)
  81. {
  82.     printf("%p data:%s goal:%s\n", p, p->data, p->goal);
  83. }
  84.  
  85. static void dump_datas(nodeT* p)
  86. {
  87.     while(p){
  88.         printf("%p %s: %d(%p) %d %d\n", p, p->data, p->dir, p->prev, p->flag, p->evalvalue);
  89.         p = p->next;
  90.     }
  91. }
  92.  
  93. /*
  94.  * 解答の計算
  95.  */
  96. static int create_answer(problemT* p)
  97. {
  98.     int i;
  99.     int ch = '1';
  100.     char* data = (char*)malloc(p->h * p->w + 1);
  101.     memset(data, 0, sizeof(p->h * p->w + 1));
  102.     memset(p->posChar, -1, sizeof(p->posChar));
  103.     memset(p->valChar, 0, sizeof(p->valChar));
  104.  
  105.     for(i=0; i<p->h * p->w;){
  106.         if(ch == '9' + 1) ch = 'A';
  107.         if(strchr(p->data, ch)) {
  108.             p->posChar[ch] = i;
  109.             p->valChar[i] = ch;
  110.             data[i] = ch;
  111.         } else {
  112.             if((p->wall & (1LL << i))){
  113.                 data[i] = '=';
  114.             } else {
  115.                 ch++;
  116.                 continue;
  117.             }
  118.         }
  119.         ch++;
  120.         i++;
  121.     }
  122.     data[p->h * p->w -1] = '0';
  123.     p->posChar['0'] = p->h * p->w - 1;
  124.     p->valChar[p->h * p->w - 1] = '0';
  125.     data[p->h * p->w] = '\0';
  126.  
  127.     p->goal = data;
  128.     return 0;
  129. }
  130.  
  131. /*
  132.  * 置換座標の計算
  133.  */
  134. static int create_swap_data(problemT* p)
  135. {
  136.     int c, i, j;
  137.  
  138.     if(p->swap_data) {
  139.         free(p->swap_data);
  140.     }
  141.  
  142.     p->swap_data = (int*)malloc(sizeof(int) * 4 * p->h * p->w);
  143.     memset(p->swap_data, -1, sizeof(int) * 4 * p->h * p->w);
  144.  
  145.     c = 0;
  146.     for(i=0; i<p->h; i++){
  147.         for(j=0; j<p->w; j++){
  148.             int c2;
  149.             c2 = c * 4;
  150.             if(p->wall & (1LL << c)){
  151.                 c++;
  152.                 continue;
  153.             }
  154.             // L
  155.             if(j != 0) {
  156.                 if(!(p->wall & (1LL << (c - 1))))
  157.                     p->swap_data[c2] = c - 1;
  158.             }
  159.             // R
  160.             if(j != p->w-1) {
  161.                 if(!(p->wall & (1LL << (c + 1))))
  162.                     p->swap_data[c2+1] = c + 1;
  163.             }
  164.             // U
  165.             if(i != 0) {
  166.                 if(!(p->wall & (1LL << (c - p->w))))
  167.                     p->swap_data[c2+2] = c - p->w;
  168.             }
  169.             // D
  170.             if(i != p->h-1) {
  171.                 if(!(p->wall & (1LL << (c + p->w))))
  172.                     p->swap_data[c2+3] = c + p->w;
  173.             }
  174.             c++;
  175.         }
  176.     }
  177.     return 0;
  178. }
  179.  
  180. /*
  181.  * 問題文字列のパース
  182.  */
  183. static int parse_problem(const char* line, problemT** p)
  184. {
  185.     const char* s = line;
  186.     const char* s2;
  187.     const char* s3;
  188.     int h, w;
  189.     w = strtoul(s, 0, 10);
  190.     s = strchr(s, ',');
  191.     if( !s ) return -1;
  192.     h = strtoul(s + 1, 0, 10);
  193.     s = strchr(s + 1, ',');
  194.     if( !s ) return -1;
  195.     s++;
  196.  
  197.     if((h < 2) || (w < 2)) {
  198.         fprintf(stderr, "*** problem too small error (%d, %d)\n", h, w);
  199.         return -1;
  200.     }
  201.  
  202.     *p = (problemT*)malloc(sizeof(problemT));
  203.     if(!*p) {
  204.         fprintf(stderr, "*** malloc error (%s:%d)\n", __FUNCTION__, __LINE__);
  205.         return -1;
  206.     }
  207.     memset(*p, 0, sizeof(problemT));
  208.     (*p)->w = w;
  209.     (*p)->h = h;
  210.     (*p)->data = strdup(s);
  211.     (*p)->data[w*h] = '\0';
  212.     if(strchr((*p)->data, ',') || !strchr((*p)->data, '0')) {
  213.         fprintf(stderr, "*** problem parse error (%s)\n", (*p)->data);
  214.         free((*p)->data);
  215.         free((*p));
  216.         (*p) = 0;
  217.         return -1;
  218.     }
  219.  
  220.     (*p)->wall = 0;
  221.     s3 = s;
  222.     while(0 != (s2 = strchr(s, '='))){
  223.         int b;
  224.         b = s2 - s3;
  225.         s = s2 + 1;
  226.         (*p)->wall |= 1LL << b;
  227.     }
  228.     return 0;
  229. }
  230.  
  231. static int delete_node(nodeT* p)
  232. {
  233.     if(!p) return -1;
  234.     free(p->data);
  235.     free(p);
  236.     return 0;
  237. }
  238.  
  239. static int delete_problem(problemT* p)
  240. {
  241.     int i;
  242.     if(!p) return -1;
  243.     if(p->sequence) free(p->sequence);
  244.     if(p->data) free(p->data);
  245.     if(p->swap_data) free(p->swap_data);
  246.     if(p->goal) free(p->goal);
  247.  
  248.     for(i=0; i<MAX_STEP; i++){
  249.         if(p->step_count[i]){
  250.             nodeT* p2 = p->step_p[i];
  251.             while(p2){
  252.                 nodeT* p3;
  253.                 p3 = p2;
  254.                 p2 = p2->next;
  255.                 delete_node(p3);
  256.             }
  257.         }
  258.     }
  259.     for(i=0; i<MAX_ANS_STEP; i++){
  260.         if(p->ans_step_count[i]){
  261.             nodeT* p2 = p->ans_step_p[i];
  262.             while(p2){
  263.                 nodeT* p3;
  264.                 p3 = p2;
  265.                 p2 = p2->next;
  266.                 delete_node(p3);
  267.             }
  268.         }
  269.     }
  270.     free(p);
  271.     return 0;
  272. }
  273.  
  274. /*
  275.  * 解答文字列のパース
  276.  */
  277. static int parse_answer(const char* line, problemT** p)
  278. {
  279.     const char* s = line;
  280.     const char* s2;
  281.     const char* s3;
  282.     const char* s4;
  283.     char* ch;
  284.     int h, w;
  285.     w = strtoul(s, 0, 10);
  286.     s = strchr(s, ',');
  287.     if( !s ) return -1;
  288.     h = strtoul(s + 1, 0, 10);
  289.     s = strchr(s + 1, ',');
  290.     if( !s ) return -1;
  291.     s++;
  292.  
  293.     if((h < 2) || (w < 2)) {
  294.         fprintf(stderr, "*** answer too small error (%d, %d)\n", h, w);
  295.         return -1;
  296.     }
  297.  
  298.     *p = (problemT*)malloc(sizeof(problemT));
  299.     if(!*p) {
  300.         fprintf(stderr, "*** malloc error (%s:%d)\n", __FUNCTION__, __LINE__);
  301.         return -1;
  302.     }
  303.     memset(*p, 0, sizeof(problemT));
  304.     (*p)->w = w;
  305.     (*p)->h = h;
  306.     (*p)->data = strdup(s);
  307.     (*p)->data[w*h] = '\0';
  308.     if(strchr((*p)->data, ',') || !strchr((*p)->data, '0')) {
  309.         fprintf(stderr, "*** problem parse error (%s)\n", (*p)->data);
  310.         free((*p)->data);
  311.         free((*p));
  312.         (*p) = 0;
  313.         return -1;
  314.     }
  315.  
  316.     s4 = strchr(s + 1, ',');
  317.     if( !s4 ) {
  318.         fprintf(stderr, "*** answer need sequence error\n");
  319.         free((*p)->data);
  320.         free((*p));
  321.         (*p) = 0;
  322.         return -1;
  323.     }
  324.     (*p)->sequence = strdup(s4 + 1);
  325.     ch = strchr((*p)->sequence, ',');
  326.     if(ch) *ch = '\0';
  327.     ch = strchr((*p)->sequence, '\r');
  328.     if(ch) *ch = '\0';
  329.     ch = strchr((*p)->sequence, '\n');
  330.     if(ch) *ch = '\0';
  331.  
  332. //  fprintf(stderr, "*** sequence=%s\n", (*p)->sequence);
  333.  
  334.     (*p)->wall = 0;
  335.     s3 = s;
  336.     while(0 != (s2 = strchr(s, '='))){
  337.         int b;
  338.         b = s2 - s3;
  339.         s = s2 + 1;
  340.         (*p)->wall |= 1LL << b;
  341.     }
  342.     return 0;
  343. }
  344.  
  345. static create_eval_data(problemT* p)
  346. {
  347.     int i;
  348.     for(i=0; i<p->w*p->h; i++){
  349.         p->eval_data[i] = (int*)malloc(sizeof(int) * p->w * p->h);
  350.     }
  351.  
  352.     // select num
  353.     for(i=0; i<p->w*p->h; i++){
  354.         int j;
  355.         int val, changed;
  356.         for(j=0; j<p->w*p->h; j++){
  357.             p->eval_data[i][j] = -1;
  358.         }
  359.  
  360.         // select pos
  361.         p->eval_data[i][i] = 0;
  362.         val = 0;
  363.         changed = 1;
  364.         while(changed){
  365.             changed = 0;
  366.             for(j=0; j<p->w*p->h; j++){
  367.                 if(p->eval_data[i][j] == val) {
  368.                     int d, k;
  369.                     for(d=0; d<4; d++){
  370.                         k = p->swap_data[j * 4 + d];
  371.                         if((k >= 0) && (p->eval_data[i][k] == -1)) {
  372.                             p->eval_data[i][k] = val + 1;
  373.                             changed = 1;
  374.                         }
  375.                     }
  376.                 }
  377.             }
  378.             val++;
  379.         }
  380.     }
  381. }
  382.  
  383. static int dump_eval_data(problemT* p)
  384. {
  385.     int i,j;
  386.     for(i=0; i<p->w*p->h; i++){
  387.         fprintf(stderr, "=== eval_data[%d] : ", i);
  388.         for(j=0; j<p->w*p->h; j++){
  389.             fprintf(stderr, "%d ", p->eval_data[i][j]);
  390.         }
  391.         fprintf(stderr, "\n");
  392.     }
  393. }
  394.  
  395. /* 距離の2乗 , 答え空白位置からの距離 * 距離*/
  396. static int eval_value(problemT *p, nodeT *np)
  397. {
  398.     int i;
  399.     int num;
  400.     np->evalvalue = 0;
  401.     for(i=0; i<p->w*p->h; i++){
  402.         int v;
  403.         num = p->posChar[np->data[i]];
  404.         if(np->data[i] == '0') continue;
  405.         if(np->data[i] == '=') continue;
  406.         v = p->eval_data[num][i];
  407. //      fprintf(stderr, "%s i=%d d=%d v=%d eval=%d\n", np->data, i, num, v, v*v);
  408.         if(v > 0) {
  409.             np->evalvalue += v * v;
  410.         }
  411.     }
  412.  
  413.     return 0;
  414. }
  415.  
  416. static __inline__ void swap_byte(char* data, int i, int j)
  417. {
  418.     char ch;
  419.     ch = data[i];
  420.     data[i] = data[j];
  421.     data[j] = ch;
  422. }
  423.  
  424. static void print_sequence(nodeT* p, nodeT* p2)
  425. {
  426.     char ans[MAX_STEP+MAX_ANS_STEP+1] = {0};
  427.     nodeT* p3;
  428.     int ans_i = 0;
  429.     int i;
  430.  
  431.     p3 = p;
  432.     while(p3){
  433.         if(!p3->prev) break;
  434. //      printf("%p %s: %d(%p) %d %d\n", p3, p3->data, p3->dir, p3->prev, p3->flag, p3->evalvalue);
  435.         ans[ans_i++] = dirChar[p3->dir];
  436.         p3 = p3->prev;
  437.     }
  438.     for(i=0; i<ans_i; i++){
  439.         fprintf(stderr, "%c", ans[ans_i - i -1]);
  440.     }
  441.  
  442.     p3 = p2;
  443.     while(p3){
  444.         fprintf(stderr, "%c", dirChar[revDir[p3->dir]]);
  445.         p3 = p3->prev;
  446.     }
  447. }
  448.  
  449. static void print_answer(problemT* pp, nodeT* p, nodeT* p2)
  450. {
  451.     int dir[4] = {0};
  452.     nodeT* p3;
  453.     int i;
  454.     char ans[1000] = {0};
  455.     int ans_i = 0;
  456.  
  457.     fprintf(stderr, "*** %s(%p, %p)\n", __FUNCTION__, p, p2);
  458.     fprintf(stdout,"%d,%d,%s,", pp->w, pp->h, pp->data);
  459.  
  460. #if 0
  461.     p3 = p2;
  462.     while(p3){
  463.         fprintf(stderr, "%s(%d)\n", p3->data, p3->evalvalue);
  464.         p3 = p3->prev;
  465.     }
  466.  
  467.     p3 = p;
  468.     while(p3){
  469.         fprintf(stderr, "%s(%d)\n", p3->data, p3->evalvalue);
  470.         p3 = p3->prev;
  471.     }
  472. #endif
  473.  
  474.     p3 = p;
  475.     while(p3->prev){
  476.         ans[ans_i++] = dirChar[p3->dir];
  477.         dir[p3->dir]++;
  478.         p3 = p3->prev;
  479.     }
  480.     for(i=0; i<ans_i; i++){
  481.         fprintf(stdout, "%c", ans[ans_i - i -1]);
  482.     }
  483.  
  484.     p3 = p2;
  485.     while(p3->prev){
  486.         fprintf(stdout, "%c", dirChar[revDir[p3->dir]]);
  487.         dir[revDir[p3->dir]]++;
  488.         p3 = p3->prev;
  489.     }
  490.  
  491.     fprintf(stdout,",%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
  492.         dir[0], dir[1], dir[2], dir[3], p->evalvalue,
  493.         pp->node_count, pp->cut_count, CUT_DETECT_NUM, CUT_REMAIN_NUM,
  494.         dir[0] + dir[1] + dir[2] + dir[3]);
  495. }
  496.  
  497. static nodeT* create_node(problemT* pp)
  498. {
  499.     nodeT* p;
  500.     p = (nodeT*)malloc(sizeof(nodeT));
  501.     memset(p, 0, sizeof(nodeT));
  502.     p->data = strdup(pp->data);
  503.     {
  504.         const char* s =  strchr(p->data, '0');
  505.         p->current = s - p->data;
  506. //      fprintf(stderr, "current=%d\n", p->current);
  507.     }
  508.     return p;
  509. }
  510.  
  511. static nodeT* create_node_answer(problemT* pp)
  512. {
  513.     nodeT* p;
  514.     p = (nodeT*)malloc(sizeof(nodeT));
  515.     memset(p, 0, sizeof(nodeT));
  516.     p->data = strdup(pp->goal);
  517.     {
  518.         const char* s =  strchr(p->data, '0');
  519.         p->current = s - p->data;
  520. //      fprintf(stderr, "current=%d\n", p->current);
  521.     }
  522.     return p;
  523. }
  524.  
  525. static nodeT* create_node_step(problemT* pp, nodeT* p, int c)
  526. {
  527.     int i, j;
  528.     nodeT* p2;
  529.     char* data;
  530.  
  531. //  fprintf(stderr, "%s: %p %p %c\n", __FUNCTION__, pp, p, dirChar[c]);
  532.  
  533.     i = p->current;
  534.     j = pp->swap_data[i * 4 + c];
  535. //  fprintf(stderr, "current=%d next=%d\n", i, j);
  536.     if(j < 0) return 0;
  537.  
  538.     data = strdup(p->data);
  539.     swap_byte(data, i, j);
  540.  
  541.     p2 = (nodeT*)malloc(sizeof(nodeT));
  542.     memset(p2, 0, sizeof(nodeT));
  543.     p2->data = data;
  544.     p2->current = j;
  545.     p2->dir = c;
  546.     p2->prev = p;
  547.  
  548.     return p2;
  549. }
  550.  
  551. static int next_steps(problemT*pp, int step)
  552. {
  553.     nodeT* p = pp->step_p[step-1];
  554.  
  555.     while(p) {
  556.         int d;
  557.  
  558.         if(p->flag & FLAG_SKIP){
  559.             p = p->next;
  560.             continue;
  561.         }
  562.  
  563.         for(d=0; d<4; d++){
  564.             nodeT* p2;
  565.             p2 = create_node_step(pp, p, d);
  566.             if(p2) {
  567.                 int step2 = step - 2;
  568.                 eval_value(pp, p2);
  569.                 if(p2->evalvalue > pp->step_max_eval[step]) {
  570.                     pp->step_max_eval[step] = p2->evalvalue;
  571.                 }
  572.                 /* 同じパターン 検知 */
  573.                 while(step2 >= 0 && p2){
  574.                     nodeT* p3 = pp->step_p[step2];
  575.                     while(p3) {
  576.                         if((p2->evalvalue == p3->evalvalue) && !strcmp(p3->data, p2->data)){
  577.                             delete_node(p2);
  578.                             p2 = 0;
  579.                             break;
  580.                         }
  581.                         p3 = p3->next;
  582.                     }
  583.                     step2 -= 2;
  584. //                  if(pp->cut_count) break;
  585.                 }
  586.             }
  587.             if(p2) {
  588.                 pp->node_count++;
  589.                 /* リストへの挿入時に評価値の低い順にソートしておく */
  590.                 if(pp->step_p[step] == 0){
  591.                     p2->next = pp->step_p[step];
  592.                     pp->step_p[step] = p2;
  593.                 } else {
  594.                     nodeT* p3 = pp->step_p[step];
  595.                     nodeT* p3prev = 0;
  596.                     while(p3){
  597.                         if(p3->evalvalue >= p2->evalvalue){
  598.                             if(p3prev == 0){
  599.                                 p2->next = p3;
  600.                                 pp->step_p[step] = p2;
  601.                             } else {
  602.                                 p3prev->next = p2;
  603.                                 p2->next = p3;
  604.                             }
  605.                             break;
  606.                         }
  607.                         p3prev = p3;
  608.                         p3 = p3->next;
  609.                     }
  610.                     if(!p3){
  611.                         p3prev->next = p2;
  612.                     }
  613.                 }
  614.                 pp->step_count[step]++;
  615.             }
  616.         }
  617.         p = p->next;
  618.     }
  619.     return 0;
  620. }
  621.  
  622. static int next_ans_steps(problemT*pp, int step)
  623. {
  624.     nodeT* p = pp->ans_step_p[step-1];
  625.  
  626.     while(p) {
  627.         int d;
  628.         for(d=0; d<4; d++){
  629.             nodeT* p2;
  630.             p2 = create_node_step(pp, p, d);
  631.             if(p2) {
  632.                 int step2 = step - 2;
  633.                 eval_value(pp, p2);
  634.                 if(p2->evalvalue > pp->ans_max_eval) {
  635.                     pp->ans_max_eval = p2->evalvalue;
  636.                 }
  637.                 /* 同じパターン 検知 */
  638.                 while(step2 >= 0 && p2){
  639.                     nodeT* p3 = pp->ans_step_p[step2];
  640.                     while(p3) {
  641.                         if((p3->evalvalue == p2->evalvalue) && !strcmp(p3->data, p2->data)){
  642.                             delete_node(p2);
  643.                             p2 = 0;
  644.                             break;
  645.                         }
  646.                         p3 = p3->next;
  647.                     }
  648.                     step2 -= 2;
  649.                 }
  650.             }
  651.             if(p2) {
  652.                 pp->node_count++;
  653.                 p2->next = pp->ans_step_p[step];
  654.                 pp->ans_step_p[step] = p2;
  655.                 pp->ans_step_count[step]++;
  656.             }
  657.         }
  658.         p = p->next;
  659.     }
  660.     return 0;
  661. }
  662.  
  663. static int cut_datas(problemT*pp, int step)
  664. {
  665.     nodeT* p;
  666.     int i;
  667.  
  668.     /* とりあえずdeleteフラグを立てておく */
  669.     for(i=0; i<step; i++){
  670.         p = pp->step_p[i];
  671.         while(p){
  672.             p->flag |= FLAG_DELETE;
  673.             p = p->next;
  674.         }
  675.     }
  676.  
  677.     p = pp->step_p[step];
  678.     for(i=0; i< CUT_REMAIN_NUM; i++){
  679.         nodeT* prev;
  680.         prev = p->prev;
  681.         while(prev){
  682.             prev->flag &= ~FLAG_DELETE;
  683.             prev = prev->prev;
  684.         }
  685.         p=p->next;
  686.     }
  687.  
  688.     while(p){
  689.         p->flag |= FLAG_SKIP;
  690.         p = p->next;
  691.     }
  692.  
  693.     for(i=0; i<step; i++){
  694.         p = pp->step_p[i];
  695. //      fprintf(stderr, "*** step=%d\n", i);
  696. //      dump_datas(p);
  697.         while(p->next){
  698.             if(p->next->flag & FLAG_DELETE){
  699.                 nodeT* p2;
  700.                 p2 = p->next;
  701.                 p->next = p->next->next;
  702.                 free(p2->data);
  703.                 free(p2);
  704.                 continue;
  705.             }
  706.             p = p->next;
  707.         }
  708.     }
  709.  
  710.     pp->step_count[step] = CUT_REMAIN_NUM;
  711.     pp->cut_count++;
  712.     return 0;
  713. }
  714.  
  715. /*
  716.  *  解等算出
  717.  */
  718. static int solver_main(const char* line)
  719. {
  720.     int ret;
  721.     int step, ans_step;
  722.     problemT* problem;
  723.     nodeT* p;
  724.     nodeT* p2;
  725.     ret = parse_problem(line, &problem);
  726.     if (ret < 0) return ret;
  727.     problem->cut_count = 0;
  728.     problem->node_count = 0;
  729.     problem->ans_max_eval = 0;
  730.  
  731.     create_swap_data(problem);
  732. //  dump_swap_data(problem);
  733.     create_eval_data(problem);
  734. //  dump_eval_data(problem);
  735.  
  736.     create_answer(problem);
  737. //  dump_problem(problem);
  738.  
  739.     p = create_node(problem);
  740.     p2 = create_node_answer(problem);
  741.     eval_value(problem, p);
  742.     eval_value(problem, p2);
  743.  
  744.     fprintf(stderr,"*** %d,%d,%s,%s,%d\n",
  745.         problem->w, problem->h, problem->data, problem->goal, p->evalvalue);
  746.  
  747.     problem->found_answer = 0;
  748.     problem->step_p[0] = p;
  749.     problem->step_count[0] = 1;
  750.     problem->ans_step_p[0] = p2;
  751.     problem->ans_step_count[0] = 1;
  752.     ans_step = 0;
  753.     step = 0;
  754.  
  755.     while(0 == problem->found_answer){
  756.         if(problem->ans_step_count[ans_step] < problem->step_count[step]){
  757.             nodeT* p;
  758.             ans_step++;
  759.             next_ans_steps(problem, ans_step);
  760.             fprintf(stderr, "*** ans[%d] count=%d eval=%d\n",
  761.                 ans_step, problem->ans_step_count[ans_step], problem->ans_max_eval);
  762.             p = problem->ans_step_p[ans_step];
  763. //          dump_datas(problem->ans_step_p[ans_step]);
  764.             while(p){
  765.                 int i;
  766.                 for(i=step; i>=step-1; i--){
  767.                     nodeT* p2 = problem->step_p[i];
  768.                     while(p2){
  769.                         if(problem->ans_max_eval < p2->evalvalue) {
  770.                             break;
  771.                         }
  772.                         if((p->evalvalue == p2->evalvalue) && !strcmp(p->data, p2->data)){ 
  773.                             print_answer(problem, p2, p);
  774.                             problem->found_answer++;
  775.                         }
  776.                         p2 = p2->next;
  777.                     }
  778.                 }
  779.                 p = p->next;
  780.             }
  781.         } else {
  782.             nodeT* p;
  783.             step++;
  784.             next_steps(problem, step);
  785.             p = problem->step_p[step];
  786.  
  787.             while(1){
  788.                 fprintf(stderr, "*** step[%d] count=%d eval=%d,%d(%s)",
  789.                     step, problem->step_count[step], p->evalvalue, problem->step_max_eval[step], p->data);
  790.                 print_sequence(p, 0);
  791.                 fprintf(stderr, "\n");
  792.                 if(!p->next) break;
  793.                 if(p->evalvalue != p->next->evalvalue) break;
  794.                 p = p->next;
  795.             }
  796.  
  797.             p = problem->step_p[step];
  798. //          dump_datas(problem->step_p[step]);
  799.             while(p){
  800.                 nodeT* p2 = problem->ans_step_p[ans_step];
  801.                 if(problem->ans_max_eval < p->evalvalue) {
  802.                     break;
  803.                 }
  804.                 while(p2){
  805.                     if((p->evalvalue == p2->evalvalue) && !strcmp(p->data, p2->data)){ 
  806.                         print_answer(problem, p, p2);
  807.                         problem->found_answer++;
  808.                     }
  809.                     p2 = p2->next;
  810.                 }
  811.                 p = p->next;
  812.             }
  813.         }
  814.         if(problem->found_answer) break;
  815. #if 0
  816.         if(problem->ans_step_count[step] > CUT_DETECT_NUM) {
  817.             fprintf(stderr, "*** cut ansdata count=%d\n", problem->ans_step_count[step]);
  818.             cut_ans_datas(step);
  819.         }
  820. #endif
  821. #if 1
  822.         if(problem->step_count[step] > CUT_DETECT_NUM) {
  823.             fprintf(stderr, "*** cutdata count=%d\n", problem->step_count[step]);
  824.             cut_datas(problem, step);
  825. //          dump_datas(problem->step_p[step]);
  826. //          break;
  827.         }
  828. #endif
  829.     }
  830.  
  831.     delete_problem(problem);
  832.  
  833.     return 0;
  834. }
  835.  
  836. /*
  837.  *  解等チェック
  838.  */
  839. static int checkans_main(const char* line)
  840. {
  841.     int ret;
  842.     int step;
  843.     problemT* problem;
  844.     nodeT* p;
  845.     ret = parse_answer(line, &problem);
  846.     if (ret < 0) {
  847.         printf("### parse error %s\n", line);
  848.         return ret;
  849.     }
  850.  
  851.     create_swap_data(problem);
  852. //  dump_swap_data(problem);
  853.  
  854.     create_answer(problem);
  855. //  dump_problem(problem);
  856.  
  857.     fprintf(stderr,"*** %d,%d,\"%s\",\"%s\",\"%s\"\n",
  858.         problem->w, problem->h, problem->data, problem->goal, problem->sequence);
  859.  
  860.     p = create_node(problem);
  861. //  dump_datas(p);
  862.  
  863.     step = 0;
  864.     while(problem->sequence[step] != 0){
  865.         switch(problem->sequence[step]){
  866.         case 'L':
  867.             p = create_node_step(problem, p, 0);
  868.             break;
  869.         case 'R':
  870.             p = create_node_step(problem, p, 1);
  871.             break;
  872.         case 'U':
  873.             p = create_node_step(problem, p, 2);
  874.             break;
  875.         case 'D':
  876.             p = create_node_step(problem, p, 3);
  877.             break;
  878.         default:
  879.             fprintf(stdout, "### sequence error %s,%s\n",
  880.                 problem->data, problem->sequence);
  881.             ret = -1;
  882.             goto err;
  883.         }
  884.         if(p == 0) {
  885.             fprintf(stdout, "### sequence error %s,%s\n",
  886.                 problem->data, problem->sequence);
  887.             ret = -1;
  888.             goto err;
  889.         }
  890.         step++;
  891.     }
  892.     if(strcmp(p->data, problem->goal)){
  893.         fprintf(stdout, "### NG %s,%s: %s(%s)\n",
  894.             problem->data, problem->sequence, p->data, problem->goal);
  895.         ret = -1;
  896.         goto err;
  897.     }
  898.  
  899. err:
  900.     while(p) {
  901.         nodeT* p2 = p;
  902.         p = p->prev;
  903.         delete_node(p2);
  904.     }
  905.     delete_problem(problem);
  906.     return ret;
  907. }
  908.  
  909. static int checkans(int argc, const char** argv)
  910. {
  911.     if(argc < 1) return -1;
  912.     if(strcmp(argv[1], "-")){
  913.         return checkans_main(argv[1]);
  914.     }
  915.     {
  916.         char line[1024];
  917.         while(fgets(line, 1024, stdin) != 0){
  918.             checkans_main(line);
  919.         }
  920.     }
  921.     return 0;
  922. }
  923.  
  924. static int solver(int argc, const char** argv)
  925. {
  926.     if(argc < 1) return -1;
  927.     if(strcmp(argv[1], "-")){
  928.         return solver_main(argv[1]);
  929.     }
  930.     {
  931.         char line[1024];
  932.         while(fgets(line, 1024, stdin) != 0){
  933.             solver_main(line);
  934.         }
  935.     }
  936.     return 0;
  937. }
  938.  
  939. /*
  940.  *  回答提出用整形
  941.  */
  942. static int sumans(int argc, const char** argv)
  943. {
  944.     int ret;
  945.     problemT* problem = 0;
  946.     problemT* p;
  947.     problemT* p2;
  948.     char line[1024];
  949.     int count = 0;
  950.     int sum[4] = {0};
  951.     int summax[4] = {0};
  952.     int countmax = 0;
  953.     const char* s;
  954.     FILE*fp;
  955.     FILE*fp2;
  956.     int i;
  957.  
  958.     fp2 = fopen(argv[2], "r");
  959.     if(!fp2) return -1;
  960.  
  961.     fgets(line, 1024, fp2);
  962. //  fprintf(stderr, "*** line = %s\n", line);
  963.     s = line;
  964.     summax[0] = strtoul(s, 0, 10);
  965.     s = strchr(s, ' ');
  966.     if( !s ) return -1;
  967.     summax[1] = strtoul(s+1, 0, 10);
  968.     s = strchr(s+1, ' ');
  969.     if( !s ) return -1;
  970.     summax[2] = strtoul(s+1, 0, 10);
  971.     s = strchr(s+1, ' ');
  972.     if( !s ) return -1;
  973.     summax[3] = strtoul(s+1, 0, 10);
  974.     fgets(line, 1024, fp2);
  975. //  fprintf(stderr, "*** line = %s\n", line);
  976.     s = line;
  977.     countmax = strtoul(s, 0, 10);
  978.     fprintf(stderr, "*** max LRUD={%d,%d,%d,%d}\n", summax[0], summax[1], summax[2], summax[3]);
  979.     fprintf(stderr, "*** max count=%d\n", countmax);
  980.  
  981.     fp = fopen(argv[1], "r");
  982.     if(!fp) return -1;
  983.  
  984.     while(fgets(line, 1024, fp) != 0){
  985.         ret = parse_answer(line, &p);
  986.         if(ret < 0) continue;
  987.         if(problem && !strcmp(problem->data, p->data)){
  988.             //printf("skip %s\n", p->data);
  989.             free(p->data);
  990.             free(p->sequence);
  991.             free(p);
  992.             continue;
  993.         }
  994.         p->next = problem;
  995.         problem = p;
  996.         count++;
  997.         for(i=0; p->sequence[i]; i++){
  998.             switch(p->sequence[i]){
  999.             case 'L':
  1000.                 sum[0]++;
  1001.                 break;
  1002.             case 'R':
  1003.                 sum[1]++;
  1004.                 break;
  1005.             case 'U':
  1006.                 sum[2]++;
  1007.                 break;
  1008.             case 'D':
  1009.                 sum[3]++;
  1010.                 break;
  1011.             }
  1012.         }
  1013.     }
  1014.     fprintf(stderr, "*** count=%d sum=(%d,%d,%d,%d)\n", count, sum[0], sum[1], sum[2], sum[3]);
  1015.     if(count > countmax) {
  1016.         fprintf(stderr, "*** count error\n");
  1017.         return -1;
  1018.     }
  1019.     for(i=0; i<4; i++){
  1020.         if(sum[i] > summax[i]) {
  1021.             fprintf(stderr, "*** LRUD limit error\n");
  1022.             return -1;
  1023.         }
  1024.     }
  1025.  
  1026.     for(i=0; i<countmax; i++){
  1027.         fgets(line, 1024, fp2);
  1028.         ret = parse_problem(line, &p2);
  1029.         p = problem;
  1030.         while(p){
  1031.             if(!strcmp(p2->data, p->data)){
  1032.                 fprintf(stdout, "%s\r\n", p->sequence);
  1033.                 break;
  1034.             }
  1035.             p = p->next;
  1036.         }
  1037.         if(!p){
  1038.             fprintf(stdout, "\r\n");
  1039.         }
  1040.     }
  1041.     return 0;
  1042. }
  1043.  
  1044. int main(int argc, const char** argv)
  1045. {
  1046.     if(strstr(argv[0], "solver"))
  1047.         return solver(argc, argv);
  1048.     if(strstr(argv[0], "checkans"))
  1049.         return checkans(argc, argv);
  1050.     if(strstr(argv[0], "sumans"))
  1051.         return sumans(argc, argv);
  1052. }
Advertisement
Add Comment
Please, Sign In to add comment