Async Tasks: Combine Results

Problem

Two tasks run at the same time: the first computes a * a, the second computes b + 10. When both are finished, add their results, and then multiply the sum by 2. Print the final number. Use the async chain tools (CompletableFuture with supplyAsync, thenCombine and thenApply in Java; futures in a thread pool in Python; JavaScript shows the same steps in one thread).

Constraints

  • |a|, |b| <= 10^6

Examples

Input

3 4

Output

46

Solutions

Best approachTime O(1)Space O(1)

The two tasks have no dependency on each other, so they may run in parallel; the combine step must wait for both. This 'fan out, then fan in' shape is typical for calls to several services. In Java, join() throws unchecked exceptions, get() throws checked ones.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Combine async results.
 * Input   : Two integers a and b.
 * Output  : One integer.
 * Approach: Futures.
 * Time    : O(1)
 * Space   : O(1)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static long solve(long a, long b) {
        // Step 1: supplyAsync starts a task on another thread and returns a CompletableFuture, a promise of a result.
        java.util.concurrent.CompletableFuture<Long> square = java.util.concurrent.CompletableFuture.supplyAsync(() -> a * a);
        java.util.concurrent.CompletableFuture<Long> shifted = java.util.concurrent.CompletableFuture.supplyAsync(() -> b + 10);
        // Step 2: thenCombine waits for both tasks and then adds their results. thenApply changes the combined result.
        java.util.concurrent.CompletableFuture<Long> result = square.thenCombine(shifted, (x, y) -> x + y).thenApply(sum -> sum * 2);
        // Step 3: join() waits for the final result. It does not throw a checked exception.
        return result.join();
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        long a = scanner.nextLong();
        long b = scanner.nextLong();
        System.out.println(solve(a, b));
    }
}
Hints (1)
  1. Which step must wait for both tasks?