m3ph1st0s's programming puzzle 2 (C++): "Call hard!"

5

1

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!

Bogdan Alexandru

Posted 2012-09-29T19:47:32.347

Reputation: 653

Question was closed 2016-01-21T16:56:06.277

Does cout count as a function call ? – Paul R – 2012-09-29T21:12:07.747

Yes of course. To make it clear I'll edit now and specify. Thanks for asking. – Bogdan Alexandru – 2012-09-29T21:23:42.467

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. – Xeo – 2012-09-30T09:48:16.883

But cout isn't a function call. << is a function call, when applied to cout. – celtschk – 2014-06-21T08:08:08.110

Answers

13

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.

CasaDeRobison

Posted 2012-09-29T19:47:32.347

Reputation: 736

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. – Bogdan Alexandru – 2012-09-30T08:16:07.073

Your submission is the shortest so you won it! – Bogdan Alexandru – 2012-10-01T06:40:55.013

I would have sworn you gave the win to someone else. Not that it really matters, no money on the line, but thanks! :) – CasaDeRobison – 2012-10-01T17:00:17.383

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. – CasaDeRobison – 2016-02-16T08:30:01.833

9

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.

CasaDeRobison

Posted 2012-09-29T19:47:32.347

Reputation: 736

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! – Bogdan Alexandru – 2012-09-30T08:13:11.243

8

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)();

mob

Posted 2012-09-29T19:47:32.347

Reputation: 2 506

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))(); – shiona – 2012-09-29T23:17:21.667

great job! these are EXACTLY the two lines in my program!! – Bogdan Alexandru – 2012-09-30T08:06:06.520

Note that it's implementation defined whether a function pointer can be reinterpret_casted to a data pointer. – Xeo – 2012-09-30T09:46:29.333

0

#include <iostream>

char message[6]="hello";

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

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

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

}

Usha Hegde

Posted 2012-09-29T19:47:32.347

Reputation: 1

3Does not compile due to missing std:: – Paul R – 2012-09-30T06:11:19.913

1Hey...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++; – Bogdan Alexandru – 2012-09-30T08:19:19.287

Alternatively one could use: [NEWLINE] while(*q!='\0') std:: [NEWLINE] cout << *q++; – CasaDeRobison – 2012-10-01T17:03:17.647