

Display 100 Hello World Without Using Loops - ajibanda
http://www.ajibanda.com/2012/05/programmers-interview-101-print-100.html#.T79WN7Bo3tw

======
user24
Decent enough explanation of recursion.

Why not take it further and produce a more general solution?

In JavaScript I'd write something like this:

    
    
        function recurseBetween(start, end, callback) {
          // Create a recursive function
          // which checks the limits and calls the supplied callback
          var recursiveCallback = function(i) {
            // Call the original callback
            callback(i);
            // If we're at the end, stop
            if(i >= end) {
              return;
            } else {
              // Else increment and recurse
              recursiveCallback(++i);
            }
          };
          // Start recursing with the start value
          recursiveCallback(start);
        }
    

Now you can use recurseBetween almost exactly as you would a for loop:

    
    
        recurseBetween(1, 10, function(i) {
          console.log(i);
        });
    

You could even abstract the start and max arguments as callbacks, and you
could supply a callback to perform the increment too so that you're not
limited to integral addition.

~~~
f055
Or go back to C and learn that recursion is not really used like that. If you
know the limits beforehand, use "for". If you don't know how deep the
processing will go, use recursion.

If you must code a loop without using "for" it means you're doing a homework
;)

~~~
masklinn
> Or go back to C and learn that recursion is not really used like that.

It's not used like that in C, it's definitely used like that in Erlang.

------
valisystem
A great answer to a similar problem here
<http://stackoverflow.com/a/4583502/456341>.

No loop, and _no conditional recursion_.

The flaw is to use arithmetic on stack function pointer, which is not
recommended nor strictly defined.

------
terryk88a
Why don't you ask "What's the least efficient way to print a string 100
times?"

Unrolling loops can be a good thing when optimizing code, but you can't get
much worse than tail recursion. It's _always_ a win to eliminate this code
pattern. The order of complexity is the same, but your stack will blow up for
large N.

I don't know what you're looking for when posing this problem. A simple loop
is already the most efficient technique.

loop good tail recursion bad

Of course, this _is_ just a homework quiz, right?

------
sad
These are fun.

In C++, make the compiler do your recursion:

    
    
      #include <iostream>
    
      template <int N>
      void pr(const std::string &msg)
      {
          std::cout << msg << std::endl;
          pr<N-1>(msg);
      }
    
      template <>
      void pr<0>(const std::string &msg)
      {
      }
    
      int main(int argc, char *argv[])
      {
          pr<100>("Hello World");
          return 0;
      }

------
ryfm
#include "stdafx.h"

#include <iostream>

using namespace std;

class HelloWorld {

    
    
      public:
    
        HelloWorld();
    

};

HelloWorld::HelloWorld()

{

    
    
        cout << "Hello World\n";
    

}

int _tmain(int argc, _TCHAR* argv[])

{

    
    
        HelloWorld * hi = new HelloWorld[100] ();
    
    
        return 0;
    
    }

------
natecavanaugh
Or, the first thing I thought of (didn't even think recursion), was evil-y
eval JavaScript:

eval(Array(101).join('console.log("hello world");'));

------
quarterto
100.times {puts "Hello, world"}

I'm just sayin'.

~~~
masklinn

        sequence_ $ take 100 $ repeat $ putStrLn "Hello, World"
    

alternatively,

    
    
        mapM_ putStrLn $ take 100 $ repeat "Hello, World"

~~~
jewbacca

        [see above]

~~~
masklinn
Oh, didn't know about `replicateM_`. Not sure I like it much though, seems...
redundant.

~~~
jewbacca
It's a pretty common pattern, I think it's worth its own word, at least as
much as mapM:

    
    
        mapM f xs      = sequence (map f xs)
        replicateM n x = sequence (replicate n x)
    

Another cool thing replicateM is equivalent to: for lists, it's the cartesian
power (sequence is the cartesian product). ...this is actually the primary
reason I'm aware of it.

------
jack-r-abbit
Here is mine in that really crappy PHP language:

print implode(PHP_EOL, array_fill(1, 100, "Hello World"));

------
430gj9j
Python version:

    
    
        exec "print 'Hello world'\n" * 100

~~~
antirez
that reminds me why I don't like Python. Ad-hoc tools (many) instead of a few
general concepts working well together.

Btw at interview time this solution would not be acceptable, because you are
using still a built-in language construct for looping.

~~~
hythloday
Huh? This is a specific case of the * operator, which is overloaded for type
string to return a repetition of the string. The only ad-hoc in the example is
the print statement, which is gone in 3.2.

How do you know the __mul__ operator overload for string is implemented with
iteration?

~~~
lloeki
> This is a specific case of the * operator, which is overloaded

It is not operator overloading in the strictest sense, but more of duck
typing. In Python (and Ruby), operators are syntactic sugar for method calls
on the first operand.

Operator overloading on the contrary suggests a function add(a, b) that reacts
differently through polymorphism (i.e according to the types of its
arguments).

The distinction is important as overloading and polymorphism simply do not
exist in Ruby and Python, only overriding.

~~~
hythloday
My hope in using the phrase "operator overloading" was to bring to mind the
familiar concept of operator ad-hoc polymorphism (which I would maintain duck
typing is an example of) rather than to misleadingly describe the internals of
the Python language. Nonetheless you are quite right on the details.

------
jcmhn
yy 100 p

or

map { print "hello, world\n" } (1..100);

or a goto or maybe even disgusting abuse of try/catch

Depending on how far I wanted to tweak the interviewer's nose. :D

------
dvgaba
Haskell Solution ::

Prelude> take 100 $ cycle "Hello World"

------
udp
Or alternatively, "how not to write a parser".

