import java.math.*; import java.util.*; public class Hailstone { private static BigInteger highestReached=BigInteger.ZERO; private static long BIG_THRESHOLD = Long.MAX_VALUE/4; private static BigInteger BIG_THRESHOLD_AS_BIGINTEGER = BigInteger.valueOf (BIG_THRESHOLD); public static void main (String [] args) { if (args.length != 2) { System.out.println ("Usage: Hailstorm "); return; } long lower=0, upper=0; try { lower = Long.parseLong (args[0]); upper = Long.parseLong (args[1]); } catch (NumberFormatException e) { System.out.println ("Unable to parse parameters: "+e.getMessage()); return; } if (lower <= 1) { System.out.println (lower+" <= 1; aborting."); return; } if (lower > upper) { System.out.println (lower+" > "+upper+"; aborting."); return; } System.out.println ("Start time: "+new Date()); for (long x=lower; x <= upper; x++) test (x); System.out.println ("End time: "+new Date()); } public static void test(long x) { long highestLong=x; BigInteger highestBig=BigInteger.valueOf(0); long current=x; BigInteger currentBig=null; boolean usingBig=false; while (current >= x) { // System.out.println (current+"/"+x); if (!usingBig) { // Even if ((current&1)==0) current=current>>>1; // Divide by two quickly // Odd else { current=current*3+1; if (current>highestLong) highestLong=current; if (current>BIG_THRESHOLD) { usingBig=true; currentBig=BigInteger.valueOf(current); } } } else { // Even if (!currentBig.testBit (0)) { currentBig = currentBig.shiftRight(1); if (currentBig.compareTo (BIG_THRESHOLD_AS_BIGINTEGER) < 0) { current = currentBig.longValue(); usingBig=false; } } else { // Multiply by four, subtract original, add 1 BigInteger tmp = currentBig.shiftLeft (2); currentBig = tmp.subtract (currentBig); currentBig = currentBig.add (BigInteger.ONE); if (currentBig.compareTo(highestBig) > 0) highestBig=currentBig; } } } if ((x&0xffffff)==0) System.out.println ("Tested "+x); BigInteger tmp = BigInteger.valueOf (highestLong); if (tmp.compareTo(highestBig)>0) highestBig=tmp; // System.out.println ("Highest big for "+x+"="+highestBig); if (highestBig.compareTo(highestReached) > 0) { System.out.println ("New record: "+x+" reached "+highestBig); highestReached=highestBig; } } }