LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: scream

如何用c写一个算24的小游戏

[复制链接]
发表于 2006-9-1 16:05:00 | 显示全部楼层
Post by scream
我的设想是这样的:首先计算机给出四个随机数,然后
*如果这四个数可以计算出24则等待直到用户按键,显示出计算方法;
*如果这四个数不能计算出24则显示impossible;

其中我想不明白的有两点:

(1)怎么实现让计算机随机给出一个数?

(2)计算机怎么自己计算24,难道是人工智能?

我觉得应该用递归回溯解决!我也写个
回复 支持 反对

使用道具 举报

发表于 2006-9-1 16:12:17 | 显示全部楼层
Post by winix
热情固然可嘉,但不要忘记:算法+数据结构=程序

Up till now Absolutely right.
如果有那么一天计算机的解构改变了,也就是说冯诺-依曼结构给别的××结构取代的时候,
这个定理就不一定对了,个人愚见。
回复 支持 反对

使用道具 举报

发表于 2006-9-1 17:04:04 | 显示全部楼层
bobhuang
我以前写过一个算5个5的24点算法,临时写的,输入输出不是很规范
输出4次计算所用的算符和计算的位置(总共计算4次,在4个位置上),给楼主做参考
====================

感觉这个算法不完整
如果是(3-1)*(8+4)这种情况你如何判断呢?
回复 支持 反对

使用道具 举报

发表于 2006-9-1 17:31:11 | 显示全部楼层
Post by doubleelec
o my god!

要是这道题要求用八个数来做,这个程序不知道要写成什么样了。


刚才没看到第三页,现在好多了。


如果要是处理数据变化的话可以考虑用递归
这样理解简单些:


// 把输入的数据看做一个集合,集合中有n个元素
// 从n个元素中取2个元素共有max组合
// 对每个组合中的2个元素进行+-*/运算
// 把运算的结果替换n集合中取出的2个元素
// 现在集合中有(n-1)个元素
// 对含有(n-1)个元素的新集合递归进行上述判断
// 如果集合只剩下1个元素,则就是最终结果
回复 支持 反对

使用道具 举报

发表于 2006-9-5 15:38:52 | 显示全部楼层
被jerboa感动了一下
回复 支持 反对

使用道具 举报

发表于 2006-9-6 11:25:13 | 显示全部楼层

我也来一个

用C++写了一个,可以计算任意个数字,任意计算目标(未必是24),输出所有可能的计算式(但类似 a+b, b+a ; a*b, b*a 之类的只输出一种 )。 应该是目前为止最完善最灵活的一个解决方案了:cool:
  1. //--------------------------------------------------------
  2. // “算24”游戏:若干个数,通过 + - * / 四则运算,求出等于目标数值的表达式。
  3. // by Lolita@linuxsir.cn 2006-09-06
  4. //
  5. // 算法: (引用 chai2010@linuxsir.cn)
  6. // 把输入的数据看做一个集合,集合中有n个元素。
  7. // 从集合中任取2个元素分别进行+-*/运算,
  8. // 把运算的结果替换n集合中取出的2个元素
  9. // 现在集合中有(n-1)个元素
  10. // 对含有(n-1)个元素的新集合递归进行上述判断
  11. // 如果集合只剩下1个元素且该,则就是最终结果
  12. //
  13. // 实现: C++, vector, 递归
  14. //
  15. //--------------------------------------------------------
  16. #include <iostream>
  17. #include <sstream>
  18. #include <vector>
  19. using namespace std;
  20. //参与“算24”的运算类型,最好是浮点数
  21. typedef float data_t;
  22. //默认为计算24
  23. data_t TARGET=24;
  24. #define GET_EXPR(des,src) do{     \
  25.     if(src.expr.str().empty())    \
  26.         des.expr<<src.data;       \
  27.     else des.expr<<src.expr.str();\
  28. }while(0)
  29. class element{
  30.     friend element operator+(element &, element &);
  31.     friend element operator-(element &, element &);
  32.     friend element operator*(element &, element &);
  33.     friend element operator/(element &, element &);
  34.     friend vector<element>& cal_target(vector<element> );
  35. private:
  36.     data_t data;
  37.     ostringstream expr;
  38. public:
  39.     element(data_t const& x):data(x){ }
  40.     element(element const& rhs):data(rhs.data){ expr<<rhs.expr.str(); }
  41.     element& operator=(element const&);
  42.     void show_expr() { cout<<expr.str(); }
  43.   
  44. };
  45. element& element::operator=(element const& rhs)
  46. {
  47.     if(this!=&rhs){
  48.         data=rhs.data;
  49.         expr.str("");
  50.         expr<<rhs.expr.str();
  51.     }
  52.     return *this;
  53. }
  54. element operator+(element& rhs1, element& rhs2)
  55. {
  56.     element ret(rhs1.data+rhs2.data);
  57.    
  58.     ret.expr<<"(";
  59.     GET_EXPR(ret,rhs1);
  60.     ret.expr<<"+";
  61.     GET_EXPR(ret,rhs2);
  62.     ret.expr<<")";
  63.     return ret;
  64. }
  65. element operator-(element & rhs1, element & rhs2)
  66. {
  67.     element ret(rhs1.data-rhs2.data);
  68.    
  69.     ret.expr<<"(";
  70.     GET_EXPR(ret,rhs1);
  71.     ret.expr<<"-";
  72.     GET_EXPR(ret,rhs2);
  73.     ret.expr<<")";
  74.     return ret;
  75. }
  76. element operator*(element& rhs1, element& rhs2)
  77. {
  78.     element ret(rhs1.data*rhs2.data);
  79.    
  80.     ret.expr<<"(";
  81.     GET_EXPR(ret,rhs1);   
  82.     ret.expr<<"*";
  83.     GET_EXPR(ret,rhs2);
  84.     ret.expr<<")";
  85.     return ret;
  86. }
  87. element operator/(element& rhs1, element& rhs2)
  88. {
  89.     if(rhs2.data){
  90.         element ret(rhs1.data/rhs2.data);
  91.    
  92.         ret.expr<<"(";
  93.         GET_EXPR(ret,rhs1);
  94.         ret.expr<<"/";
  95.         GET_EXPR(ret,rhs2);
  96.         ret.expr<<")";
  97.         return ret;
  98.     }else{
  99.         cerr<<"divide by 0 error!"<<endl;
  100.         abort();
  101.     }
  102. }
  103. vector<element>& cal_target( vector<element>  vt )
  104. {
  105.     vector<element>::iterator it,it1,it2;
  106.     static vector<element> result;
  107.    
  108.     if(vt.empty())return result;
  109.     else if(vt.size()==1){
  110.         element e=vt.back();
  111.         if(e.data==TARGET)result.push_back(e);
  112.     }else{
  113.         for(it1=vt.begin(); it1<vt.end()-1; it1++){
  114.              for(it2=it1+1; it2<vt.end(); it2++){
  115.                 element e1=*it1;
  116.                 element e2=*it2;                  
  117.                 it2=vt.erase(it2); // remove 2 elements
  118.                 it1=vt.erase(it1); // CAUTION: e2 should erase first !
  119.                
  120.                 vt.push_back(e1+e2);
  121.                 cal_target(vt);
  122.                 vt.pop_back();
  123.                
  124.                 vt.push_back(e1-e2);
  125.                 cal_target(vt);
  126.                 vt.pop_back();
  127.                
  128.                 vt.push_back(e2-e1);
  129.                 cal_target(vt);
  130.                 vt.pop_back();
  131.                
  132.                 vt.push_back(e1*e2);
  133.                 cal_target(vt);
  134.                 vt.pop_back();
  135.                
  136.                 if(e2.data){
  137.                     vt.push_back(e1/e2);
  138.                     cal_target(vt);
  139.                     vt.pop_back();
  140.                 }
  141.                
  142.                 if(e1.data){
  143.                     vt.push_back(e2/e1);
  144.                     cal_target(vt);
  145.                     vt.pop_back();
  146.                 }
  147.                
  148.                 it1=vt.insert(it1,e1);  // recover vector               
  149.                 it2=vt.insert(it2,e2);  // CAUTION: e1 should insert first !
  150.             }
  151.         }
  152.     }
  153.     return result;
  154. }
  155. int main()
  156. {
  157.     // 参与运算的数组,个数、数值可以随意设定
  158.     element arr[]={3,6,2,15};
  159.     // 运算目标,默认为24, 可以随意设定
  160.     TARGET=24;
  161.       
  162.     vector<element> vt(arr, arr+sizeof(arr)/sizeof(arr[0]));
  163.     vector<element>::iterator it;
  164.    
  165.     vector<element> result=cal_target(vt);
  166.     if(result.empty())cout<<"impossible!"<<endl;
  167.     else{
  168.         for(it=result.begin(); it!=result.end(); it++){
  169.             it->show_expr();
  170.             cout<<" = "<<TARGET<<endl;
  171.         }
  172.         cout<<"--------------------"<<endl;
  173.         cout<<"solutions found: "<<result.size()<<endl;
  174.     }
  175. }
复制代码
~/coding/cpp $ g++ cal24.cc
~/coding/cpp $ ./a.out
(2*(15+(3-6))) = 24
(2*(15-(6-3))) = 24
(15+((3*6)/2)) = 24
(15+(6*(3/2))) = 24
(15+(6/(2/3))) = 24
(2*((3+15)-6)) = 24
((6*2)-(3-15)) = 24
((15-3)+(6*2)) = 24
((6*2)-(3-15)) = 24
((6*2)+(15-3)) = 24
(15-(3-(6*2))) = 24
(15+((6*2)-3)) = 24
((15+(6*2))-3) = 24
(15+(3*(6/2))) = 24
(15+(3/(2/6))) = 24
(2*(3-(6-15))) = 24
(2*(3+(15-6))) = 24
--------------------
solutions found: 17
回复 支持 反对

使用道具 举报

发表于 2006-9-6 14:01:57 | 显示全部楼层
由于考虑的可能性比较多,所以5个元素以上的时候比较花时间。
回复 支持 反对

使用道具 举报

发表于 2006-9-7 11:21:17 | 显示全部楼层

交互式算24游戏

  1. //--------------------------------------------------------
  2. // 交互式“算24”游戏:若干个数,通过 + - * 四则运算(包括括号),
  3. // 求出等于目标数值的表达式。 提供人机交互操作,包含两种模式: 用户输入和随机生成。
  4. // by Lolita@linuxsir.cn 2006-09-07
  5. //
  6. // 算法: (引用 chai2010@linuxsir.cn)
  7. // 把输入的数据看做一个集合,集合中有n个元素。
  8. // 从集合中任取2个元素分别进行+-*/运算,
  9. // 把运算的结果替换n集合中取出的2个元素
  10. // 现在集合中有(n-1)个元素
  11. // 对含有(n-1)个元素的新集合递归进行上述判断
  12. // 如果集合只剩下1个元素且该,则就是最终结果
  13. //
  14. // 实现: C++, vector, 递归
  15. //
  16. //--------------------------------------------------------
  17. #include <iostream>
  18. #include <sstream>
  19. #include <vector>
  20. #include <cstdlib>
  21. #include <ctime>
  22. using namespace std;
  23. //参与“算24”的运算类型,最好是浮点数
  24. typedef float data_t;
  25. #define GET_EXPR(des,src) do{     \
  26.     if(src.expr.str().empty())           \
  27.         des.expr<<src.data;             \
  28.     else des.expr<<src.expr.str();   \
  29. }while(0)
  30. class element{
  31.     friend element operator+(element &, element &);
  32.     friend element operator-(element &, element &);
  33.     friend element operator*(element &, element &);
  34.     friend element operator/(element &, element &);
  35.     friend void cal_target(vector<element> );
  36.     friend class NumberGame;
  37. private:
  38.     data_t data;
  39.     ostringstream expr;
  40. public:
  41.     element(data_t const& x):data(x){ }
  42.     ~element(){ expr.str(""); data=0; }
  43.     element(element const& rhs):data(rhs.data){ expr<<rhs.expr.str(); }
  44.     element& operator=(element const&);
  45.     void show_expr() { cout<<expr.str(); }
  46.     void show_data() { cout<<data; }
  47.   
  48. };
  49. element& element::operator=(element const& rhs)
  50. {
  51.     if(this!=&rhs){
  52.         data=rhs.data;
  53.         expr.str("");
  54.         expr<<rhs.expr.str();
  55.     }
  56.     return *this;
  57. }
  58. element operator+(element& rhs1, element& rhs2)
  59. {
  60.     element ret(rhs1.data+rhs2.data);
  61.    
  62.     ret.expr<<"(";
  63.     GET_EXPR(ret,rhs1);
  64.     ret.expr<<"+";
  65.     GET_EXPR(ret,rhs2);
  66.     ret.expr<<")";
  67.     return ret;
  68. }
  69. element operator-(element & rhs1, element & rhs2)
  70. {
  71.     element ret(rhs1.data-rhs2.data);
  72.    
  73.     ret.expr<<"(";
  74.     GET_EXPR(ret,rhs1);
  75.     ret.expr<<"-";
  76.     GET_EXPR(ret,rhs2);
  77.     ret.expr<<")";
  78.     return ret;
  79. }
  80. element operator*(element& rhs1, element& rhs2)
  81. {
  82.     element ret(rhs1.data*rhs2.data);
  83.    
  84.     ret.expr<<"(";
  85.     GET_EXPR(ret,rhs1);   
  86.     ret.expr<<"*";
  87.     GET_EXPR(ret,rhs2);
  88.     ret.expr<<")";
  89.     return ret;
  90. }
  91. element operator/(element& rhs1, element& rhs2)
  92. {
  93.     if(rhs2.data){
  94.         element ret(rhs1.data/rhs2.data);
  95.    
  96.         ret.expr<<"(";
  97.         GET_EXPR(ret,rhs1);
  98.         ret.expr<<"/";
  99.         GET_EXPR(ret,rhs2);
  100.         ret.expr<<")";
  101.         return ret;
  102.     }else{
  103.         cerr<<"divide by 0 error!"<<endl;
  104.         abort();
  105.     }
  106. }
  107. class NumberGame{
  108. private:
  109.     vector<element> result;
  110.     vector<element> vin;
  111.     data_t target;
  112.     void init();
  113.     void cal_target(vector<element>);
  114.     void generate();
  115.     void show_puzzle();
  116.     void show_keypress();
  117.     void show_one_answer();
  118.     void show_all_answers();
  119. public:
  120.     NumberGame(){}
  121.     ~NumberGame(){ result.clear(); vin.clear(); }
  122.     bool input();
  123.     bool output();
  124.     bool random();
  125.    
  126. };
  127. void NumberGame::init()
  128. {
  129.     vin.clear();
  130.     result.clear();
  131. }
  132. bool NumberGame::input()
  133. {
  134.     data_t e;
  135.     int count=0;        
  136.     cout<<endl<<"How many numbers will you input( 0 to quit): ";
  137.     cin>>count;
  138.     if(count<1) return false;
  139.     if( count>8 ){
  140.         cout<<"Are you crazy? It may take a very long time to figure it out !"<<endl;
  141.     }
  142.    
  143.     init();
  144.     for(int i=1;i<=count;i++){
  145.         cout<<"num"<<i<<": ";
  146.         cin>>e;
  147.         vin.push_back(e);
  148.     }
  149.     cout<<"Your TARGET number: ";
  150.     cin>>target;
  151.     cal_target(vin);
  152.    
  153.     return true;
  154. }
  155. bool NumberGame::output()
  156. {
  157.     show_all_answers();
  158.     return true;
  159. }
  160. void NumberGame::generate()
  161. {
  162.     do{
  163.         init();
  164.         srand(time(NULL));
  165.         target=10+rand()%15;
  166.         int count=3+rand()%2;
  167.         for(int i=1; i<=count; i++){
  168.             vin.push_back( rand()%10 );
  169.             //delay();
  170.         }
  171.         cal_target(vin);
  172.     }while(result.empty());
  173. }
  174. void NumberGame::show_puzzle()
  175. {
  176.     vector<element>::iterator it;
  177.     cout<<"----------------------"<<endl;
  178.     for(it=vin.begin(); it!=vin.end(); it++)
  179.         cout<<it->data<<" ";
  180.     cout<<" = "<<target<<"  ?"<<endl<<"----------------------"<<endl;
  181. }
  182. void NumberGame::show_keypress()
  183. {
  184.     cout<<"'a': get an answer; ";
  185.     cout<<"'A' all answers; ";
  186.     cout<<"'n' to next puzzle; ";
  187.     cout<<"'q' to quit."<<endl;
  188. }
  189. void NumberGame::show_one_answer()
  190. {
  191.     static vector<element>::iterator it;
  192.    
  193.     // set it to a right answer
  194.     if(it<result.begin() || it>=result.end() )
  195.         it=result.begin();
  196.         
  197.     if( it!=result.end() ){
  198.         if(!it->expr.str().empty())it->show_expr();
  199.         else it->show_data();
  200.         cout<<" = " <<target<<endl;
  201.         it++;
  202.     }else cout<<"no other solutions found!"<<endl;
  203.    
  204. }
  205. void NumberGame::show_all_answers()
  206. {
  207.     vector<element>::iterator it;
  208.     if(result.empty())cout<<"no solutions found!"<<endl;
  209.     else{
  210.         for(it=result.begin();it!=result.end();it++){
  211.             if(!it->expr.str().empty()) it->show_expr();
  212.             else it->show_data();
  213.             cout<<" = "<<target<<endl;
  214.         }
  215.         cout<<"--------------------"<<endl;
  216.         cout<<"solutions found: "<<result.size()<<endl;
  217.     }
  218. }
  219. bool NumberGame::random()
  220. {
  221.     cout<<"Generating puzzle ... "<<endl;
  222.     generate();
  223.     show_puzzle();
  224.     show_keypress();
  225.     char ch;
  226.    
  227.     while(1){
  228.         cin.clear();
  229.         cin.get(ch);
  230.         switch(ch)
  231.         {
  232.         case 'a':
  233.             show_one_answer();
  234.             break;
  235.         case 'A':
  236.             show_all_answers();
  237.             break;
  238.         case 'n':
  239.         case 'N':
  240.             generate();
  241.             show_puzzle();
  242.             show_keypress();
  243.             break;
  244.         case 'q':
  245.         case 'Q':
  246.             return false;
  247.             break;
  248.         default:
  249.             cout<<": ";
  250.             break;
  251.         }
  252.     }
  253.     return true;
  254.    
  255. }
  256. void NumberGame::cal_target( vector<element> vt )
  257. {
  258.     vector<element>::iterator it,it1,it2;
  259.    
  260.     if(vt.empty())return;
  261.     if(vt.size()==1){
  262.         element e=vt.back();
  263.         if(e.data==target)result.push_back(e);
  264.         return;   
  265.     }
  266.     for(it1=vt.begin(); it1<vt.end()-1; it1++){
  267.         for(it2=it1+1; it2<vt.end(); it2++){
  268.             element e1=*it1;
  269.             element e2=*it2;                  
  270.             it2=vt.erase(it2); // remove 2 elements
  271.             it1=vt.erase(it1); // CAUTION: e2 should erase first !
  272.                
  273.             vt.push_back(e1+e2);
  274.             cal_target(vt);
  275.             vt.pop_back();
  276.                
  277.             vt.push_back(e1-e2);
  278.             cal_target(vt);
  279.             vt.pop_back();
  280.                
  281.             vt.push_back(e2-e1);
  282.             cal_target(vt);
  283.             vt.pop_back();
  284.                
  285.             vt.push_back(e1*e2);
  286.             cal_target(vt);
  287.             vt.pop_back();
  288.                
  289.             if(e2.data){
  290.                 vt.push_back(e1/e2);
  291.                 cal_target(vt);
  292.                 vt.pop_back();
  293.             }
  294.                
  295.             if(e1.data){
  296.                 vt.push_back(e2/e1);
  297.                 cal_target(vt);
  298.                 vt.pop_back();
  299.             }
  300.                
  301.             it1=vt.insert(it1,e1);  // recover vector               
  302.             it2=vt.insert(it2,e2);  // CAUTION: e1 should insert first !
  303.         }
  304.     }
  305.     return;
  306. }
  307. int main()
  308. {
  309.     NumberGame game;
  310.     cout<<"[1] user input"<<endl;
  311.     cout<<"[2] random test" <<endl;
  312.     cout<<"[0] quit"<<endl;
  313.     cout<<"select the number(0/1/2): ";
  314.     char ch;
  315.     cin.get(ch);
  316.     cin.clear();
  317.     switch(ch){
  318.     case '1':
  319.         while(game.input() && game.output());
  320.         break;
  321.     case '2':
  322.         game.random();
  323.         break;
  324.     default:
  325.         return 0;
  326.     }
  327. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-5-10 12:47:34 | 显示全部楼层
今天看精华,看到了这篇帖子, 找出了以前写的算 24 的程序:
  1. #include <stdio.h>
  2. void get_arr(int arr[][4], int numbers[], int len){
  3.   int i,j,k=0;
  4.   for(i=0;i<len;i++){
  5.     for(j=i+1;j<len;j++){
  6.       arr[k][0] = numbers[i];
  7.       arr[k][1] = numbers[j];
  8.       arr[k][2] = i;
  9.       arr[k++][3] = j;
  10.     }
  11.   }
  12. }
  13. void fill_arr(int to[], int len, int from[], int i, int j){
  14.   int _i,_j = 0;
  15.   for(_i=0;_i<len;_i++){
  16.     if(_i!=i && _i!=j)
  17.       to[_j++] = from[_i];
  18.   }
  19. }
  20. int calculate(int numbers[], int len, int sum){
  21.   int i,arr[len*(len-1)/2][4];
  22.   if(len==1){
  23.     if(numbers[0]==sum)
  24.       return 0;
  25.     return 1;
  26.   }
  27.   get_arr(arr,numbers,len);
  28.   for(i=0;i<len*(len-1);i++){
  29.     int _numbers[len-1];
  30.     fill_arr(_numbers,len,numbers,arr[i][2],arr[i][3]);
  31.     _numbers[len-2] = arr[i][0]+arr[i][1];
  32.     if(!calculate(_numbers,len-1,sum)){
  33.       printf("%d + %d = %d\n",arr[i][0],arr[i][1],arr[i][0]+arr[i][1]);
  34.       return 0;
  35.     }
  36.     _numbers[len-2] = arr[i][0]-arr[i][1];
  37.     if(_numbers[len-2]>0){
  38.       if(!calculate(_numbers,len-1,sum)){
  39.         printf("%d - %d = %d\n",arr[i][0],arr[i][1],arr[i][0]-arr[i][1]);
  40.         return 0;
  41.       }
  42.     }else{
  43.       _numbers[len-2] = -_numbers[len-2];
  44.     if(_numbers[len-2]>0){
  45.       if(!calculate(_numbers,len-1,sum)){
  46.         printf("%d - %d = %d\n",arr[i][0],arr[i][1],arr[i][0]-arr[i][1]);
  47.         return 0;
  48.       }
  49.     }else{
  50.       _numbers[len-2] = -_numbers[len-2];
  51.       if(!calculate(_numbers,len-1,sum)){
  52.         printf("%d - %d = %d\n",arr[i][1],arr[i][0],arr[i][1]-arr[i][0]);
  53.         return 0;
  54.       }
  55.     }
  56.     _numbers[len-2] = arr[i][0]*arr[i][1];
  57.     if(!calculate(_numbers,len-1,sum)){
  58.       printf("%d * %d = %d\n",arr[i][0],arr[i][1],arr[i][0]*arr[i][1]);
  59.       return 0;
  60.     }
  61.     if(arr[i][0] && !(arr[i][1]%arr[i][0])){
  62.       _numbers[len-2] = arr[i][1]/arr[i][0];
  63.       if(!calculate(_numbers,len-1,sum)){
  64.         printf("%d / %d = %d\n",arr[i][1],arr[i][0],arr[i][1]/arr[i][0]);
  65.         return 0;
  66.       }
  67.     }
  68.     if(arr[i][1] && !(arr[i][0]%arr[i][1])){
  69.       _numbers[len-2] = arr[i][0]/arr[i][1];
  70.       if(!calculate(_numbers,len-1,sum)){
  71.         printf("%d / %d = %d\n",arr[i][0],arr[i][1],arr[i][0]/arr[i][1]);
  72.         return 0;
  73.       }
  74.     }
  75.   }
  76.   return 1;
  77. }
  78. int main(){
  79.   int numbers[] = {3,2,6,4};
  80.   calculate(numbers,4,24);
  81.   return 0;
  82. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-5-10 12:49:22 | 显示全部楼层
还有一个 scheme 的:
  1. (define (get-composite numbers)
  2.   (letrec ((part (lambda (x alist)
  3.                    (map (lambda (y) (list x y)) alist))))
  4.     (if (null? numbers)
  5.         '()
  6.         (append (part (car numbers) (cdr numbers))
  7.                 (get-composite (cdr numbers))))))
  8. (define (remove-first x alist)
  9.   (cond ((null? alist) '())
  10.         ((= x (car alist)) (cdr alist))
  11.         (else (cons (car alist) (remove-first x (cdr alist))))))
  12. (define (remove-last x alist)
  13.   (reverse (remove-first x (reverse alist))))
  14. (define (iter1 numbers sum result composites)
  15.   (let ((remove-two (lambda (items alist)
  16.                       (remove-first (cadr items) (remove-first (car items) alist))))
  17.         (arg1 (if (not (null? composites))
  18.                   (caar composites)))
  19.         (arg2 (if (not (null? composites))
  20.                   (cadar composites))))
  21.     (if (null? composites)
  22.         'ok
  23.         (begin
  24.           (iter2 (cons (+ arg1 arg2)
  25.                        (remove-two (car composites) numbers))
  26.                  sum
  27.                  (append result (list (list arg1 '+ arg2 '= (+ arg1 arg2)))))
  28.           (iter2 (cons (- arg1 arg2)
  29.                        (remove-two (car composites) numbers))
  30.                  sum
  31.                  (append result (list (list arg1 '- arg2 '= (- arg1 arg2)))))
  32.           (iter2 (cons (- arg2 arg1)
  33.                        (remove-two (car composites) numbers))
  34.                  sum
  35.                  (append result (list (list arg2 '- arg1 '= (- arg2 arg1)))))
  36.           (iter2 (cons (* arg1 arg2)
  37.                        (remove-two (car composites) numbers))
  38.                  sum
  39.                  (append result (list (list arg1 '* arg2 '= (* arg1 arg2)))))
  40.           (if (and (not (= arg2 0)) (= 0 (remainder arg1 arg2)))
  41.               (iter2 (cons (/ arg1 arg2)
  42.                      (remove-two (car composites) numbers))
  43.                      sum
  44.                      (append result (list (list arg1 '/ arg2 '= (/ arg1 arg2))))))
  45.           (if (and (not (= arg1 0)) (= 0 (remainder arg2 arg1)))
  46.               (iter2 (cons (/ arg2 arg1)
  47.                      (remove-two (car composites) numbers))
  48.                      sum
  49.                      (append result (list (list arg2 '/ arg1 '= (/ arg2 arg1))))))
  50.           (iter1 numbers sum result (cdr composites))))))
  51. (define (iter2 numbers sum result)
  52.   (if (= (length numbers) 1)
  53.       (if (= (car numbers) sum)
  54.           (show result))
  55.       (iter1 numbers sum result (get-composite numbers))))
  56. (define (show list)
  57.   (display list)
  58.   (newline))
  59. (define (calculate numbers sum)
  60.   (iter2 numbers sum '()))
  61. (calculate '(13 3 7 5) 24)
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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