I read this on the sun forums It was really interesting.........First i had a real laugh with the answers........then i realized that it was not some silly question.......a real good one.......then i really started reading to get the answer........and then somewhere in the middle there was a fabulous answer.........the best... Guys read it.........will send the link where the correct answer is later
Oops, sorry aadhi - here's the post again (more or less): The requirements here seem a bit silly, and I think that any solution is going to be ultimately calling a loop or recursion somewhere in an existing class. Heck, even println("Hello World") by itself invokes a couple loops as it executes. But here's my contribution for what I see as a reasonable minimum of looping:
Ram Ar... It is a real good and interesting question. Let me see.......... First idea come through my mind is use inheritance because it can produce some recursion effect. Second idea is that use threads to do it,when count to 100 times then end the process of threads. Are both ideas wrong? Jim ,your idea seems to work.
Francis Siu
SCJP, MCDBA
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18670
posted
0
Did u pick it for that forum or was it a very simple question for you to answer I thought of it myself, after reading a couple pages from the forum and seeing a bunch of solutions that called other code that did the looping for them. I posted my idea here, then realized there were still loops hidden away inside so I deleted it, then said to heck with it and reposted. :roll: Then I read some more in the forum and found one guy who did something similar to my solution, using StringBuffer - but my code is much shorter looking.
Ram Kumar Subramaniam
Ranch Hand
Joined: Jan 17, 2003
Posts: 68
posted
0
That was great Jim. Well that answer didnt strike me at all. siu, that was the answer.....posted earlier But aadhi, did u get the the answer once u read the question. Didnt it, triger your thoughts ??
hmmn, i remember this being a similar puzzle in c/c++ but can't remember the solution My guess would be to use constructor or destructors, maybe let the garbage collector do the iterating. Are you sure Jim's answer is correct? doesn't seem very clever
Here is my favorite solution from the forum, with the creative use of classloader: public class MyCrappyStupidAssHelloProgram { public static int instance = 0; MyCrappyStupidAssHelloProgram() { instance ++; System.out.println("Hello World!"); if(instance == 100) System.exit(1); new MyCrappyStupidAssHelloProgram(); } public static void main(String args[]) { new MyCrappyStupidAssHelloProgram(); } }
Francis Siu
Ranch Hand
Joined: Jan 04, 2003
Posts: 867
posted
0
yes Jim answer is correct String s = "Hello World\n"; s += s + s + s + s; //s=s+s+s+s+s //s=5 s += s + s + s + s; //s=5+5+5+5+5 //s=s+s+s+s+s //s=25 s += s + s + s; //s=s+s+s+s //s=25+25+25+25 //s=100 System.out.println(s); [ May 09, 2003: Message edited by: siu chung man ]
Well I think that it is. Anything that works that I did not come up with, somehow seems clever to me . Brilliant Jim .
"JavaRanch, where the deer and the Certified play" - David O'Meara
SJ Adnams
Ranch Hand
Joined: Sep 28, 2001
Posts: 925
posted
0
hmmn, the c++ solution can use a constructor to print, and "new" performs instantiation, so: foo [] a = new foo[100]; will instantiate in c++ (i think). but this is not true in java. to get this method working in java would require using some nifty class that took an class and instantiated it. I've taken a look at the Arrays class but there is nothing nifty the other construction method, foo [] a = {new foo(), new foo(),...}; isn't much good to us either I'll ponder over it down the pub
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18670
posted
0
yes i know it's "correct", but it isn't "clever". Well I'm happy enough with it for the problem as stated. But it's true that it wouldn't scale very well if we were asked to write something 421781 times rather than 100 - it would quickly lose the semblance of simplicity it has now. So I can agree that by some standards it lacks elegance. Any solution using Timer will use loops built into the Timer code, IMO. But if we ignore this:
I don't really like the MyCrappyStupidAssHelloProgram solution - isn't it just recursively calling the constructor from within the constructor? And what's the class loader got to do with it? You can insert a new Throwable().printStackTrace(); next to the "Hello World" and see an ever-lengthening stack trace that looks pretty recursive to me. Here's another solution which I like better: my interpretation of what siu said about using threads. To me it still feels somewhat recursive, but at least the method call stack isn't getting longer and longer.
Originally posted by Simon Lee: hmmn, i remember this being a similar puzzle in c/c++ but can't remember the solution
C++ one is easier - Just let the constructor of the class output the string, and create an array of 100 objects such as - myObjects[100]; and it's done! Another solution is by using Templates, which I don't remember. - Manish
Does this count ? I've tried to do without a print function - although I'm sure its embedded somewhere. Its compiled with the " -source 1.4" option to enable assertions and run with "java -ea <program>". class AHundred { public static void main (String args[]) throws Exception { String S="Hello World\n";
S = S+S+S+S+S+S+S+S+S+S; S = S+S+S+S+S+S+S+S+S+S; assert(false):S; } }
But this has to be the best solution. Again taken from that thread.
Mark
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18670
posted
0
No on serious note this code to me is not recursive and very clever Not recursive? Really? I would call it an example of 2-phase recursion. I mean really, there are lots of CS homework assignments that ask for a nonrecursive solution of some sort, and it would be trivial to transform any simple recursive solution to a two-phase (or more) recursive solution. How many CS professors are likely to accept this sort of solution as "non-recursive"? The Arrays solution is fairly elegant-looking, but merely hides its loops in the Arrays class. Though that sort of problem is admittedly endemic to any solution that prints, unless it prints one char at a time. I figure it's best to ignore that particular issue, but avoid any other looping or recursion. YMMV of course...
There are not direct or indirect recursive methods from a programmer's point of view. Neither does it use any looping in a System provided class like ArrayList. It relies on the fact that 'creation' of one object triggers 'creation' of another- a kind of chain reaction. (Edited to remove extra tabs. How do I insert blank lines in the code?) [ May 10, 2003: Message edited by: Jignesh Malavia ]
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18670
posted
0
Well, that's an interesting idea. I think that fundamentally it's pretty much equivalent to the previous MyCrappyStupidAssHelloProgram solution, in which the constructor was recursively calling the constructor. If you insert new Throwable().printStackTrace(); just before the "Hello World", you'll see a series of lengthy stack traces like this:
This is the very end of the output; at the beginning the stack trace is 200 lines long before Hello World is printed (100 levels of 2-phase recursion). So the recursion is hidden even better here, but it's still present, IMO.
Jignesh Malavia
Author
Ranch Hand
Joined: May 18, 2001
Posts: 81
posted
0
Oops! Well, okay :-) That proved recursive- getNewInstance() calling itself. I had to put that static method to control the number of Nodes at 100. But now I have removed the static method as well as the constructor.
And the stack trace for each nth object looks like this:
Of course, the process of creating the objects is recursive from JRE's point of view that it creates the 'next' object before it completes the creation of 'this' object. And it is the compiler that inserts the instance initializers into the generated <init> method. So if you say <init> is calling itself and is recursive, then I give up :-) But the program does not use any user-defined recursive methods (like getNewInstance() of previous example) and we cannot see any user-defined methods repeating itself in the stack trace. So does this pass as a solution without recursive methods? [ May 11, 2003: Message edited by: Jignesh Malavia ]
i see lots of great ideas here. but why not just simply: println("hello world/n") ; ............ ............ ............ repeating 100 times. please note, it is not as hard as appeared. after you type the first, use copy & paste for 7 times, you got what you want.
Well, I had to waste a little time on this too. So here is my solution:
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius - and a lot of courage - to move in the opposite direction. - Ernst F. Schumacher
C'mon guys! This isn't drivel!! Well it's damn sure meaningless and 1 out of 2 ain't bad.
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18670
posted
0
Michael Morris
Ranch Hand
Joined: Jan 30, 2002
Posts: 3451
posted
0
FoundTheLoopHelloWorld100
Smart ass!
Ram Kumar Subramaniam
Ranch Hand
Joined: Jan 17, 2003
Posts: 68
posted
0
FoundTheLoopHelloWorld100 .....
Oops i dont understand a thing.......From what i guess are u creating a class dynamically .....and those bytes is the actualy code or something ???
SJ Adnams
Ranch Hand
Joined: Sep 28, 2001
Posts: 925
posted
0
anyone looked at java.swing.text.html.parseer.NPrintWriter seems to do the job but of course has a loop inside. I also thought about extending a streams class and setting the cache buffer somehow, override the flush() with a flush() followed by System.exit(). you would just then do a while(true) print("hello world"); still a loop.
Francis Siu
Ranch Hand
Joined: Jan 04, 2003
Posts: 867
posted
0
hi Michael and Jim Could you describe what happened in the initialization of private static final byte[] bytes = //...something ? And what is the concept of the coding? I really do not know what the coding mean. thanks for your attention
The above solution again is not much elegant. I was about to post similar yesterday
Michael Morris
Ranch Hand
Joined: Jan 30, 2002
Posts: 3451
posted
0
The above solution again is not much elegant. Elegance is in the eye of the coder. But agreed, though sometimes clever trumps elegant. And what is the concept of the coding? I really do not know what the coding mean.
Did you run the programs Siu? If not, try it. Just copy and paste them (do mine first and then Jim's most clever response) into your texteditor, then compile and run. Mine will print Hello World 100 times to stdout (duh!). The way this works is, I first created a class named HelloWorld100 with a single static method named doIt which used a simple for loop to print Hello World the 100 times. Next I wrote a simple routine to dump the declaration of byte[] bytes = { ... into a text file by reading the HelloWorld100.class which I later pasted into the above program. My class extends ClassLoader, so in the constructor I call defineClass() using the byte array and assign the returned Class object to the static hello member. Now all I have to do in main is call the constructor and use reflection to get to the static method doIt() and then call invoke() on the Method object and by some miracle Hello World is printed 100 times with no apparent loop or recursion.
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18670
posted
0
For my part: I figured the static byte[] array was a class file, so I modified MM's program to write the array contents to a file named HelloWorld100.class. I used JAD to decompile this and get a possible version of HelloWorld100.java which would compile to the class file. A .class file doesn't have any info about things like MM's comments, level of indentation, etc. so the original HelloWorld.java could be cosmetically different, but is probably reasonably close to what I got. One complication was that JAD was last updated in 1999, and refuses to work with .class files whose version number exceeds 46 (meaning, no JDK 1.3 or 1.4). I got around this by manually changing 48 to 46 for the 8th byte in MM's array, effectively telling JAD to pretend the program was written for JDK 1.2. Evidently the format was close enough; JAD then decompiled without problems. Once I had (a version of) HelloWorld100.java (which admittedly I also could have gotten just by guessing :roll: ) I wrote a program to print it to the screen (HeresYourLoop.java with static method show()), made a class file, and used the byte values of that class file to create FoundTheLoopHelloWorld100.java, using the same technique MM just described. It's too bad JAD hasn't been maintained. Anyone know a good alternate out there that's kept pace with later class file versions?
Michael Morris
Ranch Hand
Joined: Jan 30, 2002
Posts: 3451
posted
0
Next time I'll run it thru an obfuscater. I figured you used JAD. Anyway it was a neat hack.
I agree. Here's the link: http://ej-technologies/jprofiler - if it wasn't for jprofiler, we would need to
run our stuff on 16 servers instead of 3.
subject: 100 times "hello world" without loop or recursive