The underlying concepts of UVa 371: Ackermann Functions have been discussed in great details in our post of Collatz problem. In this post, we simply outlines an ad-hoc algorithm as a solution to this problem as follows.
import java.io.PrintWriter; | |
import java.util.Scanner; | |
public class Main { | |
private final Scanner in; | |
private final PrintWriter out; | |
private final static int _MaxValue = 1000000; | |
private final static long[] memo = new long[_MaxValue]; | |
public Main() { | |
in = new Scanner(System.in); | |
out = new PrintWriter(System.out, true); | |
} | |
public Main(Scanner in, PrintWriter out) { | |
this.in = in; | |
this.out = out; | |
} | |
private static long[] getInts(String input) { | |
String[] ints = input.trim().split(" "); | |
long[] rets = new long[2]; | |
rets[0] = Long.parseLong(ints[0]); | |
rets[1] = Long.parseLong(ints[1]); | |
return rets; | |
} | |
private void solveAckermannProblem(long from, long to) { | |
long maxValue = from; | |
long maxLength = 0; | |
for (long i = from; i <= to; i++) { | |
long length = computeCycleLength(nextAckermannNumber(i)); | |
if (maxLength < length) { | |
maxValue = i; | |
maxLength = length; | |
} | |
} | |
out.println(String | |
.format("Between %d and %d, %d generates the longest sequence of %d values.", | |
from, to, maxValue, maxLength)); | |
} | |
private static long computeCycleLength(long n) { | |
if (n == 0) | |
return 0; | |
if (n == 1) | |
return 1; | |
if (n < _MaxValue && memo[(int) n] != 0) | |
return memo[(int) n]; | |
long len = 1 + computeCycleLength(nextAckermannNumber(n));// computing | |
// length of | |
// Ackermann | |
// sequence | |
if (n < _MaxValue) // storing it in cache | |
memo[(int) n] = len; | |
return len; | |
} | |
public static long nextAckermannNumber(long n) { | |
if (n % 2 == 0) | |
return n / 2; | |
else | |
return n * 3 + 1; | |
} | |
public void run() { | |
while (in.hasNextLine()) { | |
long[] range = getInts(in.nextLine()); | |
if ((range[0] == 0) && (range[1] == 0)) | |
break; | |
long from = Math.min(range[0], range[1]); | |
long to = Math.max(range[0], range[1]); | |
solveAckermannProblem(from, to); | |
} | |
} | |
public static void main(String[] args) { | |
Main solver = new Main(); | |
solver.run(); | |
} | |
} |
Please leave a comment if you have any question regarding this problem or implementation. Thanks.