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.
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:
ReplyDeleteAdd 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.
You added constructor for such hidden actions I suppose. But static class initializer works the same.
ReplyDeletepublic class StopTheLoop {
ReplyDeletestatic 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();
}
}
import java.util.Timer;
ReplyDeleteimport 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
}
}
}
1 Implement the default constructor of StopTheLoop
ReplyDelete2 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
My off-the-top of my head solution (not sure how to format it correctly) -
ReplyDeletepublic 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);
}
}
I think, we should add the next block to this class:
ReplyDelete{
new Thread(){
public void run(){
try{
sleep(1000);
}catch(InterruptedException ie){
ie.printStackTrace();
}
StopTheLoop .looper = new StopTheLoop ();
}
}.start();
}
Not pretty but it works :)
ReplyDeletepublic 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);
}
}
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 ;-)
ReplyDeleteprivate 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();
}
}
});
}
package com.twister;
ReplyDeleteimport 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!");
}
});
}
}
package com.twister;
ReplyDeletepublic 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);
}
}
package com.twister;
ReplyDeleteimport 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);
}
}
Insert the following before the main method:
ReplyDeletestatic 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();
package com.twister;
ReplyDeletepublic 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();
}
}
Hi!
ReplyDeleteAdd 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
It ain't pretty, but this'll work:
ReplyDeleteadd this constructor to the class -
public StopTheLoop() {
new Timer().schedule(new TimerTask() { public void run() {System.exit(0);}}, 100);
}
public class StopTheLoop extends Thread {
ReplyDeletestatic 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);
}
}
package com.twister;
ReplyDeletepublic 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;
}
}
Doubt it's what you want... but here's a brute force solution...
ReplyDeletepublic 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);
}
}
package com.twister;
ReplyDeletepublic 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();
}
}
package com.twister;
ReplyDeletepublic 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();
}
}
Spawn a thread in StopTheLoop constructor that sets static looper to null after 10 seconds.
ReplyDeletepublic class StopTheLoop {
ReplyDeletestatic 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);
}
}
public class StopTheLoop {
ReplyDeletestatic 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);
}
}
package com.twister;
ReplyDeletepublic 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);
}
}
package com.twister;
ReplyDeletepublic 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);
}
}
package com.twister;
ReplyDeleteimport 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);
}
}
package com.twister;
ReplyDeletepublic 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!");
}
}
}
package com.twister;
ReplyDeletepublic 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!");
}
}
}
Either a:
ReplyDelete1) 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.
Here's what I came up with:
ReplyDeletepackage 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);
}
}
public class StopTheLoop implements Runnable {
ReplyDeletestatic 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();
}
}
public class StopTheLoop {
ReplyDeletestatic 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);
}
}
public class StopTheLoop {
ReplyDeletestatic 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();
}
}
package com.twister;
ReplyDeletepublic 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);
}
}
package com.twister;
ReplyDeleteimport 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);
}
}
@Override
ReplyDeleteprotected void finalize() throws Throwable {
StopTheLoop.looper = this;
//super.finalize();
}
package com.twister;
ReplyDeletepublic 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);
}
}
package com.twister;
ReplyDeleteimport 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 );
}
}
}
}
Gerhard Balthasar:
ReplyDeletepublic 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();
}
}
public class StopTheLoop
ReplyDelete{
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);
}
}
package com.twister;
ReplyDeleteimport 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);
}
}
}
import java.io.IOException;
ReplyDeleteimport 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);
}
}
What about a thread to set looper != null ?
ReplyDeleteLet'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 !
package com.twister;
ReplyDeletepublic 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);
}
}
package test;
ReplyDeletepublic 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);
}
}
}
// a probabilistic solution
ReplyDeletepackage 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);
}
}
// a deterministic solution
ReplyDeletepackage 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);
}
}