Retry a Task (Higher-Order Function)

Problem

A task fails on its first f attempts and works on the next one. Write a function retry that takes the task as an argument and runs it up to m times, stopping at the first success. Print ok after N (N is the number of attempts used) if it worked, or failed after M if all m attempts failed. Input: f and m.

Constraints

  • 0 <= f <= 100
  • 1 <= m <= 100

Examples

Input

2 3

Output

ok after 3

Input

3 3

Output

failed after 3

Solutions

Best approachTime O(m)Space O(1)

The retry rule (how often, when to stop) is written once. The task is a parameter, so the same retry works for any task: a network call, a file read, and so on.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Retry the task.
 * Input   : f and m.
 * Output  : One line.
 * Approach: Task passed as argument
 * Time    : O(m)
 * Space   : O(1)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
        // Step 1: A task is any piece of code that can be run for a given attempt number. It throws an exception when it fails.
        interface Task {
            void run(int attempt) throws Exception;
        }

        // Step 2: retry is a higher-order function: it receives the task and decides how often to run it. It returns the attempts used, or -1.
        static int retry(Task task, int max) {
            for (int attempt = 1; attempt <= max; attempt++) {
                try {
                    task.run(attempt);
                    return attempt;
                } catch (Exception e) {
                    // Step 3: A failure is not the end. The loop tries again.
                }
            }
            return -1;
        }

    // This method solves the task. It receives the input and returns the answer.
    static String[] solve(long a, long b) {
        final int failures = (int) a;
        int max = (int) b;
        int used = retry(attempt -> {
            if (attempt <= failures) {
                throw new IllegalStateException("fail");
            }
        }, max);
        return new String[] {used > 0 ? "ok after " + used : "failed after " + max};
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        long a = scanner.nextLong();
        long b = scanner.nextLong();
        System.out.println(String.join("\n", solve(a, b)));
    }
}
Hints (2)
  1. What does retry know about the task?
  2. What does the task know about retry?