免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3461 | 回复: 9
打印 上一主题 下一主题

图灵机 [复制链接]

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-13 13:22 |只看该作者 |倒序浏览
本帖最后由 cjaizss 于 2012-11-14 20:42 编辑
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>

  5. int *tape;
  6. int tape_len;
  7. int tape_pos=0;
  8. #ifdef START
  9. #undef START
  10. #endif
  11. #ifdef ACCEPT
  12. #undef ACCEPT
  13. #endif
  14. #ifdef REJECT
  15. #undef REJECT
  16. #endif
  17. #ifdef BLANK
  18. #undef BLANK
  19. #endif
  20. #define START 0
  21. #define ACCEPT 1
  22. #define REJECT 2
  23. #define BLANK 0
  24. int stat = START;
  25. int max_stat = 3;/*:0:start,1:accept,2:reject,3~max_stat*/
  26. int max_char = 1;/*0:balnk,1~max_char*/
  27. typedef struct {
  28.         int stat_now;
  29.         int char_now;
  30.         int stat_next;
  31.         int char_next;
  32.         int dir;/*0:tape_pos--,else:tape_pos++*/
  33. } rule_t;
  34. rule_t *rule;
  35. int rule_len;

  36. static void init_turing(const char* program)
  37. {
  38.         FILE* f;
  39.         char s[100];
  40.         char s2[100];
  41.         int rule_alloc_len;

  42.         tape_len = 1024*1024;
  43.         tape = (int*)malloc(sizeof(*tape)*tape_len);
  44.         rule_len = 0;
  45.         rule_alloc_len = 100;
  46.         rule = (rule_t*)malloc(sizeof(rule_t)*rule_alloc_len);
  47.         f = fopen(program,"r");
  48.         while(1) {
  49.                 if(fgets(s,sizeof(s),f)==NULL)
  50.                         break;
  51.                 if(sscanf(s,"%s",s2)!=1)
  52.                         continue;
  53.                 if(strcmp(s2,"tape_len")==0) {
  54.                         sscanf(s,"%s%d",s2,&tape_len);
  55.                         tape = (int*)realloc(tape,sizeof(*tape)*tape_len);
  56.                         continue;
  57.                 }
  58.                 if(strcmp(s2,"max_stat")==0) {
  59.                         sscanf(s,"%s%d",s2,&max_stat);
  60.                         assert(max_stat>REJECT);
  61.                         continue;
  62.                 }
  63.                 if(strcmp(s2,"max_char")==0) {
  64.                         sscanf(s,"%s%d",s2,&max_char);
  65.                         assert(max_char>BLANK);
  66.                         continue;
  67.                 }
  68.                 if(sscanf(s,"%d%d%d%d%d",
  69.                                         &rule[rule_len].stat_now,
  70.                                         &rule[rule_len].char_now,
  71.                                         &rule[rule_len].stat_next,
  72.                                         &rule[rule_len].char_next,
  73.                                         &rule[rule_len].dir) == 5) {
  74.                         if(max_char < rule[rule_len].char_now)
  75.                                 max_char = rule[rule_len].char_now;
  76.                         if(max_char < rule[rule_len].char_next)
  77.                                 max_char = rule[rule_len].char_next;
  78.                         if(max_stat < rule[rule_len].stat_now)
  79.                                 max_stat = rule[rule_len].stat_now;
  80.                         if(max_stat < rule[rule_len].stat_next)
  81.                                 max_stat = rule[rule_len].stat_next;
  82.                         rule_len++;
  83.                         if(rule_len >= rule_alloc_len) {
  84.                                 rule_alloc_len += 100;
  85.                                 rule = (rule_t*)realloc(rule,sizeof(rule_t)*rule_alloc_len);
  86.                         }
  87.                 }

  88.         }

  89.         rule = (rule_t*)realloc(rule,sizeof(rule_t)*rule_len);
  90.         fclose(f);
  91. }

  92. static void init_tape(void)
  93. {
  94.         int i;
  95.         int x;

  96.         memset(tape,0,sizeof(int)*tape_len);
  97.         i=0;
  98.         while(1) {
  99.                 if(scanf("%d",&x)!=1)
  100.                         break;
  101.                 if(x<0||x>max_char)
  102.                         fprintf(stderr,"%s:%d:input error",__FILE__,__LINE__);
  103.                 else
  104.                         tape[i++]=x;
  105.         }
  106. }

  107. static int work_turing(void)
  108. {
  109.         int i;

  110.         init_tape();
  111.         while(1) {
  112.                 for(i=0;i<rule_len;i++)
  113.                         if((rule[i].stat_now == stat)
  114.                                         && (rule[i].char_now == tape[tape_pos]))
  115.                                 break;
  116.                 if(i>=rule_len) {
  117.                         fprintf(stderr,"%s:%d:ERROR RULES:stat=%d,char=%d\n",__FILE__,__LINE__,stat,tape[tape_pos]);
  118.                         exit(1);
  119.                 }
  120.                 stat = rule[i].stat_next;
  121.                 tape[tape_pos] = rule[i].char_next;
  122.                 if(rule[i].dir)
  123.                         tape_pos++;
  124.                 else
  125.                         tape_pos--;
  126.                 if(stat <= REJECT)
  127.                         break;
  128.         }
  129.         return stat;
  130. }

  131. void write_result(const char* filename)
  132. {
  133.         FILE *f;
  134.         int i,j;

  135.         for(i=tape_len-1;i>=0;i--)
  136.                 if(tape[i] != BLANK)
  137.                         break;
  138.         for(j=0;j<=i;j++)
  139.                 printf("tape[%d]\t%d\n",j,tape[j]);
  140.         if(filename == NULL)
  141.                 return;
  142.         f = fopen(filename,"wb");
  143.         fwrite(tape,sizeof(int),i+1,f);
  144.         fclose(f);
  145. }

  146. int main(int argc,char**argv)
  147. {
  148.         int ret;

  149.         init_turing(argv[1]);

  150.         ret = work_turing();
  151.         switch(ret) {
  152.                 case ACCEPT:
  153.                         printf("RESULT:ACCEPT!\n");
  154.                         break;
  155.                 case REJECT:
  156.                         printf("RESULT:REJECT!\n");
  157.                         break;
  158.                 default:
  159.                         printf("%s:%d:ret=%d\n",__FILE__,__LINE__,ret);
  160.                         break;
  161.         }

  162.         if(argc == 3)
  163.                 write_result(argv[2]);
  164.         else
  165.                 write_result(NULL);

  166.         return 0;
  167. }
复制代码

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
2 [报告]
发表于 2012-11-13 13:28 |只看该作者
二进制加1
用1代表1,用2代表0
程序
# cat rule
max_stat 3
max_char 2
0 0 2 0 1
0 2 1 1 1
0 1 3 2 1
3 0 1 1 1
3 2 1 1 1
3 1 3 2 1
每行5个数,
当前状态 当前位置纸带值 下个状态 纸带改变值 读写头方向(1向右,0向左)
图灵机读写头初始位置为0位置,初始无法向左
# echo 1 1 1 2 2 1 | ./a.out rule
RESULT:ACCEPT!
tape[0] 2
tape[1] 2
tape[2] 2
tape[3] 1
tape[4] 2
tape[5] 1
解释一下:
1 1 1 2 2 1
表示二进制100111
出来的数表示是
101000

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
3 [报告]
发表于 2012-11-13 13:30 |只看该作者
cjaizss 发表于 2012-11-13 13:28
二进制加1
用1代表1,用2代表0
程序

# echo |./a.out rule
RESULT:REJECT!
无值图灵机转到拒绝状态

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
4 [报告]
发表于 2012-11-14 20:39 |只看该作者
复制二进制数
程序
#cat rule_copy
stat    tape    Nstat   Ntape   DIR
0       0       2       0       1
0       1       3       5       1
0       2       4       6       1
3       0       5       0       1
3       1       3       1       1
3       2       3       2       1
4       0       6       0       1
4       1       4       1       1
4       2       4       2       1
5       0       7       1       0
5       1       5       1       1
5       2       5       2       1
6       0       7       2       0
6       1       6       1       1
6       2       6       2       1
7       0       8       0       0
7       1       7       1       0
7       2       7       2       0
8       1       9       1       0
8       2       9       2       0
8       3       10      1       0
8       4       10      2       0
8       5       1       1       1
8       6       1       2       1
9       1       9       1       0
9       2       9       2       0
9       3       11      3       1
9       4       11      4       1
9       5       11      5       1
9       6       11      6       1
11      1       3       3       1
11      2       4       4       1
10      3       10      1       0
10      4       10      2       0
10      5       1       1       1
10      6       1       2       1
程序运行
# echo 1 | ./a.out rule_copy
RESULT:ACCEPT!
tape[0] 1
tape[1] 0
tape[2] 1
# echo 1 2 | ./a.out rule_copy
RESULT:ACCEPT!
tape[0] 1
tape[1] 2
tape[2] 0
tape[3] 1
tape[4] 2
# echo 1 2 1 1 2 1 1 1 2 | ./a.out rule_copy
RESULT:ACCEPT!
tape[0] 1
tape[1] 2
tape[2] 1
tape[3] 1
tape[4] 2
tape[5] 1
tape[6] 1
tape[7] 1
tape[8] 2
tape[9] 0
tape[10]        1
tape[11]        2
tape[12]        1
tape[13]        1
tape[14]        2
tape[15]        1
tape[16]        1
tape[17]        1
tape[18]        2

论坛徽章:
0
5 [报告]
发表于 2012-11-17 22:34 |只看该作者
回复 2# cjaizss


跑到 tape[3] 1 已经ACCEPT了?
   

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
6 [报告]
发表于 2012-11-18 00:23 |只看该作者
本帖最后由 cjaizss 于 2012-11-18 02:15 编辑
joker0910 发表于 2012-11-17 22:34
回复 2# cjaizss

恩,后面不用算了

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
7 [报告]
发表于 2012-11-18 17:16 |只看该作者
翻转
stat    tape    Nstat   Ntape   DIR
0       0       2       0       1
0       1       3       5       1
0       2       4       5       1
3       0       5       0       0
3       1       3       1       1
3       2       3       2       1
3       3       5       3       0
3       4       5       4       0
4       0       6       0       0
4       1       4       1       1
4       2       4       2       1
4       3       6       3       0
4       4       6       4       0
5       1       7       3       0
5       2       8       3       0
5       3       10      3       1
5       4       10      4       1
5       5       10      5       1
6       1       7       4       0
6       2       8       4       0
6       3       10      3       1
6       4       10      4       1
6       5       10      6       1
7       1       7       1       0
7       2       7       2       0
7       3       9       3       1
7       4       9       3       1
7       5       9       5       1
8       1       8       1       0
8       2       8       2       0
8       3       9       4       1
8       4       9       4       1
8       5       9       6       1
9       1       3       3       1
9       2       4       4       1
9       3       10      3       1
9       4       10      4       1
10      0       11      0       0
10      3       10      3       1
10      4       10      4       1
11      3       11      1       0
11      4       11      2       0
11      5       1       1       1
11      6       1       2       1
测试
# echo 1 2 1 1 2 1 1 1 2 | ./a.out rule
RESULT:ACCEPT!
tape[0] 2
tape[1] 1
tape[2] 1
tape[3] 1
tape[4] 2
tape[5] 1
tape[6] 1
tape[7] 2
tape[8] 1

论坛徽章:
0
8 [报告]
发表于 2012-11-20 00:08 |只看该作者
原来打纸带真的可以编程~~ 嗯,怎么个思路? 想做个规则,有心无力啊...

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
9 [报告]
发表于 2012-11-27 13:21 |只看该作者
下面这个效率高一些

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <assert.h>

  5. int *tape;
  6. int tape_len;
  7. int tape_pos=0;
  8. #ifdef START
  9. #undef START
  10. #endif
  11. #ifdef ACCEPT
  12. #undef ACCEPT
  13. #endif
  14. #ifdef REJECT
  15. #undef REJECT
  16. #endif
  17. #ifdef BLANK
  18. #undef BLANK
  19. #endif
  20. #define START 0
  21. #define ACCEPT 1
  22. #define REJECT 2
  23. #define BLANK 0
  24. int stat = START;
  25. int max_stat = 3;/*:0:start,1:accept,2:reject,3~max_stat*/
  26. int max_char = 1;/*0:balnk,1~max_char*/
  27. typedef struct {
  28.         int stat_next;
  29.         int char_next;
  30.         int dir;/*0:tape_pos--,else:tape_pos++*/
  31. } rule_t;
  32. rule_t **rule;

  33. static void init_turing(const char* program)
  34. {
  35.         FILE* f;
  36.         int i,j;
  37.         char s[100];
  38.         char s2[100];
  39.         int stat_now,char_now,stat_next,char_next,dir;

  40.         tape_len = 1024*1024;
  41.         tape = (int*)malloc(sizeof(*tape)*tape_len);
  42.         f = fopen(program,"r");
  43.         while(1) {
  44.                 if(fgets(s,sizeof(s),f)==NULL)
  45.                         break;
  46.                 if(sscanf(s,"%d%d",&stat_now,&char_now)!=2)
  47.                         continue;
  48.                 if(max_stat < stat_now)
  49.                         max_stat  = stat_now;
  50.                 if(max_char < char_now)
  51.                         max_char = char_now;
  52.         }
  53.         fclose(f);
  54.         rule = (rule_t**)malloc(sizeof(rule_t*)*(max_stat+1));
  55.         rule[0] = (rule_t*)malloc(sizeof(rule_t)*(max_stat+1)*(max_char+1));
  56.         for(i=1;i<=max_stat;i++)
  57.                 rule[i]=rule[i-1]+(max_char+1);
  58.         for(i=0;i<=max_stat;i++)
  59.                 for(j=0;j<max_char;j++) {
  60.                         rule[i][j].stat_next = REJECT;
  61.                         rule[i][j].char_next = j;
  62.                         rule[i][j].dir = 1;
  63.                 }
  64.         f = fopen(program,"r");
  65.         while(1) {
  66.                 if(fgets(s,sizeof(s),f)==NULL)
  67.                         break;
  68.                 if(sscanf(s,"%s",s2)!=1)
  69.                         continue;
  70.                 if(strcmp(s2,"tape_len")==0) {
  71.                         sscanf(s,"%s%d",s2,&tape_len);
  72.                         tape = (int*)realloc(tape,sizeof(*tape)*tape_len);
  73.                         continue;
  74.                 }
  75.                 if(sscanf(s,"%d%d%d%d%d",
  76.                                         &stat_now,
  77.                                         &char_now,
  78.                                         &stat_next,
  79.                                         &char_next,
  80.                                         &dir) == 5) {
  81.                         rule[stat_now][char_now].stat_next = stat_next;
  82.                         rule[stat_now][char_now].char_next = char_next;
  83.                         rule[stat_now][char_now].dir = dir;
  84.                 }

  85.         }

  86.         fclose(f);
  87. }

  88. static void init_tape(void)
  89. {
  90.         int i;
  91.         int x;

  92.         memset(tape,0,sizeof(int)*tape_len);
  93.         i=0;
  94.         while(1) {
  95.                 if(scanf("%d",&x)!=1)
  96.                         break;
  97.                 if(x<0||x>max_char)
  98.                         fprintf(stderr,"%s:%d:input error",__FILE__,__LINE__);
  99.                 else
  100.                         tape[i++]=x;
  101.         }
  102. }

  103. static int work_turing(void)
  104. {
  105.         int stat_now,char_now;

  106.         init_tape();
  107.         while(1) {
  108.                 stat_now = stat;
  109.                 char_now = tape[tape_pos];
  110.                 stat = rule[stat_now][char_now].stat_next;
  111.                 tape[tape_pos] = rule[stat_now][char_now].char_next;
  112.                 if(rule[stat_now][char_now].dir)
  113.                         tape_pos++;
  114.                 else
  115.                         tape_pos--;
  116.                 if(stat <= REJECT)
  117.                         break;
  118.         }
  119.         return stat;
  120. }

  121. void write_result(const char* filename)
  122. {
  123.         FILE *f;
  124.         int i,j;

  125.         for(i=tape_len-1;i>=0;i--)
  126.                 if(tape[i] != BLANK)
  127.                         break;
  128.         for(j=0;j<=i;j++)
  129.                 printf("tape[%d]\t%d\n",j,tape[j]);
  130.         if(filename == NULL)
  131.                 return;
  132.         f = fopen(filename,"wb");
  133.         fwrite(tape,sizeof(int),i+1,f);
  134.         fclose(f);
  135. }

  136. int main(int argc,char**argv)
  137. {
  138.         int ret;

  139.         init_turing(argv[1]);

  140.         ret = work_turing();
  141.         switch(ret) {
  142.                 case ACCEPT:
  143.                         printf("RESULT:ACCEPT!\n");
  144.                         break;
  145.                 case REJECT:
  146.                         printf("RESULT:REJECT!\n");
  147.                         break;
  148.                 default:
  149.                         printf("%s:%d:ret=%d\n",__FILE__,__LINE__,ret);
  150.                         break;
  151.         }

  152.         if(argc == 3)
  153.                 write_result(argv[2]);
  154.         else
  155.                 write_result(NULL);

  156.         return 0;
  157. }

复制代码

论坛徽章:
1
技术图书徽章
日期:2013-10-29 15:46:41
10 [报告]
发表于 2012-12-04 16:20 |只看该作者
mark              
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP