-3

This is my homework. I can't figure it out with an algorithm. Please help me. It's better to use C++/C.

UPDATE: I'm sorry that I didn't describe this problem clearly. vivek_23: "I have assumed you meant to use 8 as is and use +,-,*,/ between them and not attaching 8's with each other to have numbers like 88,888,8888 etc." What he said is what I mean.

Here is the codes from my friend.

#include <iostream>  
#include <string>  
#include <cstdlib>  
#include <ctime>  
#include <cmath>
#include <map>
#include <set>
using namespace std;  

const double EPS = 1e-6;  
const int NUM = 8;  
const int RES = 1000;  

double A[NUM];  
string res_str[NUM];  
set<string> ans; 
set<string>::iterator it;
int times = 0;  

bool dfs(int n)  
{  
    // 退出条件  
    if (n==1)  
    {  
        if (fabs(A[0]-RES)<EPS)  
        {  
//            cout << res_str[0] << endl;
            ans.insert(res_str[0]);  
        }  
    }  

    double a, b;  
    string expa, expb;  
    map<int ,int> hash;
    hash.clear();

    for (int i=0; i<n; i++)  
        for (int j=i+1; j<n; j++)  
        {                 
            times++;  
            // 保存状态(操作数i,j)  
            a = A[i];  
            b = A[j];  
            expa = res_str[i];  
            expb = res_str[j];  

            //hash判重 
            if(hash[a] == b) continue;
            if(hash[b] == a) continue;
            hash[a] = b;

            // 改变状态  
            A[j] = A[n-1];  
            res_str[j] = res_str[n-1];  

            // + 
            A[i] = a+b;  
            res_str[i] = '(' + expa + '+' + expb + ')';  
            if (dfs(n-1))  
                return true;  

            // -    
            A[i] = a-b;  
            res_str[i] = '(' + expa + '-' + expb + ')';  
            if (dfs(n-1))  
                return true;

            // - 反方向  
            A[i] = b-a;  
            res_str[i] = '(' + expb + '-' + expa + ')';  
            if (dfs(n-1))  
                return true;  

            // *
            A[i] = a*b;  
            res_str[i] = '(' + expa + '*' + expb + ')';  
            if (dfs(n-1))  
                return true;  

            // /
            if (b!=0)  
            {  
                A[i] = a/b;  
                res_str[i] = '(' + expa + '/' + expb + ')';  
                if (dfs(n-1))  
                    return true;  
            }  

            // /反方向 
            if (a!=0)  
            {  
                A[i] = b/a;  
                res_str[i] = '(' + expb + '/' + expa + ')';  
                if (dfs(n-1))  
                    return true;  
            }  

            // 恢复状态  
            A[i] = a;  
            A[j] = b;  
            res_str[i] = expa;  
            res_str[j] = expb;  
        }  
    return false;  
}  


int main()  
{  
    for (int i=0; i<NUM; i++)  
    {  
        A[i] = 8; 
        char c[10];  
        sprintf(c,"%.0f",A[i]);  
        res_str[i] = c;  
    }  
    cout<<"开始搜索"<<endl;
    clock_t start = clock();
    dfs(NUM);  
    for(it = ans.begin(); it != ans.end();it ++)
    {
        cout<<*it<<endl;
    }
}  
Jaycee Zhou
  • 69
  • 1
  • 5
  • You should perhaps explain your question and show what you have done so far – Maytham Fahmi Oct 24 '18 at 14:05
  • There are only 4^7 possibilities to place the operators.Write a brute force program to do that. – xrisk Oct 24 '18 at 14:05
  • 1
    You can use this answer: https://stackoverflow.com/questions/50240628/all-possibilities-to-put-or-nothing-between-numbers-to-get-sum-equal-to-100 - just change the sum and numbers to 8. For this specific problem use: 888+88+8+8+8 – dWinder Oct 24 '18 at 14:37

2 Answers2

-1

A starting point:

int two = (8 + 8) / 8;
int ten = 8 + two;
int oneThousand = ten * ten * ten;
Ollie
  • 7
  • 2
-1
  • I hope you will find my answer helpful.
  • ASSUMPTION: I have assumed you meant to use 8 as is and use +,-,*,/ between them and not attaching 8's with each other to have numbers like 88,888,8888 etc.

  • There will be lot of permutations for eight 8s' to be evaluated. So, in my code, I have sticked with 7 8s' to produce 1000.

  • I have coded this in Java and left as an exercise to you to convert it into C/C++. Below is my code and output-

CODE:

import java.util.*;
class Expression{
    String expression;
    double value;
    Expression(String exp,double val){
        expression = exp;
        value = val;
    }
}
public class Solution {
    public static void main(String[] args) {
        expressions(1000,8,7);
    }

    private static void expressions(int sum,int digit,int freq){
        Map<Integer,List<Expression>> memo = new HashMap<>();
        List<Expression> temp = new ArrayList<>();
        temp.add(new Expression(Integer.toString(digit),(double)digit));
        memo.put(1,temp);
        for(int i=2;i<=freq;++i){
            List<Expression> permutations = new ArrayList<>();
            for(int j=1;j<i;++j){
                List<Expression> part1 = memo.get(j);
                List<Expression> part2 = memo.get(i-j);
                int size1 = part1.size();
                int size2 = part2.size();
                for(int k=0;k<size1;++k){
                    Expression first = part1.get(k);
                    for(int l=0;l<size2;++l){
                        Expression second = part2.get(l);    
                        permutations.add(new Expression("(" + first.expression + "+" + second.expression + ")",first.value + second.value));
                        permutations.add(new Expression("(" + first.expression + "-" + second.expression + ")",first.value - second.value));
                        permutations.add(new Expression("(" + first.expression + "*" + second.expression + ")",first.value * second.value));
                        permutations.add(new Expression("(" + first.expression + "/" + second.expression + ")",second.value == (double)0 ? (double)0 : first.value / second.value));
                    }
                }
            }
            memo.put(i,permutations);
        }

        List<Expression> res = memo.get(freq);
        int size = res.size();
        for(int i=0;i<size;++i){
            if(res.get(i).value == (double)sum){
                System.out.println(res.get(i).expression + " = " + res.get(i).value);
            }
        }
    }
}

OUTPUT:

((8*(8*(8+8)))-(8+(8+8))) = 1000.0
((8*(8*(8+8)))-((8+8)+8)) = 1000.0
((8*((8+8)*8))-(8+(8+8))) = 1000.0
((8*((8+8)*8))-((8+8)+8)) = 1000.0
(((8+8)*(8*8))-(8+(8+8))) = 1000.0
(((8+8)*(8*8))-((8+8)+8)) = 1000.0
(((8*8)*(8+8))-(8+(8+8))) = 1000.0
(((8*8)*(8+8))-((8+8)+8)) = 1000.0
(((8*(8+8))*8)-(8+(8+8))) = 1000.0
(((8*(8+8))*8)-((8+8)+8)) = 1000.0
((((8+8)*8)*8)-(8+(8+8))) = 1000.0
((((8+8)*8)*8)-((8+8)+8)) = 1000.0
(((8*(8*(8+8)))-8)-(8+8)) = 1000.0
(((8*((8+8)*8))-8)-(8+8)) = 1000.0
((((8+8)*(8*8))-8)-(8+8)) = 1000.0
((((8*8)*(8+8))-8)-(8+8)) = 1000.0
((((8*(8+8))*8)-8)-(8+8)) = 1000.0
(((((8+8)*8)*8)-8)-(8+8)) = 1000.0
(((8+8)*((8*8)-(8/8)))-8) = 1000.0
(((8*(8*(8+8)))-(8+8))-8) = 1000.0
(((8*((8+8)*8))-(8+8))-8) = 1000.0
((((8+8)*(8*8))-(8+8))-8) = 1000.0
((((8*8)*(8+8))-(8+8))-8) = 1000.0
((((8*8)-(8/8))*(8+8))-8) = 1000.0
((((8*(8+8))*8)-(8+8))-8) = 1000.0
(((((8+8)*8)*8)-(8+8))-8) = 1000.0
((((8*(8*(8+8)))-8)-8)-8) = 1000.0
((((8*((8+8)*8))-8)-8)-8) = 1000.0
(((((8+8)*(8*8))-8)-8)-8) = 1000.0
(((((8*8)*(8+8))-8)-8)-8) = 1000.0
(((((8*(8+8))*8)-8)-8)-8) = 1000.0
((((((8+8)*8)*8)-8)-8)-8) = 1000.0
nice_dev
  • 17,053
  • 2
  • 21
  • 35
  • Ok, if someone is downvoting please mention the reason. It takes efforts to give an answer. Also, you can't say I spoon feeded since my code is not in OP's choice of language. He still needs to do a lot to convert it. First is OP needs to understand the algorithm. – nice_dev Oct 24 '18 at 16:38
  • 1
    I want to upvote your answer but I only have 7 reputation left. So it can't be displayed. Plus thanks for your help! – Jaycee Zhou Oct 25 '18 at 06:07
  • @JayceeZhou You are welcome. You can still upvote my answer. Reputation should not be a problem. Also, if my answer answered your question, can you please consider accepting it(via tick mark)? – nice_dev Oct 25 '18 at 06:43
  • I change the parameter 'freq' from 12 to 8, but why there are no outputs. In fact, it seems that there are 48 possible answers in total. For example, (8-(((8/(8+8))-(8+8))*(8*8))) – Jaycee Zhou Oct 26 '18 at 08:12
  • @JayceeZhou Yes, mine did not give results because I considered integer division over float division, so `8/(8+8)` was giving `0` instead of `0.5`. Secondly, I noticed that I missed a lot of permutations to evaluate. Hence, I have edited my answer and posted an updated correct code. However, now it can't produce permutations for 8 8s' because there a lot of them to evaluate and I get a OutOfMemory error. I hope my current answer gets you the idea of generating permutations. – nice_dev Oct 26 '18 at 13:20
  • @JayceeZhou Code from your friend seems fine and you could go with it. – nice_dev Oct 26 '18 at 13:24
  • I ran your code just now and it didn't give me a OutOfMemory error. I got 136 possible answers in total lol. Thank u!! Seems that my friend didn't get all of them. – Jaycee Zhou Oct 26 '18 at 14:13
  • @JayceeZhou Great!! Looks like your PC has some different specs. See what I got when I ran it in my PC [OutOfMemory Error](https://imgur.com/a/eMOujTm) – nice_dev Oct 26 '18 at 14:20
  • Aha maybe you could try IntelliJ IDEA, sometimes I just got weird errors using command prompt but it ran well in IntelliJ IDEA. I can't explain this haha. – Jaycee Zhou Oct 26 '18 at 14:28
  • @JayceeZhou Lol, sure, I would try IntelliJ IDEA. – nice_dev Oct 26 '18 at 14:32