Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looking for arithmetic operations that result in 24

I'm writing a program that evaluates the integer values of 4 playing cards (numbers 1-13), and displays a solution that equals 24. I have a large if statement that I've written for this and have realized that there are just too many solutions to add them all. I'm looking for advice on how to condense this into a more optimized version. The code is running fine with no errors, here is my entire code:

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import javafx.scene.image.ImageView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicReference;
import java.util.*;

public class Main extends Application {

   private Card card1;
   private Card card2;
   private Card card3;
   private Card card4;

   private int a;
   private int b;
   private int c;
   private int d;
   private int e=0;
   private int f=0;
   boolean par=false;


   @Override
   public void start(Stage primaryStage) {

      ArrayList<Integer> deck;
      deck = new ArrayList<>();
      int i = 1;
      while(i < 52){
         deck.add(i);
         i++;
      }
      final AtomicReference<String> result = new AtomicReference<>("");

      Collections.shuffle(deck);

      BorderPane pane = new BorderPane();

      HBox top = new HBox(10);
      Label display = new Label(result.toString());
      Button btShuffle = new Button("Shuffle");
      Button fiSolution = new Button("Find Solution");
      TextField solfield = new TextField();
      VBox bottomBox = new VBox();

      top.getChildren().add(fiSolution);
      top.getChildren().add(solfield);
      top.getChildren().add(btShuffle);

      HBox center = new HBox(10);

      card1 = new Card(deck.get(0));
      center.getChildren().add(card1);

      card2 = new Card(deck.get(1));
      center.getChildren().add(card2);

      card3 = new Card(deck.get(3));
      center.getChildren().add(card3);

      card4 = new Card(deck.get(4));
      center.getChildren().add(card4);


      //String str1 = solfield.setText();

      fiSolution.setOnAction(
            (ActionEvent e) -> {

               a = card1.CardValue();
               b = card2.CardValue();
               c = card3.CardValue(); 
               d = card4.CardValue();



              if (a+b+c+d == 24)
                  solfield.setText(a+"+"+b+"+"+c+"+"+d);
               else if (a+b+c-d == 24)
                  solfield.setText(a+"+"+b+"+"+c+"-"+d);
               else if (a-b+c+d == 24)
                  solfield.setText(a+"+-"+b+"+"+c+"+"+d);   
               else if (a+b-c+d == 24)
                  solfield.setText(a+"+"+b+"-"+c+"+"+d);
               else if ((((a+b)-c)*d)==24)
                  solfield.setText(a+"+"+b+"-"+c+"*"+d);
               else if ((((a+b)-c)/d)==24)
                  solfield.setText(a+"+"+b+"-"+c+"/"+d);
               else if ((((a+b)/c)-d)==24)
                  solfield.setText(a+"+"+b+"/"+c+"-"+d);
               else if ((((a+b)/c)*d)==24)
                  solfield.setText(a+"+"+b+"/"+c+"*"+d);
               else if ((((a+b)*c)/d)==24)
                  solfield.setText(a+"+"+b+"*"+c+"/"+d);
               else if ((((a+b)*c)-d)==24)
                  solfield.setText(a+"+"+b+"*"+c+"-"+d);
               else if ((((a-b)+c)*d)==24)
                  solfield.setText(a+"-"+b+"+"+c+"*"+d);
               else if ((((a-b)+c)/d)==24)
                  solfield.setText(a+"-"+b+"+"+c+"/"+d);
               else if ((((a-b)/c)+d)==24)
                  solfield.setText(a+"-"+b+"/"+c+"+"+d);
               else if ((((a-b)/c)*d)==24)
                  solfield.setText(a+"-"+b+"/"+c+"*"+d);
               else if ((((a-b)*c)/d)==24)
                  solfield.setText(a+"-"+b+"*"+c+"/"+d);
               else if ((((a-b)*c)+d)==24)
                  solfield.setText(a+"-"+b+"*"+c+"+"+d);
               else if ((((a*b)+c)/d)==24)
                  solfield.setText(a+"*"+b+"+"+c+"/"+d);
               else if ((((a*b)+c)-d)==24)
                  solfield.setText(a+"*"+b+"+"+c+"-"+d);
               else if ((((a*b)-c)/d)==24)
                  solfield.setText(a+"*"+b+"-"+c+"/"+d);
               else if ((((a*b)-c)+d)==24)
                  solfield.setText(a+"*"+b+"-"+c+"+"+d);
               else if ((((a*b)/c)+d)==24)
                  solfield.setText(a+"*"+b+"/"+c+"+"+d);
               else if ((((a*b)/c)-d)==24)
                  solfield.setText(a+"*"+b+"/"+c+"-"+d);
               else if ((((a/b)+c)*d)==24)
                  solfield.setText(a+"/"+b+"+"+c+"*"+d);
               else if ((((a/b)+c)-d)==24)
                  solfield.setText(a+"/"+b+"+"+c+"-"+d);
               else if ((((a/b)-c)+d)==24)
                  solfield.setText(a+"/"+b+"-"+c+"+"+d);
               else if ((((a/b)-c)*d)==24)
                  solfield.setText(a+"/"+b+"-"+c+"*"+d);
               else if ((((a/b)*c)-d)==24)
                  solfield.setText(a+"/"+b+"*"+c+"-"+d);
               else if ((((a/b)*c)+d)==24)
                  solfield.setText(a+"/"+b+"*"+c+"+"+d);


               f=c+d;
               if (((a/b)*f)==24)
                  solfield.setText(a+"/"+b+"*("+c+"+"+d+")");
               else if (((a/b)-f)==24)
                  solfield.setText(a+"/"+b+"-("+c+"+"+d+")");
               else if (((a*b)-f)==24)
                  solfield.setText(a+"*"+b+"-("+c+"+"+d+")");
               else if (((a*b)/f)==24)
                  solfield.setText(a+"*"+b+"/("+c+"+"+d+")");
               else if (((a-b)*f)==24)
                  solfield.setText(a+"-"+b+"*("+c+"+"+d+")");
               else if (((a-b)/f)==24)
                  solfield.setText(a+"-"+b+"/("+c+"+"+d+")");

               f=c-d;
               if (((a/b)*f)==24)
                  solfield.setText(a+"/"+b+"*("+c+"-"+d+")");
               else if (((a/b)+f)==24)
                  solfield.setText(a+"/"+b+"+("+c+"-"+d+")");
               else if (((a*b)+f)==24)
                  solfield.setText(a+"*"+b+"+("+c+"-"+d+")");
               else if (((a*b)/f)==24)
                  solfield.setText(a+"*"+b+"/("+c+"-"+d+")");
               else if (((a+b)*f)==24)
                  solfield.setText(a+"+"+b+"*("+c+"-"+d+")");
               else if (((a+b)/f)==24)
                  solfield.setText(a+"+"+b+"/("+c+"-"+d+")");

               f=c*d;
               if (((a/b)-f)==24)
                  solfield.setText(a+"/"+b+"*("+c+"*"+d+")");
               else if (((a/b)+f)==24)
                  solfield.setText(a+"/"+b+"+("+c+"*"+d+")");
               else if (((a-b)+f)==24)
                  solfield.setText(a+"-"+b+"+("+c+"*"+d+")");
               else if (((a-b)/f)==24)
                  solfield.setText(a+"-"+b+"/("+c+"*"+d+")");
               else if (((a+b)-f)==24)
                  solfield.setText(a+"+"+b+"-("+c+"*"+d+")");
               else if (((a+b)/f)==24)
                  solfield.setText(a+"+"+b+"/("+c+"*"+d+")");

               f=c/d;
               if (((a-b)*f)==24)
                  solfield.setText(a+"-"+b+"*("+c+"/"+d+")");
               else if (((a-b)+f)==24)
                  solfield.setText(a+"-"+b+"+("+c+"/"+d+")");
               else if (((a*b)+f)==24)
                  solfield.setText(a+"*"+b+"+("+c+"/"+d+")");
               else if (((a*b)-f)==24)
                  solfield.setText(a+"*"+b+"-("+c+"/"+d+")");
               else if (((a+b)*f)==24)
                  solfield.setText(a+"+"+b+"*("+c+"/"+d+")");
               else if (((a+b)-f)==24)
                  solfield.setText(a+"+"+b+"-("+c+"/"+d+")");

               f=b*c;
               if (((a-f)/d)==24)
                  solfield.setText(a+"-("+b+"*"+c+")/"+d);
               else if (((a-f)+d)==24)
                  solfield.setText(a+"-("+b+"*"+c+")+"+d);
               else if (((a/f)+d)==24)
                  solfield.setText(a+"/("+b+"*"+c+")+"+d);
               else if (((a/f)-d)==24)
                  solfield.setText(a+"/("+b+"*"+c+")-"+d);
               else if (((a+f)/d)==24)
                  solfield.setText(a+"+("+b+"*"+c+")/"+d);
               else if (((a+f)-d)==24)
                  solfield.setText(a+"+("+b+"*"+c+")-"+d);

               f=b-c;
               if (((a*f)/d)==24)
                  solfield.setText(a+"*("+b+"-"+c+")/"+d);
               else if (((a*f)+d)==24)
                  solfield.setText(a+"*("+b+"-"+c+")+"+d);
               else if (((a/f)+d)==24)
                  solfield.setText(a+"/("+b+"-"+c+")+"+d);
               else if (((a/f)*d)==24)
                  solfield.setText(a+"/("+b+"-"+c+")*"+d);

               f=b/c;
               if (((a-f)*d)==24)
                  solfield.setText(a+"-("+b+"/"+c+")*"+d);
               else if (((a-f)+d)==24)
                  solfield.setText(a+"-("+b+"/"+c+")+"+d);
               else if (((a*f)+d)==24)
                  solfield.setText(a+"*("+b+"/"+c+")+"+d);
               else if (((a*f)-d)==24)
                  solfield.setText(a+"*("+b+"/"+c+")-"+d);
               else if (((a+f)*d)==24)
                  solfield.setText(a+"+("+b+"/"+c+")*"+d);
               else if (((a+f)-d)==24)
                  solfield.setText(a+"+("+b+"/"+c+")-"+d);

               f=b+c;
               if (((a*f)/d)==24)
                  solfield.setText(a+"*("+b+"+"+c+")/"+d);
               else if (((a*f)-d)==24)
                  solfield.setText(a+"*("+b+"+"+c+")-"+d);
               else if (((a/f)-d)==24)
                  solfield.setText(a+"/("+b+"+"+c+")-"+d);
               else if (((a/f)*d)==24)
                  solfield.setText(a+"/("+b+"+"+c+")*"+d);






            });

      btShuffle.setOnAction(
            e -> {
               center.getChildren().clear();  
               Collections.shuffle(deck);
               card1 = new Card(deck.get(0));
               card2 = new Card(deck.get(1));
               card3 = new Card(deck.get(2));
               card4 = new Card(deck.get(3));

               center.getChildren().add(card1);
               center.getChildren().add(card2);           
               center.getChildren().add(card3);
               center.getChildren().add(card4);

            });

      HBox bottom = new HBox(10);
      Label expression = new Label("Please Enter the expression: ");

      TextField tfExpress = new TextField();

      String str = tfExpress.getText();       

      Button btVerify = new Button("Verify");
      bottom.getChildren().add(expression);
      bottom.getChildren().add(tfExpress);
      bottom.getChildren().add(btVerify);

      bottomBox.getChildren().add(bottom);
      bottomBox.getChildren().add(display);

      btVerify.setOnAction(
            (ActionEvent e) -> 
            {               
               String regex = ("[^0-9]+");
               String[] inputIntegers = tfExpress.getText().split(regex);

              // expInput.removeIf(p-> p.equals(signs));
               ArrayList<Integer> temp = new ArrayList<>();
               temp.add(new Integer(card1.CardValue()));
               temp.add(new Integer(card2.CardValue()));                    
               temp.add(new Integer(card3.CardValue()));          
               temp.add(new Integer(card4.CardValue())); 

               if(inputIntegers.length != 0)
               {
                  if (inputIntegers.length != 0) {
                     for (String s : inputIntegers) {
                        if (!s.equals(""))
                           temp.remove(new Integer(Integer.valueOf(s)));
                     }
                  }        
               }

               if(temp.isEmpty())
               {
                  if(evaluateExpression(tfExpress.getText()) == 24){
                     display.setText("Correct");
                  }
                  else
                     display.setText("Incorrect");
               }
               else
                  display.setText("The numbers in the expression don't "
                     + "match the numbers in the set.");
            });

      pane.setTop(top);
      pane.setCenter(center);
      pane.setBottom(bottomBox);


      Scene scene = new Scene(pane);
      primaryStage.setTitle("24 card game");
      primaryStage.setScene(scene);
      primaryStage.show();
   }

   public boolean Twentyfour(boolean par){
   //some people play the game with or without parentheses.
      this.par=par;

      return par;
   }

   /** Evaluate an expression */
   public static int evaluateExpression(String expression) {
    // Create operandStack to store operands
      Stack<Integer> operandStack = new Stack<Integer>();

    // Create operatorStack to store operators
      Stack<Character> operatorStack = new Stack<Character>();

    // Insert blanks around (, ), +, -, /, and *
      expression = insertBlanks(expression);

    // Extract operands and operators
      String[] tokens = expression.split(" ");

    // Phase 1: Scan tokens
      for (String token: tokens) {
         if (token.length() == 0) // Blank space
            continue; // Back to the while loop to extract the next token
         else if (token.charAt(0) == '+' || token.charAt(0) == '-') {
         // Process all +, -, *, / in the top of the operator stack 
            while (!operatorStack.isEmpty() &&
            (operatorStack.peek() == '+' || 
            operatorStack.peek() == '-' ||
            operatorStack.peek() == '*' ||
            operatorStack.peek() == '/')) {
               processAnOperator(operandStack, operatorStack);
            }

         // Push the + or - operator into the operator stack
            operatorStack.push(token.charAt(0));
         }
         else if (token.charAt(0) == '*' || token.charAt(0) == '/') {
         // Process all *, / in the top of the operator stack 
            while (!operatorStack.isEmpty() &&
            (operatorStack.peek() == '*' ||
            operatorStack.peek() == '/')) {
               processAnOperator(operandStack, operatorStack);
            }

         // Push the * or / operator into the operator stack
            operatorStack.push(token.charAt(0));
         }
         else if (token.trim().charAt(0) == '(') {
            operatorStack.push('('); // Push '(' to stack
         }
         else if (token.trim().charAt(0) == ')') {
         // Process all the operators in the stack until seeing '('
            while (operatorStack.peek() != '(') {
               processAnOperator(operandStack, operatorStack);
            }

            operatorStack.pop(); // Pop the '(' symbol from the stack
         }
         else { // An operand scanned
         // Push an operand to the stack
            operandStack.push(new Integer(token));
         }
      }

    // Phase 2: process all the remaining operators in the stack 
      while (!operatorStack.isEmpty()) {
         processAnOperator(operandStack, operatorStack);
      }

    // Return the result
      return operandStack.pop();
   }

  /** Process one operator: Take an operator from operatorStack and
   *  apply it on the operands in the operandStack */
   public static void processAnOperator(
      Stack<Integer> operandStack, Stack<Character> operatorStack) {
      char op = operatorStack.pop();
      int op1 = operandStack.pop();
      int op2 = operandStack.pop();
      if (op == '+') 
         operandStack.push(op2 + op1);
      else if (op == '-') 
         operandStack.push(op2 - op1);
      else if (op == '*') 
         operandStack.push(op2 * op1);
      else if (op == '/') 
         operandStack.push(op2 / op1);
   }

   public static String insertBlanks(String s) {
      String result = "";

      for (int i = 0; i < s.length(); i++) 
      {
         if (s.charAt(i) == '(' || s.charAt(i) == ')' || 
          s.charAt(i) == '+' || s.charAt(i) == '-' ||
          s.charAt(i) == '*' || s.charAt(i) == '/')
            result += " " + s.charAt(i) + " ";
         else
            result += s.charAt(i);
      }

      return result;
   }

   public class Card extends Pane {
      public int cardVal;
      Card(int card){
         Image cardImage;
         cardImage = new Image("card/"+ card +".png");
         getChildren().add(new ImageView(cardImage));
         cardVal = card;
      }

      public int CardValue(){
         int card = 0;

         if(cardVal <= 13){
            card = cardVal;
         }
         else if(cardVal > 13 && cardVal <= 26){
            card = cardVal - 13;
         }
         else if(cardVal > 26 && cardVal <= 39){
            card = cardVal - 26;
         }
         else if(cardVal > 39 && cardVal <= 52){
            card = cardVal - 39;
         }

         return card;
      }
   }

   public static void main(String[] args) {
      launch(args);
   }
}
like image 737
John Doe Avatar asked May 06 '15 15:05

John Doe


1 Answers

An enum could help here.

I'm not sure I have it complete as I am not sure I have implemented all of the possible bracketing but it looks complete to me now.

enum Op {

    Add("+") {

                @Override
                int op(int a, int b) {
                    return a + b;
                }

            },
    Sub("-") {

                @Override
                int op(int a, int b) {
                    return a - b;
                }

            },
    Mul("*") {

                @Override
                int op(int a, int b) {
                    return a * b;
                }

            },
    Div("/") {

                @Override
                int op(int a, int b) {
                    // Insane value for / 0 to ensure unlikely to match.
                    return b != 0 ? a / b : Integer.MAX_VALUE;
                }

            };
    final String asString;

    Op(String asString) {
        this.asString = asString;
    }

    public String toString() {
        return asString;
    }

    abstract int op(int a, int b);
}

private void tryAllOrders(int a, int b, int c, int d, Op op1, Op op2, Op op3, int target) {
    if (op3.op(op2.op(op1.op(a, b), c), d) == target) {
        System.out.println("    ((" + a + op1 + b + ")" + op2 + c + ")" + op3 + d + "=" + target);
    }
    if (op3.op(op1.op(a, op2.op(b, c)), d) == target) {
        System.out.println("    (" + a + op1 + "(" + b + op2 + c + "))" + op3 + d + "=" + target);
    }
    if (op2.op(op1.op(a, b), op3.op(c, d)) == target) {
        System.out.println("    (" + a + op1 + b + ")" + op2 + "(" + c + op3 + d + ")=" + target);
    }
    if (op1.op(a, op3.op(op2.op(b, c), d)) == target) {
        System.out.println("    " + a + op1 + "((" + b + op2 + c + ")" + op3 + d + ")=" + target);
    }
    if (op1.op(a, op2.op(b, op3.op(c, d))) == target) {
        System.out.println("    " + a + op1 + "(" + b + op2 + "(" + c + op3 + d + "))=" + target);
    }
}

private void tryAllOps(int a, int b, int c, int d, int target) {
    for (Op op1 : Op.values()) {
        for (Op op2 : Op.values()) {
            for (Op op3 : Op.values()) {
                tryAllOrders(a, b, c, d, op1, op2, op3, target);
            }
        }
    }
}

public void test() {
    int target = 24;
    for (int a = 1; a <= 13; a++) {
        for (int b = 1; b <= 13; b++) {
            for (int c = 1; c <= 13; c++) {
                for (int d = 1; d <= 13; d++) {
                    tryAllOps(a, b, c, d, target);
                }

            }

        }
    }
}

It prints:

((1+1)+1)*8=24
(1+(1+1))*8=24
(1+1)*(1+11)=24
((1+1)*1)*12=24
(1+(1*1))*12=24
(1+1)*(1*12)=24
...
7+((11*8)/5)=24
((7+11)*8)/6=24
((7-11)+8)*6=24
(7-(11-8))*6=24
((7+11)/8)*12=24
(7/(11-8))*12=24
...
((13/13)*13)+11=24
(13/13)*(13+11)=24
(13/(13/13))+11=24
((13+13)/13)*12=24
(13-(13/13))+12=24
13-((13/13)-12)=24

There's a total of 67,752 results.

like image 80
OldCurmudgeon Avatar answered Sep 22 '22 16:09

OldCurmudgeon