Abhinav Gauniyal
Abhinav Gauniyal

Reputation: 7574

What code would make this loop work?

So here's the question asked to me during an interview -

for( blah blah ) { 
   cout<<"World";
}

my task was to replace blah blah so that the printed output was :- Hello World !

And I am only allowed to change the blah blah phrase only , nothing more than that. No code changes below or above that!

Upvotes: 3

Views: 372

Answers (8)

danielschemmel
danielschemmel

Reputation: 11116

Obviously the for loop is nothing more than a diversion. Look at it like this:

for(
/* Your Code Here */
) { cout << "World"; }

So, the first thing you need to do is get rid of all of the pesky code already in the program:

for(
/* Your Code Begins */
;0;);
/* TODO */
if(0
/* Your Code Ends */
) { cout << "World"; }

Since, naturally, they will want to test your cleverness, let us do something very clever next:

    for(
    /* Your Code Begins */
    ;0;);
    struct cout {
        void operator<<(cout world)
        {
            hello <world> !"";
        }
        char const* out;
        cout() : out(0) { }
        cout(char const* out) : out(out) { }
        operator bool() { return !out; }
        struct typeof
        {
            typeof(decltype(::std::cout) const&) { }
            void operator>(bool a)
            {
                ::std::cout << (!a ? "!" : "?");
            }
        };
        struct
        {
            typeof operator<(cout c)
            {
                return typeof(::std::cout << "Hello " << c.out);
            }
        } hello;
    } cout;
    if(cout
    /* Your Code Ends */
    ) { cout << "World"; }

Note: Since they like the name cout, make sure to use it liberally in your code!

Also, be aware of a common GCC bug (well, they call it an "extension"), that may cause problems with your absolutely standards compliant c++ code.

Finally, recall that the initial instructions did not call for any newline at the end, so do not expect any. Should the wish to see the output immediately, you may have to flush your output.

Some of the hoops that you have to jump through may seem unnecessary, but the rigid requirement that you use a nested class instead of one at namespace level causes some problems with proper operator overloading.

Personally, I would like to point out that this code is very easy to understand: All it does is say hello <world>!, so let us just quickly reformat the result a bit, leading to your final code (this time, the surrounding constructs are omitted):

    ;0;);struct cout{void operator<<(cout world){

        hello <world>!

    "";}char const*out;cout():out(0){}cout(char const*out):out(out){}
    operator bool(){return!out;}struct
    typeof{typeof(decltype(::std::cout)const&){}void
    operator>(bool a){::std::cout<<(!a?"!":"?");}};
    struct{typeof operator<(cout c){return
    typeof(::std::cout<<"Hello "<<c.out);}}hello;}cout;if(cout

Of course, the final step is only done for purely aesthetic reasons and can be omitted if so desired.

P.S.: It actually prints "Hello World!", not ":- Hello World !", which I assume is what the question said exactly. Changing it to conform to the other format is left as an exercise to the reader.

Upvotes: 2

bitmask
bitmask

Reputation: 34628

Nobody bothered to fix the obviously broken code, which access some mysterious never-defined cout, which is very obviously horrible code, so ... here's the fix:

#include <iostream>

#define BLAH \
  struct { \
    template <typename T> \
    void operator<<(T const& t) const { \
      ::std::cout << ":- Hello " << t << " !\n"; \
    } \
    bool okay;\
  } cout{true}; \
  cout.okay; \
  cout.okay = false

int main() {
  for(BLAH) {
    cout<<"World";
  }
}

Only for better readability I part you may change into a separate #define called BLAH.

Note: My gcc refuses to build this, but clang accepts this with the highest warn-level. I'm building hw.cpp like this:

make CXXFLAGS=-Wall\ -Wextra\ -pedantic\ -std=c++11 CXX=clang++ hw

Upvotes: 0

chrizke
chrizke

Reputation: 458

There are two problems to solve.

  1. Output in the loop's header
  2. Suppress the iteration.

In the first part of a for declaration you can execute almost every single command. So it's a good idea to print here the desired output.

To suppress the iteration just enter false as condition. The last part of the header can be left blank.

#include <iostream>

using namespace std;

int main()
{
    for ( cout<<"Hello World!"<<endl ; false ; )
    {
            cout<<"World"<<endl;
    }
    return 0;
}

Upvotes: 4

Mats Petersson
Mats Petersson

Reputation: 129344

How about this for blah blah:

const char *p = "Hello "; *p; cout << *p, p++); if (1 

Upvotes: 2

yizzlez
yizzlez

Reputation: 8805

Use the fact that C++ doesn't recognize spaces!

for(int i = 0; i < 0; ++i); if(true){ cout << "Hello World!"; } else { //blah blah ) { 
    cout<<"World";
}

Upvotes: 0

jrok
jrok

Reputation: 55395

They didn't say you need to actually run the loop, did they?

#include <iostream>
#include <ios>
using namespace std;
int main() {
    for (int i = (cout << "Hello World!",0); i; ) { cout << "World"; }
}

Upvotes: 7

A.E. Drew
A.E. Drew

Reputation: 2137

Why even worry about the body of the for loop if you can put anything in for blah blah:

for(int i = 0 ; std::cout << "Hello world!", i < 0;   ) { 
   std::cout<<"World";
}

Upvotes: 14

trojanfoe
trojanfoe

Reputation: 122391

It took me a little while attempting to control the loop to a single iteration:

#include <iostream>
#include <ios>
using namespace std;
int main() {
    for (cout << "Hello "; cout; cout.setstate(ios::badbit)) { cout << "World"; }
}

If the ! is meant to be in the output then this code will do that:

#include <iostream>
#include <ios>

using namespace std;
int main() {
    for (cout << "Hello "; cout; cout << "!", cout.setstate(ios::badbit)) {
        cout << "World";
    }
}

Upvotes: 6

Related Questions