5
\$\begingroup\$

I am back with a brand new puzzle for C/C++ addicts. Following the feedback received on the 1st puzzle, this time I will try to make the requirements crystal clear and to provide a perfectly valid code.

Here is the problem. Given the following code:

#include <iostream>

char message[6]="hello";

void print_hello_message() {
   std::cout << message;
}

int main() {
   char* q = &message[0];

   // insert your code here
}

You are required to insert two more lines where the comment specifies in order to make the program print "hello" and nothing more, with the following restrictions:

  1. the first line will NOT call any function, including cout

  2. the second line will contain AT MOST 5 letters (and as many other symbols as you want)

  3. the first line may contain new variable declarations but may not initialize them

  4. the symbols # and / will not be used at all.

  5. no logical operators will be used

    The shortest code wins!

\$\endgroup\$
  • \$\begingroup\$ Does cout count as a function call ? \$\endgroup\$ – Paul R Sep 29 '12 at 21:12
  • \$\begingroup\$ Yes of course. To make it clear I'll edit now and specify. Thanks for asking. \$\endgroup\$ – Bogdan Alexandru Sep 29 '12 at 21:23
  • \$\begingroup\$ A tip for the next quiz: Please only allow standard portable C++ code. The workaround with function pointers is implementation defined on whether it actually works or not. \$\endgroup\$ – Xeo Sep 30 '12 at 9:48
  • \$\begingroup\$ But cout isn't a function call. << is a function call, when applied to cout. \$\endgroup\$ – celtschk Jun 21 '14 at 8:08
13
\$\begingroup\$

In thinking about it some more, the problem states "insert two more lines where the comment specifies" not "statements". Taking that into consideration, here is another shorter answer (though it depends on how you define "the first line will NOT call any function, including cout"):

std::
cout<<q;

The first line qualifies which cout will be used, and the second line includes the actual operator that results in calling operator<< for the std::ostream & const char* operands.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This is also correct and another way around my solution. In the beginning the first rule stated that the first line must end with ; but I thought about it more and decided to let people get creative and deliver two line statement. \$\endgroup\$ – Bogdan Alexandru Sep 30 '12 at 8:16
  • \$\begingroup\$ Your submission is the shortest so you won it! \$\endgroup\$ – Bogdan Alexandru Oct 1 '12 at 6:40
  • \$\begingroup\$ I would have sworn you gave the win to someone else. Not that it really matters, no money on the line, but thanks! :) \$\endgroup\$ – CasaDeRobison Oct 1 '12 at 17:00
  • \$\begingroup\$ In thinking about it, even if you had left in the "first line must end with ;" rule, this solution would have still qualified with the addition of "//;" to the end of the first line. \$\endgroup\$ – CasaDeRobison Feb 16 '16 at 8:30
9
\$\begingroup\$

If I understand what you're asking for, this is what I'd add:

using std::cout;
cout<<q;

The first line brings std::cout into the current name space so that we can use it without qualification. using namespace std; would have worked as well but is longer so I didn't use it.

The second line uses the limit of five letters (plus three symbols and no necessary white space beyond whatever the platform uses to denote end of line).

There may be something shorter, but I can't think of it at the moment.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ nice! this is the "cheating" version, I tried to do my best with those restrictions to prevent things like this one, but apparently a hole could be found :) Good work! \$\endgroup\$ – Bogdan Alexandru Sep 30 '12 at 8:13
8
\$\begingroup\$

Use q to store a pointer to print_hello_message, then cast it back to a function pointer and invoke it.

q = (char *) &print_hello_message;
(*(void(*)())q)();

Short version:

q=(char*)print_hello_message;
(*(void(*)())q)();
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Love it. I didn't read the 3rd rule well enough and tried to work around having to save the function address altogether. Like so: ((void(*)())(q-40))(); \$\endgroup\$ – shiona Sep 29 '12 at 23:17
  • \$\begingroup\$ great job! these are EXACTLY the two lines in my program!! \$\endgroup\$ – Bogdan Alexandru Sep 30 '12 at 8:06
  • \$\begingroup\$ Note that it's implementation defined whether a function pointer can be reinterpret_casted to a data pointer. \$\endgroup\$ – Xeo Sep 30 '12 at 9:46
0
\$\begingroup\$
#include <iostream>

char message[6]="hello";

void print_hello_message() {
   std::cout << message;
}

int main() {
   char* q = &message[0];

   while(*q!=' ')
       cout<<*q++;

}
| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ Does not compile due to missing std:: \$\endgroup\$ – Paul R Sep 30 '12 at 6:11
  • 1
    \$\begingroup\$ Hey...nice idea but poorly executed! You came close to the second solution I had in mind which is correctly written as: [NEWLINE] using std::cout; while(*q!='\0') [NEWLINE] cout << *q++; \$\endgroup\$ – Bogdan Alexandru Sep 30 '12 at 8:19
  • \$\begingroup\$ Alternatively one could use: [NEWLINE] while(*q!='\0') std:: [NEWLINE] cout << *q++; \$\endgroup\$ – CasaDeRobison Oct 1 '12 at 17:03

Not the answer you're looking for? Browse other questions tagged or ask your own question.