找回密码
 欢迎注册
查看: 47598|回复: 54

[擂台] 求算24点的程序,要求快且求出所有解!

[复制链接]
发表于 2012-4-12 14:06:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
给出4个整数.
1,2,3,4允许改变顺序,则可以是4,3,2,1

分四类情况:
A\允许改变数字顺序,不允许使用括号,使用加减乘除.
B\允许改变数字顺序,允许使用括号,使用加减乘除.
C\不允许改变数字顺序,不允许使用括号,使用加减乘除.
D\不允许改变数字顺序,允许使用括号,使用加减乘除.

在这四种情况下,写出程序!

8\8\4\3
先给一个,看谁先算出来
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2012-4-12 14:29:44 | 显示全部楼层
C {-23, -13, -(23/2), -10, -9, -8, -(13/2), -5, -4, -(23/6), -(11/3), -(10/3), -(5/2), -(7/3), -2, -(7/4), -(5/3), -1, -(1/2), -(1/ 4), 0, 1/24, 1/6, 3/8, 2/3, 5/6, 1, 7/6, 5/4, 3/2, 2, 9/4, 5/2, 8/3, 11/4, 3, 11/3, 15/4, 4, 25/6, 13/3, 14/3, 11/2, 17/3, 6, 15/2, 9, 10, 11, 25/2, 14, 15, 24, 25}
  1. TableForm[{#, ToExpression[#]} & /@ Map[StringJoin, Riffle[CharacterRange["1", "4"], #] & /@ Tuples[{"+", "-", "*", "/"}, {3}]]]
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2012-4-13 08:28:30 | 显示全部楼层
找到一个过去写的c++代码
  1. #include <stdio.h>
  2. #include <map>
  3. #include <algorithm>
  4. using namespace std;
  5. int pm[]={0x1,0x55,0x10515,0x555555,0x41041,0x15,0x30f3f,0xffffff,
  6. 0x3f,0x30f3f,0xaaff,0x20b,0xaaff,0x2cb2cb,0x1c71c7};
  7. short table[]={
  8. 0, 65, 130, 195, 132, 261, 134, 199,
  9. 328, 201, 138, 203, 140, 205, 142, 207,
  10. 402, 467, 537, 410, 475, 412, 605, 414,
  11. 479, 354, 227, 164, 229, 166, 231, 42,
  12. 107, 172, 237, 174, 303, 691, 436, 501,
  13. 438, 503, 1416, 1481, 1738, 1803, 1420, 1485,
  14. 1871, 1432, 1497, 1754, 1819, 1436, 1501, 1887,
  15. 1760, 1825, 1442, 1507, 1893, 1446, 1511, 1776,
  16. 1841, 1458, 1523, 1909, 1462, 1527, 2883, 2503,
  17. 2899, 2519, 2921, 2541, 2937, 2557, 3331, 3975,
  18. 3915, 3535, 3287, 3931, 3551, 3937, 3557, 3369,
  19. 4013, 3953, 3573, 3325, 4301, 4573, 4327, 4599
  20. };
  21. short o0[24];
  22. short o1[24];
  23. short o2[24];
  24. short o3[24];
  25. char opprint[]={'+','-','*','/'};
  26. int mask_cd,mask_bcd,mask_ab_cd;
  27. #define mask_null 0xFFFFFF
  28. #define mask_abcd 1
  29. struct expression{
  30. int value;
  31. expression(int v):value(v){ }
  32. int first_op()const{
  33. return value & 3;
  34. }
  35. int second_op()const{
  36. return (value >> 2)&3;
  37. }
  38. int third_op()const{
  39. return (value >> 4)&3;
  40. }
  41. int graph_type()const{
  42. return (value >> 6)/24;
  43. }
  44. int num_order()const{
  45. return (value >> 6)%24;
  46. }
  47. };
  48. typedef int INT;
  49. struct factor_num{
  50. INT up;
  51. INT down;
  52. factor_num(){}
  53. factor_num(INT u,INT d):up(u),down(d){ }
  54. };
  55. typedef factor_num (*OperatorFun)(const factor_num& x,const factor_num& y);
  56. factor_num sum(const factor_num& i,const factor_num& j){
  57. INT d,u;
  58. if(i.down==0||j.down==0){
  59. d=0;
  60. }else{
  61. d=i.down * j.down;
  62. u=i.up * j.down + j.up * i.down;
  63. }
  64. return factor_num(u,d);
  65. }
  66. factor_num dif(const factor_num& i,const factor_num& j){
  67. INT d,u;
  68. if(i.down==0||j.down==0){
  69. d=0;
  70. }else{
  71. d=i.down * j.down;
  72. u=i.up * j.down - j.up * i.down;
  73. }
  74. return factor_num(u,d);
  75. }
  76. factor_num prod(const factor_num& i,const factor_num& j){
  77. INT d,u;
  78. u=i.up * j.up;
  79. d=i.down * j.down;
  80. return factor_num(u,d);
  81. }
  82. factor_num ratio(const factor_num& i,const factor_num& j){
  83. INT d,u;
  84. if(i.down == 0 || j.down==0){
  85. d=0;
  86. }else{
  87. d=i.down * j.up;
  88. u=i.up * j.down;
  89. }
  90. return factor_num(u,d);
  91. }
  92. OperatorFun funs[]={sum,dif,prod,ratio};
  93. bool equal_num(const factor_num& i,INT j)
  94. {
  95. if(i.down==0){
  96. return false;
  97. }else{
  98. return i.up == j * i.down;
  99. }
  100. }
  101. void show(INT input[],expression expr){
  102. int order=expr.num_order();
  103. INT aa=input[o0[order]];
  104. INT bb=input[o1[order]];
  105. INT cc=input[o2[order]];
  106. INT dd=input[o3[order]];
  107. short op1=expr.first_op();
  108. char ops1=opprint[op1];
  109. short op2=expr.second_op();
  110. char ops2=opprint[op2];
  111. short op3=expr.third_op();
  112. char ops3=opprint[op3];
  113. switch(expr.graph_type()){
  114. case 0:
  115. if(op1<2 && op2 >=2){
  116. printf("(%d%c%d)%c",aa,ops1,bb,ops2);
  117. } else {
  118. printf("%d%c%d%c",aa,ops1,bb,ops2);
  119. }
  120. if(op2>=op3){
  121. printf("(%d%c%d)",cc,ops3,dd);
  122. }else{
  123. printf("%d%c%d",cc,ops3,dd);
  124. }
  125. break;
  126. case 1:
  127. if(op2<2&&op3>=2)
  128. printf("(");
  129. if(op1<2&&op2>=2)
  130. printf("(");
  131. printf("%d%c%d",aa,ops1,bb);
  132. if(op1<2&&op2>=2)
  133. printf(")");
  134. printf("%c%d",ops2,cc);
  135. if(op2<2&&op3>=2)
  136. printf(")");
  137. printf("%c%d",ops3,dd);
  138. break;
  139. case 2:
  140. if(op1<2&&op3>=2)
  141. printf("(");
  142. printf("%d%c",aa,ops1);
  143. if(op1>=op2)
  144. printf("(");
  145. printf("%d%c%d",bb,ops2,cc);
  146. if(op1>=op2)
  147. printf(")");
  148. if(op1<2&&op3>=2)
  149. printf(")");
  150. printf("%c%d",ops3,dd);
  151. break;
  152. case 3:
  153. printf("%d%c",aa,ops1);
  154. if(op1>=op3)
  155. printf("(");
  156. if(op2<2&&op3>=2)
  157. printf("(");
  158. printf("%d%c%d",bb,ops2,cc);
  159. if(op2<2&&op3>=2)
  160. printf(")");
  161. printf("%c%d",ops3,dd);
  162. if(op1>=op3)
  163. printf(")");
  164. break;
  165. case 4:
  166. printf("%d%c",aa,ops1);
  167. if(op1>=op2)
  168. printf("(");
  169. printf("%d%c",bb,ops2);
  170. if(op2>=op3)
  171. printf("(");
  172. printf("%d%c%d",cc,ops3,dd);
  173. if(op2>=op3)
  174. printf(")");
  175. if(op1>=op2)
  176. printf(")");
  177. break;
  178. }
  179. }
  180. #define elems(x) (sizeof(x)/sizeof(x[0]))
  181. void c_main(INT input[],int mask,INT result)
  182. {
  183. int total=0;
  184. int i;
  185. factor_num r1,r2,r;
  186. for(i=0;i<elems(table);i++){
  187. int op=table[ i]&63;
  188. int left=table[ i]>>6;
  189. int g=left>>4;
  190. int pl=left&15;
  191. int pattern=pm[pl]&mask;
  192. int j;
  193. for(j=0;j<24;j++){
  194. if(pattern&(1<<j)){
  195. short elem=(j+g*24)*64+op;
  196. expression t(elem);
  197. short op1=t.first_op();
  198. short op2=t.second_op();
  199. short op3=t.third_op();
  200. short gtype=t.graph_type();
  201. short order=t.num_order();
  202. factor_num aa=factor_num(input[o0[order]],1);
  203. factor_num bb=factor_num(input[o1[order]],1);
  204. factor_num cc=factor_num(input[o2[order]],1);
  205. factor_num dd=factor_num(input[o3[order]],1);
  206. OperatorFun fun1=funs[op1];
  207. OperatorFun fun2=funs[op2];
  208. OperatorFun fun3=funs[op3];
  209. switch(gtype){
  210. case 0:
  211. r1=fun1(aa,bb);
  212. r2=fun3(cc,dd);
  213. r=fun2(r1,r2);
  214. break;
  215. case 1:
  216. r1=fun1(aa,bb);
  217. r2=fun2(r1,cc);
  218. r=fun3(r2,dd);
  219. break;
  220. case 2:
  221. r1=fun2(bb,cc);
  222. r2=fun1(aa,r1);
  223. r=fun3(r2,dd);
  224. break;
  225. case 3:
  226. r1=fun2(bb,cc);
  227. r2=fun3(r1,dd);
  228. r=fun1(aa,r2);
  229. break;
  230. case 4:
  231. r1=fun3(cc,dd);
  232. r2=fun2(bb,r1);
  233. r=fun1(aa,r2);
  234. break;
  235. }
  236. if(equal_num(r,result)){
  237. show(input,t);
  238. printf("/t");
  239. total++;
  240. }
  241. }
  242. }
  243. }
  244. if(total)printf("/n");
  245. }
  246. void c24(INT s1,INT s2,INT s3,INT s4,INT r){
  247. INT input[4];
  248. int i,j;
  249. input[0]=s1;input[1]=s2;input[2]=s3;input[3]=s4;
  250. for(i=0;i<4;i++){
  251. for(j=i+1;j<4;j++){
  252. if(input[j]<input[ i]){
  253. INT temp=input[j];
  254. input[j]=input[ i];
  255. input[ i]=temp;
  256. }
  257. }
  258. }
  259. if(input[0]==input[1]){//a==b
  260. if(input[1]!=input[2]){
  261. if(input[2]!=input[3]){//only a==b
  262. INT temp=input[2];
  263. input[2]=input[0];
  264. input[0]=temp;
  265. temp=input[3];
  266. input[3]=input[1];
  267. input[1]=temp;
  268. c_main(input,mask_cd,r);
  269. }else{//a==b,c==d
  270. c_main(input,mask_ab_cd,r);
  271. }
  272. }else if(input[2]!=input[3]){//a==b==c!=d
  273. INT temp=input[0];
  274. input[0]=input[3];
  275. input[3]=temp;
  276. c_main(input,mask_bcd,r);
  277. }else{//a==b==c==d
  278. c_main(input,mask_abcd,r);
  279. }
  280. }else{//a!=b
  281. if(input[1]==input[2]){
  282. if(input[2]!=input[3]){//b==c
  283. INT temp=input[3];
  284. input[3]=input[1];
  285. input[1]=temp;
  286. c_main(input,mask_cd,r);
  287. }else{//b==c==d
  288. c_main(input,mask_bcd,r);
  289. }
  290. }else{
  291. if(input[2]==input[3]){//c==d
  292. c_main(input,mask_cd,r);
  293. }else{
  294. c_main(input,mask_null,r);
  295. }
  296. }
  297. }
  298. }
  299. #define N 13
  300. void init()
  301. {
  302. INT i=0;
  303. short a[4]={0,1,2,3};
  304. do{
  305. o0[ i]=a[0];
  306. o1[ i]=a[1];
  307. o2[ i]=a[2];
  308. o3[ i]=a[3];
  309. i++;
  310. }while(next_permutation(a,a+4));
  311. for(i=0;i<24;i++){
  312. short inv[4];
  313. inv[o0[ i]]=0;
  314. inv[o1[ i]]=1;
  315. inv[o2[ i]]=2;
  316. inv[o3[ i]]=3;
  317. if(inv[2]<inv[3]){
  318. mask_cd|=(1<<i);
  319. }
  320. if(inv[1]<inv[2]&&inv[2]<inv[3]){
  321. mask_bcd|=(1<<i);
  322. }
  323. if(inv[0]<inv[1]&&inv[2]<inv[3]){
  324. mask_ab_cd|=(1<<i);
  325. }
  326. }
  327. }
  328. int bits(int x){
  329. int b=0,i;
  330. for(i=0;i<32;i++)if(x&(1<<i))b++;
  331. return b;
  332. }
  333. int main()
  334. {
  335. INT i=0,j,k,m;
  336. init();
  337. for(i=1;i<=N;i++)for(j=i;j<=N;j++)for(k=j;k<=N;k++)for(m=k;m<=N;m++){
  338. c24(i,j,k,m,24);
  339. }
  340. }
复制代码

点评

你的代码我看不懂,看到没注释的代码,我就不想看了,但是能写这么复杂,表示你很牛逼  发表于 2018-7-27 13:00
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2012-4-13 11:48:19 | 显示全部楼层
C {-23, -13, -(23/2), -10, -9, -8, -(13/2), -5, -4, -(23/6), -(11/3), -(10/3), -(5/2), -(7/3), -2, -(7/4), -(5/3), -1, -(1/2), -(1/ 4), 0, 1/24, 1/6, 3/8, 2/3, 5/6, 1, 7/6, 5/4, 3/2, 2, 9/4, 5/2, 8/3 ... wayne 发表于 2012-4-12 14:29
文字内容和代码都没看明白!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2012-4-13 11:49:31 | 显示全部楼层
找到一个过去写的c++代码#include #include #include using namespace std; int pm[]={0x1,0x55,0x10515,0x555555,0x41041,0x15,0x30f3f,0xffffff, ... mathe 发表于 2012-4-13 08:28
没有注释的程序,将来自己能看明白吗? 我很怀疑! 我觉得那么长的程序,还不如弄成压缩一下传上来呢 对了,最好还有注释与说明,不然程序真的很难懂!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2012-4-13 11:52:21 | 显示全部楼层
其实这个代码几乎不包含什么有用的信息,主要是一个表格,包含了四个数的不等价的表达式的一种编码后的形式。而产生表格的代码我已经找不到。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2012-4-13 14:37:59 | 显示全部楼层
文字内容和代码都没看明白! mathematica 发表于 2012-4-13 11:48
赫赫,wayne的意思是:
  1. (* 关于题目中的情况C: *)
  2. s[z_] := Select[Map[StringJoin,Riffle[Map[ToString, z], #] & /@Tuples[{"+", "-", "*", "/"}, {3}]],ToExpression[#] == 24 &]; (* 这里套用wayne的代码 *)
  3. {1, 2, 3, 4} // s (* 例子一 *)
  4. {8, 8, 4, 3} // s (* 例子二 *)
复制代码
其实,我个人喜欢他们的风格,赫赫。

点评

这个是只能没有括号的情况  发表于 2013-10-18 18:08
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2012-4-13 15:42:19 | 显示全部楼层
还可以用x~jia~y来表示(x+y),赫赫。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2012-4-15 10:59:39 | 显示全部楼层
7# zgg___ ,逃不过zgg的慧眼 感觉有括号的情况要麻烦些
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2012-4-18 13:20:45 | 显示全部楼层
我也看不懂,Mathematica的函数真多
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-11-22 12:50 , Processed in 0.027764 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表