Function Pipeline (Composition)

Problem

The first line is a starting integer. Each next line is an operation: add X, mul X or square. Apply the operations in order and print the final value. Build the pipeline as a list of functions and combine them into one function.

Constraints

  • 1 <= lines <= 1000
  • the result fits in 2^53

Examples

Input

3
add 2
mul 4
square

Output

400

Solutions

Best approachTime O(n)Space O(n)

Functions are values: we store them in a list and combine them. In the Python lambda we pass amount as a default argument, so each lambda keeps its own value. Without it all lambdas would share the last amount.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Function pipeline.
 * Input   : Start value, then operation lines.
 * Output  : The final value.
 * Approach: Compose functions.
 * Time    : O(n)
 * Space   : O(n)
 * 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(String[] lines) {
        // Step 1: Start with a function that returns its input (the identity function).
        java.util.function.LongUnaryOperator pipeline = value -> value;

        // Step 2: For each operation line, make a small function and join it at the end with andThen.
        for (int i = 1; i < lines.length; i++) {
            String[] parts = lines[i].split(" ");
            java.util.function.LongUnaryOperator step;
            if (parts[0].equals("add")) {
                long amount = Long.parseLong(parts[1]);
                step = value -> value + amount;
            } else if (parts[0].equals("mul")) {
                long amount = Long.parseLong(parts[1]);
                step = value -> value * amount;
            } else {
                step = value -> value * value;
            }
            pipeline = pipeline.andThen(step);
        }

        // Step 3: Run the one combined function on the starting number.
        return pipeline.applyAsLong(Long.parseLong(lines[0]));
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        java.util.List<String> all = new java.util.ArrayList<>();
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine().trim();
            if (!line.isEmpty()) {
                all.add(line);
            }
        }
        String[] lines = all.toArray(new String[0]);
        System.out.println(solve(lines));
    }
}
Hints (1)
  1. What does andThen do?