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
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.
/*
* 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)
- What does retry know about the task?
- What does the task know about retry?