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\$
4
  • \$\begingroup\$ Does cout count as a function call ? \$\endgroup\$
    – Paul R
    Commented Sep 29, 2012 at 21:12
  • \$\begingroup\$ Yes of course. To make it clear I'll edit now and specify. Thanks for asking. \$\endgroup\$ Commented Sep 29, 2012 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
    Commented Sep 30, 2012 at 9:48
  • 1
    \$\begingroup\$ But cout isn't a function call. << is a function call, when applied to cout. \$\endgroup\$
    – celtschk
    Commented Jun 21, 2014 at 8:08

3 Answers 3

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.

\$\endgroup\$
4
  • \$\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\$ Commented Sep 30, 2012 at 8:16
  • \$\begingroup\$ Your submission is the shortest so you won it! \$\endgroup\$ Commented Oct 1, 2012 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\$ Commented Oct 1, 2012 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\$ Commented Feb 16, 2016 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.

\$\endgroup\$
1
  • \$\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\$ Commented Sep 30, 2012 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)();
\$\endgroup\$
3
  • \$\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
    Commented Sep 29, 2012 at 23:17
  • \$\begingroup\$ great job! these are EXACTLY the two lines in my program!! \$\endgroup\$ Commented Sep 30, 2012 at 8:06
  • 1
    \$\begingroup\$ Note that it's implementation defined whether a function pointer can be reinterpret_casted to a data pointer. \$\endgroup\$
    – Xeo
    Commented Sep 30, 2012 at 9:46

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