Sunday, August 23, 2009

Puzzle 49 – Stop me if you can ...

Language – Java | Type – Concept | Last date 30-Aug-2009 12:00 p.m. IST | Points 3

After a long week here is the next puzzle,

package com.twister;
public class StopTheLoop {
static StopTheLoop looper;

public static void main(String[] args) {
looper
= new StopTheLoop();
looper
= null;
do{
System.out.println(
"Infinite Loop");;
}
while(looper==null);
}
}

This program keeps printing the string "Infinite Loop" an infinite number of times. Without making any changes to the main method (no additions, deletions, modifications, redefining main) - convert this program so that the loop runs a finite number of times.
Note : the loop must run at least one time.

Got an answer? Do leave it here.

48 comments:

  1. Yeah, we could run main method in daemon thread and then terminate main program forcefully. So daemon won't execute forever. But it's not interesting. I think its easier to redefine System.out stream. See:

    Add static block

    static {
    final PrintStream oldOut = System.out;
    PrintStream newOut = new PrintStream(oldOut) {
    @Override
    public void println(String x) {
    oldOut.println(x);
    System.exit(0);
    }
    };
    System.setOut(newOut);
    }

    It prints exactly one time. Not hard to fix to print only 10 times an so on.

    ReplyDelete
  2. You added constructor for such hidden actions I suppose. But static class initializer works the same.

    ReplyDelete
  3. public class StopTheLoop {
    static StopTheLoop looper;

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }
    public void finalize() {
    looper = new StopTheLoop();
    }

    }

    ReplyDelete
  4. import java.util.Timer;
    import java.util.TimerTask;

    public class StopTheLoop {
    static StopTheLoop looper;

    Timer timer = new Timer();

    public StopTheLoop() {
    timer.schedule(new StopTheLoopTask(), 2000);
    }

    public StopTheLoop(int i) {

    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");
    ;
    } while (looper == null);
    }

    class StopTheLoopTask extends TimerTask {
    public void run() {
    System.out.println("OK, It's time to stop the loop!");
    looper = new StopTheLoop(1);
    timer.cancel(); // Terminate the thread
    }
    }

    }

    ReplyDelete
  5. 1 Implement the default constructor of StopTheLoop
    2 In there :
    -- e.g. create a timer with a TimerTask that sets the static looper instance to a non-null reference after some configurable time
    -- or intercept/substitute the System.out with a wrapper and count the println invocations and set the static looper instance after a configurable nr of invocations

    ReplyDelete
  6. My off-the-top of my head solution (not sure how to format it correctly) -

    public class StopTheLoop {
    static StopTheLoop looper;

    static boolean threadStarted = false;

    public StopTheLoop() {
    if (!threadStarted) {
    Thread t = new Thread() {
    public void run() {
    try {
    Thread.sleep(10);
    } catch (InterruptedException e) {}
    if (looper == null) {
    looper = new StopTheLoop();
    }
    }
    };
    new Thread(t).start();
    threadStarted = true;
    }
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }
    }

    ReplyDelete
  7. I think, we should add the next block to this class:
    {
    new Thread(){
    public void run(){
    try{
    sleep(1000);
    }catch(InterruptedException ie){
    ie.printStackTrace();
    }
    StopTheLoop .looper = new StopTheLoop ();
    }
    }.start();
    }

    ReplyDelete
  8. Not pretty but it works :)

    public class StopTheLoop {
    static StopTheLoop looper;
    static {
    new Thread(new Runnable() {
    public void run() {
    try {
    Thread.sleep(500);
    } catch (Exception e) {}
    looper = new StopTheLoop();
    }
    }).start();
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }
    }

    ReplyDelete
  9. Just add this code snippet to your class and you'll be able to control how many lines are printed. Not your average best-practice, though ;-)

    private int counter = 0;
    private final int maxCount = 5;

    public StopTheLoop() {
    System.setOut(new PrintStream(System.out) {
    @Override public void println(final String x) {
    super.println(x);
    if (++counter == maxCount) {
    looper = new StopTheLoop();
    }

    }
    });
    }

    ReplyDelete
  10. package com.twister;

    import java.io.PrintStream;

    public class StopTheLoop {
    static StopTheLoop looper;

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }

    public StopTheLoop() {
    System.setOut(new PrintStream(System.out) {
    public void println(String str) {
    super.println(str);
    throw new RuntimeException("Stop!");
    }
    });
    }
    }

    ReplyDelete
  11. package com.twister;

    public class StopTheLoop {
    static StopTheLoop looper;

    public StopTheLoop() {
    javax.swing.SwingUtilities.invokeLater(// :-)
    new Runnable() {
    public void run() {
    if (looper == null) looper = new StopTheLoop();
    }
    });
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");;
    } while (looper == null);
    }
    }

    ReplyDelete
  12. package com.twister;
    import java.io.ByteArrayOutputStream;
    import java.io.OutputStream;
    import java.io.PrintStream;

    public class StopTheLoop {
        static StopTheLoop looper;

        static {
            final PrintStream PS = System.out;
            PrintStream MyPS = new PrintStream(new ByteArrayOutputStream()) {
                public void println(String S) {
                    PS.println(S);
                    looper = new StopTheLoop();
                }
            };
            System.setOut(MyPS);
        }

        public static void main(String[] args) {
            looper = new StopTheLoop();
            looper = null;
            do {
                System.out.println("Infinite Loop");;
            }while(looper==null);
        }
    }

    ReplyDelete
  13. Insert the following before the main method:

    static class FakeSystem {
    class Out {
    void println(final String s) {
    java.lang.System.out.println(s);
    looper = new StopTheLoop();
    }
    }
    Out out = new Out();
    }
    static FakeSystem System = new FakeSystem();

    ReplyDelete
  14. package com.twister;
    public class StopTheLoop {
    static StopTheLoop looper;

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }

    protected void finalize() throws Throwable
    {
    StopTheLoop.looper = new StopTheLoop();
    }

    }

    ReplyDelete
  15. Hi!
    Add this constructor to the class (excuse the formatting):

    public StopTheLoop() {
    Runnable r = new Runnable() {
    public void run() {
    Thread.yield();
    looper = new StopTheLoop();
    }
    };
    final Thread thread = new Thread(r);
    thread.start();
    }

    regards,
    Vlad

    ReplyDelete
  16. It ain't pretty, but this'll work:

    add this constructor to the class -

    public StopTheLoop() {
    new Timer().schedule(new TimerTask() { public void run() {System.exit(0);}}, 100);
    }

    ReplyDelete
  17. public class StopTheLoop extends Thread {
    static StopTheLoop looper;

    static {
    new StopTheLoop().start();
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");
    } while (looper == null);
    }

    @Override
    public void run() {
    System.out.println("run");
    Thread.yield();
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.exit(0);
    }
    }

    ReplyDelete
  18. package com.twister;
    public class StopTheLoop {
    static StopTheLoop looper;

    public static void main(String[] args) {
    looper = new StopTheLoop();

    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    looper = null;
    }
    }

    ReplyDelete
  19. Doubt it's what you want... but here's a brute force solution...

    public class StopTheLoop {
    static StopTheLoop looper=new StopTheLoop();
    static {
    Thread t = new Thread() {
    public void run() {
    try {
    Thread.sleep(1000);
    } catch(InterruptedException e) {
    e.printStackTrace();
    }
    looper=new StopTheLoop();
    }
    };
    t.start();
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }
    }

    ReplyDelete
  20. package com.twister;

    public class StopTheLoop
    {
    static StopTheLoop looper;

    public static void main(String[] args)
    {
    looper = new StopTheLoop();
    looper = null;
    do
    {
    System.out.println("Infinite Loop");;
    }
    while (looper == null);
    }

    @Override
    protected void finalize() throws Throwable
    {
    looper = new StopTheLoop();
    }
    }

    ReplyDelete
  21. package com.twister;

    public class StopTheLoop
    {
    static StopTheLoop looper;

    public static void main(String[] args)
    {
    looper = new StopTheLoop();
    looper = null;
    do
    {
    System.out.println("Infinite Loop");;
    }
    while (looper == null);
    }

    @Override
    protected void finalize() throws Throwable
    {
    looper = new StopTheLoop();
    }
    }

    ReplyDelete
  22. Spawn a thread in StopTheLoop constructor that sets static looper to null after 10 seconds.

    ReplyDelete
  23. public class StopTheLoop {
    static StopTheLoop looper;
    static class MyThread extends Thread {
    public void run() {
    try {
    sleep(1000);
    } catch (Exception e) {
    }
    looper = new StopTheLoop();
    }
    }
    static {
    MyThread thread = new MyThread();
    thread.start();
    }
    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }
    }

    ReplyDelete
  24. public class StopTheLoop {
    static StopTheLoop looper;
    static class MyThread extends Thread {
    public void run() {
    try {
    sleep(1000);
    } catch (Exception e) {
    }
    looper = new StopTheLoop();
    }
    }
    static {
    MyThread thread = new MyThread();
    thread.start();
    }
    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }
    }

    ReplyDelete
  25. package com.twister;

    public class StopTheLoop {
    static StopTheLoop looper;

    @Override
    protected void finalize() throws Throwable {
    looper = new StopTheLoop();
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }

    }

    ReplyDelete
  26. package com.twister;

    public class StopTheLoop {
    static StopTheLoop looper;

    static class System {
    static System out = new System();
    void println(String s) {
    java.lang.System.out.println(s);
    looper = new StopTheLoop();
    }
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");
    } while (looper == null);
    }
    }

    ReplyDelete
  27. package com.twister;

    import java.io.PrintStream;

    public class StopTheLoop {

    static StopTheLoop looper;

    static final int MAX_EXECUTIONS = 5;

    static {
    System.setOut(new PrintStream(System.out) {

    private int count = 0;

    @Override
    public void println(String x) {
    super.println(x);

    if (++count == MAX_EXECUTIONS) {
    looper = new StopTheLoop();
    }
    }

    });
    }

    static {
    Thread thread = new Thread(new Runnable() {

    private int count;

    @Override
    public void run() {
    for (int count = 0; count < 1000; count++) {
    looper = new StopTheLoop();
    PrintStream s;
    System.setOut(new PrintStream(System.out));
    Thread.currentThread().stop();
    }
    }
    });
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");
    ;
    } while (looper == null);
    }
    }

    ReplyDelete
  28. package com.twister;

    public class StopTheLoop implements Runnable {
    static volatile StopTheLoop looper;

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");
    ;
    } while (looper == null);
    }

    public void run() {
    String[] foo = new String[0];
    main(foo);
    }

    public static class Foo {
    public static void main(String[] args) throws Throwable {
    Runnable runnable = new StopTheLoop();
    Thread thread = new Thread(runnable);
    thread.start();
    StopTheLoop.looper = new StopTheLoop();
    System.out.println("Stopped!");
    }
    }
    }

    ReplyDelete
  29. package com.twister;

    public class StopTheLoop implements Runnable {
    static volatile StopTheLoop looper;

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");
    ;
    } while (looper == null);
    }

    public void run() {
    String[] foo = new String[0];
    main(foo);
    }

    public static class Foo {
    public static void main(String[] args) throws Throwable {
    Runnable runnable = new StopTheLoop();
    Thread thread = new Thread(runnable);
    thread.start();
    StopTheLoop.looper = new StopTheLoop();
    System.out.println("Stopped!");
    }
    }
    }

    ReplyDelete
  30. Either a:
    1) static initializer
    2) normal initializer
    3) StopTheLoop constructor

    that
    1) spawns a thread that sleeps for a bit, or
    2) replaces System.out with a custom PrintStream that waits for some action, first delgating to the standard System.out

    and then:
    1) sets looper = new StopTheLoop(); (or just looper = this if not in a static block), or
    2) calls System.exit();

    Various other combinations are possible too.

    ReplyDelete
  31. Here's what I came up with:

    package com.twister;

    public class StopTheLoop extends Thread implements Runnable {
    static StopTheLoop looper;
    static volatile boolean running = false;

    public StopTheLoop() {
    if (!StopTheLoop.running)
    this.start();
    }

    @Override
    public void run() {
    try {
    StopTheLoop.running = true;
    Thread.sleep(0);
    StopTheLoop.looper = new StopTheLoop();
    } catch (InterruptedException ex) {
    ex.printStackTrace();
    }
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;

    do {
    System.out.println("Infinite loop");
    } while (looper == null);
    }
    }

    ReplyDelete
  32. public class StopTheLoop implements Runnable {
    static StopTheLoop looper;

    public StopTheLoop() {

    Thread t = new Thread(this);
    t.start();

    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");
    ;
    } while (looper == null);
    }

    @Override
    public void run() {
    looper = new StopTheLoop();

    }
    }

    ReplyDelete
  33. public class StopTheLoop {
    static StopTheLoop looper;

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }

    public StopTheLoop() {
    PrintStream ps = new PrintStream(System.out){
    @Override
    public void println(String x) {
    super.println(x);
    looper = new StopTheLoop();
    }
    };
    System.setOut(ps);
    }

    }

    ReplyDelete
  34. public class StopTheLoop {
    static StopTheLoop looper;

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");
    }while(looper==null);
    }

    protected void finalize() throws Throwable {
    looper = new StopTheLoop();
    super.finalize();
    }

    }

    ReplyDelete
  35. package com.twister;
    public class StopTheLoop {
    static volatile StopTheLoop looper;
    static int count = 0;

    public StopTheLoop() {

    if (count == 0) {

    Thread t = new Thread() {

    public void run() {
    try {Thread.sleep(16);} catch(Exception e) {};
    looper = new StopTheLoop();
    }
    };

    t.start();
    count = 1;
    }
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop : ");;
    }
    while(looper==null);
    }
    }

    ReplyDelete
  36. package com.twister;

    import java.io.PrintStream;

    public class StopTheLoop {


    final int MAX_LOOP = 5;
    static StopTheLoop looper;
    {

    System.setOut(new PrintStream(System.out) {
    int counter = MAX_LOOP;
    @Override
    public void println(String x) {
    super.println(x);
    if (--counter == 0)
    looper = new StopTheLoop();
    }
    });
    }
    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");
    } while (looper == null);
    }
    }

    ReplyDelete
  37. @Override
    protected void finalize() throws Throwable {
    StopTheLoop.looper = this;
    //super.finalize();
    }

    ReplyDelete
  38. package com.twister;

    public class StopTheLoop {
    static StopTheLoop looper;


    {
    new Thread() {
    {
    setDaemon(true);
    }

    public void run() {

    looper=new StopTheLoop();
    }
    }.start();
    }

    public static void main(String[] args) {
    looper=new StopTheLoop();
    looper=null;
    do {
    System.out.println("Infinite Loop");
    ;
    } while (looper==null);
    }
    }

    ReplyDelete
  39. package com.twister;

    import java.io.*;

    public class StopTheLoop
    {
    static StopTheLoop looper;
    private static final int NUM_ITERATIONS = 1;

    public StopTheLoop()
    {
    System.setOut( new MyPrintStream( NUM_ITERATIONS ) );
    }

    public static void main( String[] args )
    {
    looper = new StopTheLoop();
    looper = null;
    do
    {
    System.out.println( "Infinite Loop" );;
    } while ( looper == null );
    }

    private static class MyPrintStream extends PrintStream
    {
    private int iterationCount = 0;
    private int targetNumIterations;

    public MyPrintStream( int aNumIterations )
    {
    super( System.out );

    targetNumIterations = aNumIterations;
    }

    public void println( String aString )
    {
    iterationCount++;
    if ( iterationCount > targetNumIterations )
    {
    throw new RuntimeException();
    }
    else
    {
    super.println( aString );
    }
    }
    }
    }

    ReplyDelete
  40. Gerhard Balthasar:

    public class StopTheLoop {

    static StopTheLoop looper;

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");;
    } while (looper == null);
    }

    // --- Modification

    static {
    new Thread(new Runnable() {
    public void run() {
    do {
    looper = new StopTheLoop();
    } while (looper == null);
    }
    }).start();
    }

    }

    ReplyDelete
  41. public class StopTheLoop
    {
    static StopTheLoop looper;

    public StopTheLoop()
    {
    new Thread()
    {
    public void run()
    {
    try {Thread.sleep(200);}catch (InterruptedException e){}

    if (looper == null)
    looper = new StopTheLoop();
    }
    }.start();
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;

    do {
    System.out.println("Infinite Loop");;
    }
    while(looper==null);
    }
    }

    ReplyDelete
  42. package com.twister;

    import java.util.Timer;
    import java.util.TimerTask;

    public class StopTheLoop {
    static StopTheLoop looper;
    static Timer timer = new Timer();

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");
    ;
    } while (looper == null);
    }

    public StopTheLoop() {
    timer.schedule(new ExitTask(), 1);
    }

    class ExitTask extends TimerTask {
    public void run() {
    System.exit(0);
    }
    }

    }

    ReplyDelete
  43. import java.io.IOException;
    import java.io.OutputStream;
    import java.io.PrintStream;

    public class StopTheLoop {
    static StopTheLoop looper;

    static {
    final PrintStream out = System.out;
    System.setOut(new PrintStream(new OutputStream() {
    public void write(int b) throws IOException {
    out.write(b);
    looper = new StopTheLoop();
    }
    }));
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }
    }

    ReplyDelete
  44. What about a thread to set looper != null ?

    Let's add these two constructors:


    StopTheLoop(boolean spawnThread) {
    new Thread(new Runnable() {
    public void run() {
    if (looper == null) looper = new StopTheLoop(false);
    }
    }).start();
    }

    StopTheLoop() { this(true); }

    Works for me !

    ReplyDelete
  45. package com.twister;

    public class StopTheLoop {
    static StopTheLoop looper;

    private StopTheLoop() {
    new Thread() {
    @Override public void run() {
    try {
    sleep(1000L);
    looper = StopTheLoop.this;
    } catch(InterruptedException e){
    e.printStackTrace();
    }
    }
    }.start();
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }
    }

    ReplyDelete
  46. package test;

    public class StopTheLoop implements Runnable{

    static volatile StopTheLoop looper;

    static int stop = 0;

    public StopTheLoop(){
    Thread t = new Thread(this);
    t.start();
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do{
    System.out.println("Infinite Loop");;
    }while(looper==null);
    }

    @Override
    public void run() {
    stop++;
    System.out.println(stop);
    if(stop == 1){
    System.exit(0);
    }
    }



    }

    ReplyDelete
  47. // a probabilistic solution

    package com.twister;

    import java.util.Timer;
    import java.util.TimerTask;

    public class StopTheLoop {
    static StopTheLoop looper;

    StopTheLoop() {
    new Timer(true).schedule(new TimerTask() {
    public void run() {
    looper = new StopTheLoop(1);
    }
    }, 5000);
    }

    StopTheLoop(int x) {
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");
    ;
    } while (looper == null);
    }
    }

    ReplyDelete
  48. // a deterministic solution

    package com.twister;

    import java.io.PrintStream;

    public class StopTheLoop {
    static StopTheLoop looper;

    StopTheLoop() {
    System.setOut(new PrintStream(System.out) {
    @Override
    public void write(byte[] buf, int off, int len) {
    super.write(buf, off, len);
    looper = new StopTheLoop();
    }
    });
    }

    public static void main(String[] args) {
    looper = new StopTheLoop();
    looper = null;
    do {
    System.out.println("Infinite Loop");
    ;
    } while (looper == null);
    }
    }

    ReplyDelete

Solution for this question?