Java Puzzle 9: Tweet - Solution

Feb 10, 2015

Here's the puzzle again:

The challenge is that you have to reach a statement that comes after an infinitely recursing constructor call, that also tries to divide by zero. You need to avoid a StackOverflowError and an ArithmeticException to get there.

Avoiding infinite recursion

How do we avoid the infinite recursion of B's constructor from calling itself? Looking at that syntax, there's no doubt that's a constructor call. So to avoid recursion it must be a call to a constructor of a different class. All we control is the super class; so what if there's another class called B in there? Let's try that with a simpler example:

class A {
  static class B {
  }
}

class B extends A {
  public static void main(String[] args) {
    System.out.println(new B().getClass().getName());
  }
}

This prints A$B! When resolving a class name, the compiler surprisingly looks at inner classes of a superclasses before it considers using the current class. One down.

Avoiding division by zero

Next, how do we avoid that i/Long.compare(i,i) throws an ArithmeticException?

You might try the same trick, creating another class A.Long. But that doesn't work out here. The constructor of B takes Long i as argument. If that's not java.lang.Long, then i/something doesn't compile. You cannot divide an instance of A.B by something; it cannot be unboxed into a long.

compare(i,i) on the java.lang.Long class will always return zero, leading to the division by zero. So we want that to resolve to a different method. The catch is that types (as in Long i) are not resolved in the same way as method calls (as in Long.compare). If we have a field called Long, then Long.compare is a method call on that. Simpler demonstration:

class A {
  static A Long = new A();
}

class B extends A {
  public static void main(String[] args) {
    System.out.println(Long.class);
    System.out.println(Long.getClass());
  }
}

That prints class java.lang.Long in the first line because it's looking for a class, and then class A because when resolving a method the A.Long field hides the java.lang.Long class.

Putting it all together

Applying that to the original puzzle, there is one more minor obstacle to overcome. The main method in our class A needs to call the constructor of B without getting distracted by A.B. Just doing new B() would call the wrong constructor. Usually you would solve such ambiguity with a fully qualified name; but since we're in the default package, B is the fully qualified name already. A simple indirection through another class, called S here, solves that. Giving the full solution:

class A {
  public static void main(String[] args) {
    S.go();
  }

  A Long = this;

  int compare(long a, long b) {
    return 1;
  }

  class B {
    B(long i) {
    }
  }
}

class S {
  static void go() {
    new B(0L);
  }
}

For bonus points, if you're into code golf and want to fit that solution in a tweet with room for more: a static initializer is less characters than a main method, and a lambda saves some chars too. It also throws an exception about not finding the main method but that's only after the win.

As usual, submitted solutions have been moved to comments of this post.


16 comments

Bas de Bakker wrote on 2015-02-03 10:34

Thanks for another fun puzzle. All the below goes in A.java as instructed, including the class C.

class A {
    public static void main(String[] args) {
        C.main();
    }
    A Long;
    class B {
        B(long i) {}
    }
    static long compare(long a, long b) {
        return 1;
    }
}

class C {
    static void main() {
        new B(0L);
    }
}
Adam K wrote on 2015-02-03 12:17
public class A {

    public static X Long = new X();

    public static class X {
        public int compare(long a, long b){
            return 1;
        }
    }

    public class B {
        public B(Object l) {
        }
    }

    public static void main(String[] args) throws Exception {
        new C(1l); // class C needed because B in default package can't be referred to directly
    }
}

class C extends B {
    public C(java.lang.Long i) {
        super(i);
    }
}
Christophe Devriese wrote on 2015-02-03 14:57

This took me almost 2 hours ! Fantastic puzzle !

class helper {
    B b = new B(5L);
}

public class A {
    static class compare {
        public static int compare(Long i, Long j) { return 1; }
    }
    static compare Long = new compare();
    static class B {
        public B(long l) {}
    }

    public static void main(String[] params) {
        helper b = new helper();
    }
}
Chris Povirk wrote on 2015-02-03 18:23

Fun puzzle. Thanks!

class A {
  static class Foo {
    int compare(Long a, Long b) {
      return 1;
    }
  }

  static final Foo Long = new Foo();

  public static void main(String[] args) {
    new C();
  }

  static class B {
    B(long l) {}
  }
}

class C {
  C() {
    new B(1L);
  }
}
mihi wrote on 2015-02-03 23:53

Easy win:

public class A{static A Long=new A();class B{public B(long a){}}int compare(Long a, Long b){return 1;}
    public static void main(String[] a) throws Exception {
        Class.forName("B").getDeclaredConstructor(Long.class).newInstance((long)1);
    }
}
Yuzhe Jin wrote on 2015-02-04 02:10
import java.lang.reflect.Constructor;

public class A {
  C Long = new C();

  public A () {

  }

  class B {
    B(double d) {
    }
  }

  class C {
    double compare(long a, long b) {
      return 1.0;
    }
  }

  public static void main(String[] args) {
    try {
      Class c = Class.forName("B");
      Constructor[] allConstructors = c.getDeclaredConstructors();
      allConstructors[0].newInstance(1L);
    } catch (Exception e) {
      System.out.println(e);
    }
  }
}
Jonathan Rascher wrote on 2015-02-04 02:43

My solution’s A.java file:

class A {
  static class Xyzzy {
    long compare(Long a, Long b) {
      return 1;
    }
  }

  public static void main(String[] args) {
    Plugh.plover();
  }

  class B {
    B(long n) {}
  }

  Xyzzy Long = new Xyzzy();
}

class Plugh {
  static void plover() {
    new B(0L);
  }
}

I think the class Plugh could be replaced with reflective instantiation of B using Class#forName and friends, but that seemed like more work.

Sergey wrote on 2015-02-04 09:32
public class A {

  public static void main(String... args) {
    new C(1L);
  }

  protected static class B {
    public B(long ignore) {
    }
  }

  D Long;
}

class C extends B {

  C(java.lang.Long i) {
    super(i);
  }
}

class D {
  public static int compare(long x, long y) {
    return 1;
  }
}
Brian wrote on 2015-02-04 17:29

class A{java.util.Comparator Long=(x,y)->1;class B{B(long y){}}public static void main(String[]x){new X();}}class X

Daniel Schwarz wrote on 2015-02-04 19:35
public class A {
    public static void main(String[] args) {
        C.execute();
    }

    static class B {
        B(long l) {
        }
    }

    public LongComparator Long;

    static class LongComparator {
        static long compare(Long l1, Long l2) {
            return 1;
        }
    }
}

class C {
    static void execute() {
        new B(Long.valueOf(1));
    }
}
Kofa wrote on 2015-02-04 20:07
import java.util.Comparator;

public class A {
    public class B {
        B(double b) {
        }
    }

    static Comparator<Object> Long = new Comparator<Object>() {
        @Override
        public int compare(Object o1, Object o2) {
            return 1;
        }
    };

    public static void main(String[] args) throws Exception {
        Class.forName("B").getDeclaredConstructor(Long.class).newInstance(new java.lang.Long(1));
    }
}
Ian Haken wrote on 2015-02-04 20:38

A very neat puzzle! Cleverly put together as well.

My solution:

public class A {

  public static Foo Long = new Foo();

  public static class Foo {
    public long compare(Long a, Long b) {
      return 1L;
    }
  }

  public static class B {
    public B(Long a) {}
  }

  public static void main(String[] args) throws Exception {
    Class.forName("B").getDeclaredConstructor(Long.class).newInstance(new Long(1L));
  }
}
Stefan M. wrote on 2015-02-04 21:26

First of all, thanks Wouter! Below my solution:

class A
{
    static final A Long = new A();

    long compare(long __, long ___)
    {
        return 1;
    }

    static class B
    {
        B(long __)
        {
        }
    }
}
Stefan M. wrote on 2015-02-08 21:56

Second try, now with a main method:

import java.lang.reflect.Constructor;

class A
{
    static final A Long = new A();

    long compare(long __, long ___)
    {
        return 1;
    }

    public static void main(String[] args) throws Exception
    {
        Class<?> c = Class.forName("B");
        Constructor<?> declaredConstructor = c.getDeclaredConstructor(Long.class);
        declaredConstructor.newInstance(1L);
    }

    static class B
    {
        B(long __)
        {
        }
    }

}
Matt Nathan wrote on 2015-02-09 16:25
import java.util.Comparator;

public class A {
  // this replaces the B.java reference in B.java to avoid the stack overflow
  public static class B {
    public B(long l) {
    }
  }

  // this replaces the Long.compare references in B.java to avoid the divide by zero
  public static Comparator<Long> Long = new Comparator<java.lang.Long>() {
    @Override
    public int compare(Long o1, Long o2) {
      return 1;
    }
  };

  public static void main(String[] args) throws Exception {
    // because we have a B in our scope that overrides the B.java reference we
    // need to instantiate it via reflection
    Class.forName("B").getDeclaredConstructor(Long.class)
         .newInstance(1L);
  }
}
Ivan Z wrote on 2015-02-10 06:19
import java.lang.reflect.Constructor;

public class A {

    class B {
        B(float f) {
        }
        float compare(long x, long y) {
            return 1L;
        }
    }

    B Long = new B(1);

    public static void main(String[] args) throws Exception {
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        Class<?> classB = cl.loadClass("B");
        Constructor<?> constructor = classB.getDeclaredConstructor(Long.class);
        constructor.newInstance(0L);
    }
}