Untitled

 avatar
unknown
java
a month ago
5.4 kB
3
Indexable
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Random;

interface Operation {
    double execute(double num1, double num2);
}

class Addition implements Operation {
    @Override
    public double execute(double num1, double num2) {
        return num1 + num2;
    }
}

class Subtraction implements Operation {
    @Override
    public double execute(double num1, double num2) {
        return num1 - num2;
    }
}

class Multiplication implements Operation {
    @Override
    public double execute(double num1, double num2) {
        if (num1 == 0 || num2 == 0) return 0;
        if (num1 == 1) return num2;
        if (num2 == 1) return num1;
        return num1 * num2;
    }
}

class Division implements Operation {
    @Override
    public double execute(double num1, double num2) {
        if (num2 == 0) {
            throw new IllegalArgumentException("Cannot divide by zero");
        }
        if (num1 == 0) return 0;
        if (num2 == 1) return num1;
        return num1 / num2;
    }
}

public class Calculator {
    private final Map<String, Operation> operations = new HashMap<>();

    public Calculator() {
        operations.put("add", new Addition());
        operations.put("subtract", new Subtraction());
        operations.put("multiply", new Multiplication());
        operations.put("divide", new Division());
    }

    public double calculate(String operation, double num1, double num2) {
        Operation op = operations.get(operation.toLowerCase());
        if (op == null) {
            throw new UnsupportedOperationException("Unknown operation: " + operation);
        }
        return op.execute(num1, num2);
    }

    public List<Double> batchCalculate(List<String> operations, List<Double> num1s, List<Double> num2s) throws InterruptedException {
        if (operations.size() != num1s.size() || operations.size() != num2s.size()) {
            throw new IllegalArgumentException("Input lists must have the same size");
        }

        int threadCount = 4; // Default number of threads
        int size = operations.size();
        int chunkSize = (int) Math.ceil((double) size / threadCount);

        List<Thread> threads = new ArrayList<>();
        List<List<Double>> partialResults = new ArrayList<>();

        for (int i = 0; i < threadCount; i++) {
            int start = i * chunkSize;
            int end = Math.min(start + chunkSize, size);

            List<String> subOperations = operations.subList(start, end);
            List<Double> subNum1s = num1s.subList(start, end);
            List<Double> subNum2s = num2s.subList(start, end);
            List<Double> subResults = new ArrayList<>();
            partialResults.add(subResults);

            Thread thread = new Thread(() -> {
                for (int j = 0; j < subOperations.size(); j++) {
                    try {
                        subResults.add(calculate(subOperations.get(j), subNum1s.get(j), subNum2s.get(j)));
                    } catch (Exception e) {
                        subResults.add(Double.NaN);
                    }
                }
            });

            threads.add(thread);
            thread.start();
        }

        for (Thread thread : threads) {
            thread.join();
        }

        List<Double> output = new ArrayList<>(size);
        for (int i = 0; i < threadCount; i++) {
            output.addAll(partialResults.get(i));
        }

        return output;
    }

    public static void main(String[] args) {
        Calculator calculator = new Calculator();

        List<String> operations = new ArrayList<>();
        List<Double> num1s = new ArrayList<>();
        List<Double> num2s = new ArrayList<>();
        Random random = new Random();

        String[] operationTypes = {"add", "subtract", "multiply", "divide"};

        for (int i = 0; i < 2000000; i++) {
            operations.add(operationTypes[random.nextInt(operationTypes.length)]);
            num1s.add(random.nextDouble() * 100);
            num2s.add(random.nextDouble() * 100);
        }

        // Sequential calculation
        long startSequential = System.currentTimeMillis();
        List<Double> sequentialResults = new ArrayList<>();
        for (int i = 0; i < operations.size(); i++) {
            try {
                sequentialResults.add(calculator.calculate(operations.get(i), num1s.get(i), num2s.get(i)));
            } catch (Exception e) {
                sequentialResults.add(Double.NaN);
            }
        }
        long endSequential = System.currentTimeMillis();
        System.out.println("Sequential calculation time: " + (endSequential - startSequential) + " ms");

        // Batch calculation
        long startBatch = System.currentTimeMillis();
        try {
            List<Double> batchResults = calculator.batchCalculate(operations, num1s, num2s);
            long endBatch = System.currentTimeMillis();
            System.out.println("Batch calculation time: " + (endBatch - startBatch) + " ms");
        } catch (InterruptedException e) {
            System.out.println("Batch calculation interrupted: " + e.getMessage());
        }
    }
}
Leave a Comment